Passing members of structs as pointers

N

nolonger

Sample code:-

typedef struct __Y
{
int a;
char b[5];
} Y;

Y my_struct;
Y *my_ptr_struct;

void my_func (char *str);

main
{
my_ptr_struct = &my_struct;

my_func(&my_struct.b);
my_func(&my_ptr_struct->b);
}

Both func calls gave me compiler warnings of pointer mismatch. So I
changed to (char *) &my_struct.b and (char *) &my_ptr_struct.b. Is
this correct passing of pointers to members?

Thank-you.
 
R

Richard Heathfield

John Paul II ([email protected]) said:
Sample code:-

typedef struct __Y
{
int a;
char b[5];
} Y;

Y my_struct;
Y *my_ptr_struct;

void my_func (char *str);

main
{
my_ptr_struct = &my_struct;

my_func(&my_struct.b);

Lose the ampersand. &my_struct.b has type char (*)[5], whereas you want
char *, which you can get with my_struct.b, because of The Rule (i.e.
the Standard's guarantee that A and *(A + I) are synonymous).
 
R

Richard Bos

John said:
typedef struct __Y

That is an identifier which you are not allowed to use. Identifiers
starting with __, or with _ and a capital letter, are reserved for the
implementation; and under many circumstances, ones starting with _ and
anything else as well. Besides, you don't even need the tag here if
you're going to refer to it by a typedef name anyway. Dike it out.
{
int a;
char b[5];
} Y;

Y my_struct;
Y *my_ptr_struct;

void my_func (char *str);

main

This should not have compiled. Please copy & paste, don't re-type, code
you are asking about. That way you won't introduce typos.
{
my_ptr_struct = &my_struct;

my_func(&my_struct.b);
my_func(&my_ptr_struct->b);
}

Both func calls gave me compiler warnings of pointer mismatch. So I
changed to (char *) &my_struct.b and (char *) &my_ptr_struct.b. Is
this correct passing of pointers to members?

No. In fact, your question has nothing to do with struct members as
such. The problem lies with getting the address to an array, regardless
of whether it is a struct member. Try, for example, this code:

void my_func (char *str);

int main(void)
{
char my_array[5];

my_func(&my_array);
}

You should get a very similar warning.

Casting the pointer to char * is the wrong solution. In fact, casting
away warnings is very nearly always the wrong solution. In this case,
the right solution is to pass the right address: a pointer to the first
member of mystruct.b, rather than to the entire array. So you want:

my_func(&(*my_struct.b));

or, equivalently,

my_func(&(my_ptr_struct->b[0]));


Richard
 
A

Army1987

John Paul II said:
Sample code:-

typedef struct __Y
{
int a;
char b[5];
} Y;

Y my_struct;
Y *my_ptr_struct;

void my_func (char *str);

main
{
my_ptr_struct = &my_struct;

my_func(&my_struct.b);
my_func(&my_ptr_struct->b);
}

Both func calls gave me compiler warnings of pointer mismatch. So I
changed to (char *) &my_struct.b and (char *) &my_ptr_struct.b. Is
this correct passing of pointers to members?

That will happen to work, here, but is a bad idea.
Use my_func(my_struct.b), and my_struct.b will decay into
&mystruct.b[0]. Reading the www.c-faq.com section about arrays and
pointers will help.
 
A

Army1987

Richard Bos said:
John said:
typedef struct __Y

That is an identifier which you are not allowed to use. Identifiers
starting with __, or with _ and a capital letter, are reserved for the
implementation; and under many circumstances, ones starting with _ and
anything else as well. Besides, you don't even need the tag here if
you're going to refer to it by a typedef name anyway. Dike it out.
{
int a;
char b[5];
} Y;

Y my_struct;
Y *my_ptr_struct;

void my_func (char *str);

main

This should not have compiled. Please copy & paste, don't re-type, code
you are asking about. That way you won't introduce typos.
{
my_ptr_struct = &my_struct;

my_func(&my_struct.b);
my_func(&my_ptr_struct->b);
}

Both func calls gave me compiler warnings of pointer mismatch. So I
changed to (char *) &my_struct.b and (char *) &my_ptr_struct.b. Is
this correct passing of pointers to members?

No. In fact, your question has nothing to do with struct members as
such. The problem lies with getting the address to an array, regardless
of whether it is a struct member. Try, for example, this code:

void my_func (char *str);

int main(void)
{
char my_array[5];

my_func(&my_array);
}

You should get a very similar warning.

Casting the pointer to char * is the wrong solution. In fact, casting
away warnings is very nearly always the wrong solution. In this case,
the right solution is to pass the right address: a pointer to the first
member of mystruct.b, rather than to the entire array. So you want:

my_func(&(*my_struct.b));

or, equivalently,

my_func(&(my_ptr_struct->b[0]));

or equivalently,
my_func(my_struct.b);
or equivalently,
my_func(my_ptr_struct.b);
 
J

John Paul II nolonger

To those who replied.

Yes, I wasn't seeing that the members of a struct are dereferenced by
-> therefore they are pointers to the first character in the array.

Thank-you for setting me straight!
 
R

Richard Heathfield

John Paul II (e-mail address removed) said:
To those who replied.

Yes, I wasn't seeing that the members of a struct are dereferenced by
->

No, they aren't. -> dereferences a struct pointer, not the members of a
struct. P->M and (*P).M are synonymous.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,744
Messages
2,569,483
Members
44,903
Latest member
orderPeak8CBDGummies

Latest Threads

Top