----- Original Message -----
From: "nataraj"
To: "Vijay Kumar R Zanvar"
Sent: Monday, April 19, 2004 12:31 PM
Subject: c code
> Hi Vijay,
>
> find out the problem in below code...i want address of first member
> of structure in MACRO.
>
> Regards
> Nataraj
>
> #include
>
> typedef struct A{
> char b;
> int c;
> }A;
>
> #define STA1(t1) { A *p; \
> p=t1; \
> (p)?((int)&(p->b)):(0); }
>
> int
> main()
> {
> A test;
> int k = 0;
>
> test.b=4;
> test.c=1;
> k=STA1(&test);
Things get wrong here. The macro, STA1, expands into a block of statements.
And, you are trying to assign a block to an identifier, which is an illegal
construct in C. Anything sorrounded by parantheses is an expression, and that
sorrounded by braces is a block(compound statement).
GCC, as an extension, allows a compound statement enclosed in parantheses as
an expression. The value of the last statement serves as the value of the
entire construct. So, the macro could be rewritten as:
#define STA1(t1) ({ A *p; \
p=t1; \
(p)?((int)&(p->b)):(0); })
If it is required that only the macro should be used to get the address of
a structure member, then following macro could be used more portably than
the above one. Using a macro could be due to future changes and/or portability
issues.
#include /* for offsetof() macro */
#define STA1(ptr, member) (ptr + offsetof ( struct A, member ))
The other undefined behaviour that can be observed is the assignment:
k = STA1 ( &test );
assuming that the macro, STA1, evaluates to a pointer of type struct A.
The conversion from pointer to integer is implementation-defined and may
not give the results you expect.
> printf ( "%d\n", k );
> }
To print the value of a pointer, use the "%p" conversion specifier.
The value of the pointer is converted to a sequence of printing characters,
in an implementation-defined manner. The pointer should be casted to a
pointer to void. For example,
struct A *ptr = STA1 ( &test );
printf ( "%p\n", (void *) ptr );
C99 also makes available a new integer type, intptr_t, that is capable of
holding object pointers. The pointer should always be converted to void *
prior the assignment. So, for example,
#include /* for intptr_t */
intptr_t ptr = (void *) STA1 ( &test );
Well, the easiest method I can think of finding the address of a structure
member, say b, is:
printf ( "%p\n", (void *) &test -> b );
               (
geocities.com/vijoeyz/faq)                   (
geocities.com/vijoeyz)