C: request for member in something not a structure or union

If you're trying to pass a pointer to a structure to a function, you may be getting the compiler error request for member ‘SOME_PROPERTY’ in something not a structure or union. If you swear you're passing in a pointer to the proper structure, and you're certain, there are no typos for the member name you're trying to access, you may just be experiencing a bit of pointer ambiguity.

The Problem!

Consider a very simple example. [c] // Example demonstrating C pointer ambiguity #include<stdio.h> typedef struct{ char* job; int age; } Person; void give_bob_a_job(Person*); int main(){ Person bob; give_bob_a_job(&bob); printf("The job of bob is %s\n", bob.job); return 0; } void give_bob_a_job(Person *bob){ *bob.job = "Sysadmin"; } [/c] We compile the file
~$ gcc bob.c -o bob.o
bob.c: In function ‘give_bob_a_job’:
bob.c:18:6: error: request for member ‘job’ in something not a structure or union
So we receive the error error: request for member ‘job’ in something not a structure or union. We run through a mental checklist:
  • Did I pass a pointer to the right structure?
  • Does that structure really have a 'job' member?
  • Did I make any typos in declaring the member or calling the member?
If all these check out, then we move on. Let's look closer at the statement on line 18. [c]*bob.job = "Sysadmin";[/c] This actually reads
'Assign the string "Sysadmin" to the pointer variable of bob.job'
In other words, the deference operator (*) is dereferencing all of bob.job instead of dereferencing bob and accessing its job member. In this context, bob is just a pointer to Person, so it's a memory address. Thus the compiler error makes sense! Luckily, the solution is super simple.

The Solution!

We can be explicit about our dereferencing by using parenthesis. [c](*bob).job = "Sysadmin";[/c] This reads
'Assign the string "Sysadmin" to the pointer variable of bob's job member'
Replace line 18 with the correction, and the code should compile with the following output upon execution:
The job of bob is Sysadmin

Syntax cleanup

Dereferencing a pointer to a structure is so common, we have a shorthand for doing so.
(*foo).bar
is equal to
foo->bar
so
bob->job = "Sysadmin";
would work as well. April 03, 2012
About the Author:

Joseph is the lead developer of Vert Studios Follow Joseph on Twitter: @Joe_Query
Subscribe to the blog: RSS
Visit Joseph's site: joequery.me