1

Former I had a function f(double *a), which gets an array to work on. In order to get the correct position it should work on the array, it gets called as f(a+offset), with offset an integer. Now I reworked the code, and I defined a custom struct:

typedef struct{
double *a;
} struName;

and the function changed to f(struName *a). Now I was wondering how I still could get the offset to the function, without having to create a new temporary struct or having to change the function from f(struName *a) to f(struName *a, int offset). Is that even possible?

2
  • 5
    Why you changed the function prototype to f(struName *a)? It should have still worked with f(variabelname.a + offset) Commented Apr 28, 2016 at 7:46
  • 3
    Changing the function seems like the cleanest solution by far. If that can't be done, is adding an offset member to the struct an option? Commented Apr 28, 2016 at 8:06

2 Answers 2

2

It's not possible, without changing the contents of the struct, or invoking undefined behaviour.

If you have access to ISO C99, you can change the signature to accept the struct by value, and pass in a compound literal:

f((struct struName){ .a = myStruct.a + offset });

Otherwise your proposed solution with to distinct parameters should work just fine:

f(myStruct, offset);
Sign up to request clarification or add additional context in comments.

6 Comments

If you do not fear undefined behavior, and want to break the strict aliasing rule, you can do: f(((double*)myStruct)+offset);. DO NOT DO THIS UNLESS YOU LIKE NASAL DAEMONS
That UB is easily dodged by changing the struct to a union, in which case the behavior would be well-defined. There's only one member anyhow.
@Lundin Isn't it still aliasing a different type?
It is well-defined as per 6.7.2.1/16: "A pointer to a union object, suitably converted, points to each of its members (or if a member is a bitfield, then to the unit in which it resides), and vice versa." Also note this exception for unions in the "strict aliasing rule": "an aggregate or union type that includes one of the aforementioned types among its members"
@Lundin Cool. Thank you!
|
2

The best solution is to change the function to take an offset parameter.

If that isn't an option, the second best solution is to change the struct definition to contain an offset member (if that makes sense design-wise).

If that isn't an option either, the third best solution is like in the answer by Leandros: create a temporary struct and change the pointer member before passing a pointer to the temporary struct. That is, treat the struct as immutable - if possible make the pointer member const. This keeps the program design clean, but you have to make an extra copy of the struct.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.