Is there a way to access a structure member which is identical to a macro name? Consider this code:
struct test {
int foo;
};
#define foo bar
int main(int argc, char *argv[])
{
struct test t;
t.foo = 5;
return 0;
}
This code will obviously fail to compile because bar
is not a member of struct test
. In this question it is described that putting a function name in parentheses will disable macro expansion. So I thought that maybe this is possible with structures too and I've tried the following:
t.(foo) = 5;
But it didn't work. That's why I'd like to ask the question if it's possible to access the foo
member even though there is a macro that has the same name or can I only access the structure member foo
by undefining the macro foo
first?
Ideally, I'm looking for a portable solution but anything that works with gcc is also fine.
Is there a way to access a structure member which is identical to a macro name? Consider this code:
struct test {
int foo;
};
#define foo bar
int main(int argc, char *argv[])
{
struct test t;
t.foo = 5;
return 0;
}
This code will obviously fail to compile because bar
is not a member of struct test
. In this question it is described that putting a function name in parentheses will disable macro expansion. So I thought that maybe this is possible with structures too and I've tried the following:
t.(foo) = 5;
But it didn't work. That's why I'd like to ask the question if it's possible to access the foo
member even though there is a macro that has the same name or can I only access the structure member foo
by undefining the macro foo
first?
Ideally, I'm looking for a portable solution but anything that works with gcc is also fine.
Share Improve this question asked Mar 17 at 18:41 AndreasAndreas 10.2k11 gold badges56 silver badges114 bronze badges 16 | Show 11 more comments2 Answers
Reset to default 5anything that works with gcc
If you really want to preserve the macro, just:
struct test {
int foo;
};
#define foo bar
int main(int argc, char *argv[])
{
struct test t;
#pragma push_macro("foo")
#undef foo
t.foo = 5;
#pragma pop_macro("foo")
return 0;
}
Obviously the correct and proper solution is to have good names so there's no namespace collisions in the first place.
Failing that (because you are maintaining some old rotten code base?) then I guess these are various alternatives:
The obvious solution is to either
#undef foo
or temporarily define another macro that counters the first one, only to#undef
the temporary macro.You could assign to the whole struct using a whole compound literal, but that overwrites all members:
t = (struct test){ 5, t.x };
Where
t.x
is some other struct member you'd like to preserve.The address of the struct is the same as the address of the first member, so this is safe:
int val = 5; memcpy(&t, &val, sizeof(int));
Similarly,
*(int*)&t
is a safe conversion printing the contents offoo
.Alternatively if the member is in the middle of the struct, pre-calculate the offset using
offsetof
before the macro is defined.
* (int *) &t
is a defined way to access that member. – Eric Postpischil Commented Mar 17 at 18:56#define bar foo
, then usingt.foo
, then following it with the line#undef bar
. If this is not what you want, you should update the post with full requirements. – Eric Postpischil Commented Mar 17 at 19:05foo
before defining the macro.const size_t fo = offsetof(struct test, foo);
and then*(int*)((char*)&t + fo) = 5;
– Ted Lyngmo Commented Mar 17 at 20:43