468,290 Members | 1,938 Online
Bytes | Developer Community
New Post

Home Posts Topics Members FAQ

Post your question to a community of 468,290 developers. It's quick & easy.

What is this?



What is this?

( char * ) &( ( struct aStruct * ) 0 )

It looks like it's taking the address of something that contains a
pointer to null, and casting it to a pointer to char.

(Actually, technically, the address of a pointer to the beginning of a
struct aStruct, that starts at address 0).

Or, is it taking the pointer to null itself, and casting that to a
pointer to char?

Nov 19 '08 #1
19 1643
On Nov 19, 1:48*pm, Eric <answer.to.newsgr...@nospam.comwrote:
What is this?

( char * ) *&( ( struct aStruct * ) *0 )
It wouldn't work, because you can't take address (&) of the constant
(( struct aStruct * ) 0 ).

Nov 19 '08 #2
Eric wrote:
>
What is this?

( char * ) &( ( struct aStruct * ) 0 )

It looks like it's taking the address of something that contains a
pointer to null, and casting it to a pointer to char.
No, it looks like something that attempts to take the address of a null
pointer value. As such, it's a constraint violation (6.5.3.2p1).
Nov 19 '08 #3
In article <kh********************************@4ax.com>,
Eric <an*****************@nospam.comwrote:
>What is this?

( char * ) &( ( struct aStruct * ) 0 )
As it is, it's an error. If it were

( char * ) &( ( struct aStruct * ) 0 )->x

(assuming x is a member of the struct), then it would be an
almost-plausible (though theoretically non-portable) imitation of
offsetof().

-- Richard
--
Please remember to mention me / in tapes you leave behind.
Nov 19 '08 #4
Eric <an*****************@nospam.comwrites:
What is this?

( char * ) &( ( struct aStruct * ) 0 )
It is a constraint violation. That means that a conforming compiler
must issue a diagnostic. The result of a cast is not an lvalue and
the operand of & must be an lvalue.
It looks like it's taking the address of something that contains a
pointer to null, and casting it to a pointer to char.

(Actually, technically, the address of a pointer to the beginning of a
struct aStruct, that starts at address 0).
Not really. Once you have a constraint violation the program is
essentially meaningless, but if we put that to one side (i.e. we
pretend that the stated constraint is missing from the C
specification) then all we have is an attempt to take the address of a
null pointer constant. Null pointers (constant or otherwise) do not
point at anything -- specifically they don't point to an object at
"address zero".

The context of the code might explain the mystery, but it is hard to
guess any intent (at least I can't). Maybe there is a typo?

--
Ben.
Nov 19 '08 #5
Ben Bacarisse wrote:
Eric writes:
What is this?

( char * ) &( ( struct aStruct * ) 0 )

It is a constraint violation. That means that a conforming compiler
must issue a diagnostic. The result of a cast is not an lvalue and
the operand of & must be an lvalue.
It looks like it's taking the address of something that contains a
pointer to null, and casting it to a pointer to char.

(Actually, technically, the address of a pointer to the beginning of a
struct aStruct, that starts at address 0).

Not really. Once you have a constraint violation the program is
essentially meaningless, but if we put that to one side (i.e. we
pretend that the stated constraint is missing from the C
specification) then all we have is an attempt to take the address of a
null pointer constant. Null pointers (constant or otherwise) do not
point at anything -- specifically they don't point to an object at
"address zero".
The contents of the pointer are irrelevant since we're taking its ADDRESS.
Taking the address of a null pointer is perfectly fine (and casting this
to char* is too):

struct aStruct* p = NULL;
char* cp = (char*) &p; // perfectly valid

Maybe you were thinking of taking the address of the pointed-to object,
that is, dereferencing it first? In C89, it's undefined behavior, but in
C99 it's well-defined; the footnote for section 6.5.3.2 starts out: "83)
Thus, &*E is equivalent to E (even if E is a null pointer) [...]".

struct aStruct* p = NULL;
char* cp = (char*) &*p; // undefined behavior in C89 (valid in C99)
Nov 19 '08 #6
bl********@gishpuppy.com (blargg) writes:
Ben Bacarisse wrote:
>Eric writes:
What is this?

( char * ) &( ( struct aStruct * ) 0 )

It is a constraint violation. That means that a conforming compiler
must issue a diagnostic. The result of a cast is not an lvalue and
the operand of & must be an lvalue.
It looks like it's taking the address of something that contains a
pointer to null, and casting it to a pointer to char.

(Actually, technically, the address of a pointer to the beginning of a
struct aStruct, that starts at address 0).

Not really. Once you have a constraint violation the program is
essentially meaningless, but if we put that to one side (i.e. we
pretend that the stated constraint is missing from the C
specification) then all we have is an attempt to take the address of a
null pointer constant. Null pointers (constant or otherwise) do not
point at anything -- specifically they don't point to an object at
"address zero".

The contents of the pointer are irrelevant since we're taking its ADDRESS.
Taking the address of a null pointer is perfectly fine (and casting this
to char* is too):
Yes, true, but I don't think I contradicted that, did I? I was keen
to correct the idea that (T *)0 is pointer to a T "at address zero".

<snip>

--
Ben.
Nov 19 '08 #7
Ben Bacarisse wrote:
Eric <an*****************@nospam.comwrites:
What is this?

( char * ) &( ( struct aStruct * ) 0 )

It is a constraint violation. That means that a conforming compiler
must issue a diagnostic. The result of a cast is not an lvalue and
the operand of & must be an lvalue.
It looks like it's taking the address of something that contains a
pointer to null, and casting it to a pointer to char.

(Actually, technically, the address of a pointer to the beginning of a
struct aStruct, that starts at address 0).

Not really. Once you have a constraint violation the program is
essentially meaningless, but if we put that to one side (i.e. we
pretend that the stated constraint is missing from the C
specification) then all we have is an attempt to take the address of a
null pointer constant. Null pointers (constant or otherwise) do not
point at anything -- specifically they don't point to an object at
"address zero".
The fact that this pointer is null is irrelevant. There would be no
problem if it were a null pointer object rather than a null pointer
constant. The problem is that it's a pointer value, not a pointer
object, and it is just as much of a problem whether or not the pointer
value is null.
The context of the code might explain the mystery, but it is hard to
guess any intent (at least I can't). Maybe there is a typo?
If it were followed by ->x, where "x" is one of the members of struct
aStruct, the only problem with this code would be the fact that it
attempts to de-reference a null pointer, rendering the behavior
undefined. For that reason, such a construct should never occur in
user code. However, on many implementations the actual behavior of
this construct is such that, when the result is converted to size_t,
it constitutes a conforming implementation of the offsetof() macro.
Since <stddef.his part of the implementation, it's perfectly
legitimate for the implementor to take advantage of that fact inside
of stddef.h, even though developers should not do so in user code.
Nov 19 '08 #8
Ben Bacarisse wrote:
blargg writes:
Ben Bacarisse wrote:
[...]
Null pointers (constant or otherwise) do not
point at anything -- specifically they don't point to an object at
"address zero".
The contents of the pointer are irrelevant since we're taking its ADDRESS.
Taking the address of a null pointer is perfectly fine (and casting this
to char* is too):

Yes, true, but I don't think I contradicted that, did I? I was keen
to correct the idea that (T *)0 is pointer to a T "at address zero".
Ahhh, I see now what you were getting at, that for example the
(non-portable) offsetof implementation based on it depends on a null
pointer's representation being all-zero,

#define offsetof(n,m) ((size_t) &((n*) 0)->m)

whereas something like

#define offsetof(n,m) ((size_t) &((n*) sizeof (n))->m - sizeof (n))

doesn't depend on a null pointer representation (but is still not fully
portable of course). Or more simply, to get a pointer to a T at zero, you
need something like (again, not fully portable, but then again, needing an
object at zero is inherently platform-specific)

T* t_at_zero = ((T*) sizeof (T)) - 1;
Nov 19 '08 #9
jameskuyper <ja*********@verizon.netwrites:
Ben Bacarisse wrote:
>Eric <an*****************@nospam.comwrites:
What is this?

( char * ) &( ( struct aStruct * ) 0 )

It is a constraint violation. That means that a conforming compiler
must issue a diagnostic. The result of a cast is not an lvalue and
the operand of & must be an lvalue.
It looks like it's taking the address of something that contains a
pointer to null, and casting it to a pointer to char.

(Actually, technically, the address of a pointer to the beginning of a
struct aStruct, that starts at address 0).

Not really. Once you have a constraint violation the program is
essentially meaningless, but if we put that to one side (i.e. we
pretend that the stated constraint is missing from the C
specification) then all we have is an attempt to take the address of a
null pointer constant. Null pointers (constant or otherwise) do not
point at anything -- specifically they don't point to an object at
"address zero".

The fact that this pointer is null is irrelevant. There would be no
problem if it were a null pointer object rather than a null pointer
constant. The problem is that it's a pointer value, not a pointer
object, and it is just as much of a problem whether or not the pointer
value is null.
Total failure to communicate on my part, I guess, since two people
have now made this point! I only wanted to address the phrase "a
struct aStruct at address 0". The cast expression (struct aStruct *)0
is (as you know) just a null pointer of struct aStruct * type and has
nothing to do with an object of type struct aStruct (and I did point
out what the problem really is with the code right up front!).

--
Ben.
Nov 19 '08 #10
bl********@gishpuppy.com (blargg) writes:
Ben Bacarisse wrote:
>blargg writes:
Ben Bacarisse wrote:
[...]
>Null pointers (constant or otherwise) do not
point at anything -- specifically they don't point to an object at
"address zero".

The contents of the pointer are irrelevant since we're taking its ADDRESS.
Taking the address of a null pointer is perfectly fine (and casting this
to char* is too):

Yes, true, but I don't think I contradicted that, did I? I was keen
to correct the idea that (T *)0 is pointer to a T "at address zero".

Ahhh, I see now what you were getting at, that for example the
(non-portable) offsetof implementation based on it depends on a null
pointer's representation being all-zero,

#define offsetof(n,m) ((size_t) &((n*) 0)->m)
No, that was not what I meant. For one thing, that code does not
depend on the representation of a null pointer (it is non-portable
because it involves de-referencing a null pointer). Honestly, all I
wanted to say was "null pointers do not point at anything --
specifically they don't point to an object at address zero".

I won't comment on the rest for fear of complicating matters more.

--
Ben.
Nov 19 '08 #11
On Wed, 19 Nov 2008 12:07:07 +0000, Ben Bacarisse
<be********@bsb.me.ukwrote:
>The context of the code might explain the mystery, but it is hard to
guess any intent (at least I can't). Maybe there is a typo?
Good afternoon, Ben.

I apologize for not providing enough information... I was just trying
to minimize my post but I guess I minimized it too much. :-)

A more detailed block of code is:

bool result;
bool GetByte( char *theAddr, int theCount, char *theDest);

char Dest[ SOME_SIZE ];

result =
GetByte( ( char * ) &( ( struct aStruct * ) 0 )->Addr,
1, ( char * ) ( &Dest ) );

My question is... does the struct aStruct live at address 0, or does
address 0 contain a pointer to wherever aStruct actually lives? Seems
to me like the "&" ahead of ( ( struct aStruct * ) 0 )->Addr would
indicate the latter...

Nov 20 '08 #12

On Wed, 19 Nov 2008 22:56:14 +0000, Ben Bacarisse
<be********@bsb.me.ukwrote:
>that code does not
depend on the representation of a null pointer (it is non-portable
because it involves de-referencing a null pointer).
Technically, it's dereferencing a zero pointer, which isn't guaranteed
to be the same thing as a null pointer, right?

This code runs on a low-end microcontroller and I think the idea is
that they have something specific at address zero, that they want to
access.

Not really sure about that, though (yet).

See my other post today that shows a more complete block of code that
hopefully does a slightly better job of showing what they are trying
to do.

Nov 20 '08 #13
Eric wrote:
On Wed, 19 Nov 2008 22:56:14 +0000, Ben Bacarisse
<be********@bsb.me.ukwrote:
that code does not
depend on the representation of a null pointer (it is non-portable
because it involves de-referencing a null pointer).

Technically, it's dereferencing a zero pointer, which isn't guaranteed
to be the same thing as a null pointer, right?
(struct aStruct*)0 is a null pointer.
Nov 20 '08 #14
Eric wrote:
On Wed, 19 Nov 2008 12:07:07 +0000, Ben Bacarisse
<be********@bsb.me.ukwrote:
The context of the code might explain the mystery, but it is hard to
guess any intent (at least I can't). Maybe there is a typo?

Good afternoon, Ben.

I apologize for not providing enough information... I was just trying
to minimize my post but I guess I minimized it too much. :-)
That's easy to do; it's still too minimal.
A more detailed block of code is:

bool result;
bool GetByte( char *theAddr, int theCount, char *theDest);

char Dest[ SOME_SIZE ];

result =
GetByte( ( char * ) &( ( struct aStruct * ) 0 )->Addr,
1, ( char * ) ( &Dest ) );

My question is... does the struct aStruct live at address 0, or does
address 0 contain a pointer to wherever aStruct actually lives? Seems
to me like the "&" ahead of ( ( struct aStruct * ) 0 )->Addr would
indicate the latter...
struct aStruct is not a particular struct that resides at a particular
location, it is a struct type. This code creates a null pointer of
type "struct aStruct*", and then dereferences it. The behavior is
undefined, which ends the discussion as far as the C standard is
concerned.

Pragmatically, on many implementations a null pointer points at an
actual memory location, one that strictly conforming C code cannot
access. The result of the above conversion is to treat that memory
location as if it was the start of an object of type "struct aStruct".
The rest of the expression creates a char* pointer that points at the
location at which the "Addr" member of such a struct would reside. We
don't know what GetByte() will do with that pointer - you haven't told
us what GetByte() does. I would guess that this call to GetBytes()
copies 1 byte from that location into Dest.

This is all highly non-portable.
Nov 20 '08 #15
In article <13********************************@4ax.com>,
Eric <an*****************@nospam.comwrote:
>Technically, it's dereferencing a zero pointer,
No...
>which isn't guaranteed
to be the same thing as a null pointer, right?
Right.

But (type *)0 is always a null-pointer constant: if null pointers have
some odd representation, the compiler must recognise the construct and
generate that odd representation.

On such a system you may be able to get a "zero pointer" by casting
a non-constant zero or by setting a pointer using memcpy().

-- Richard
--
Please remember to mention me / in tapes you leave behind.
Nov 20 '08 #16
Eric <an*****************@nospam.comwrites:
On Wed, 19 Nov 2008 12:07:07 +0000, Ben Bacarisse
<be********@bsb.me.ukwrote:
>>The context of the code might explain the mystery, but it is hard to
guess any intent (at least I can't). Maybe there is a typo?

Good afternoon, Ben.

I apologize for not providing enough information... I was just trying
to minimize my post but I guess I minimized it too much. :-)

A more detailed block of code is:

bool result;
bool GetByte( char *theAddr, int theCount, char *theDest);

char Dest[ SOME_SIZE ];

result =
GetByte( ( char * ) &( ( struct aStruct * ) 0 )->Addr,
1, ( char * ) ( &Dest ) );

My question is... does the struct aStruct live at address 0, or does
address 0 contain a pointer to wherever aStruct actually lives? Seems
to me like the "&" ahead of ( ( struct aStruct * ) 0 )->Addr would
indicate the latter...
&((struct aStruct *)0)->Addr is the address where s.Addr would be
located, if s were located at address 0. (Note that -binds more
tightly than &.) On many machines this has the same numerical value as
offsetof(struct aStruct, Addr), and on such machines the offsetof()
macro might be implemented in this way. According to standard C,
however, this behavior can't be relied upon.

The point of offsetof(), of course, is to tell you where a certain
member is located with respect to the starting address of a struct. So given

struct foo { T1 a; T2 b; T3 c; } s;

then

(T2 *)(((char *)s) + offsetof(struct foo, b)) == &s.b

This is sometimes useful to allow an external function to modify
something inside a structure that it doesn't otherwise know anything
about.

Now back in your case, why the program would take that address, cast it
to char *, and pass it to a function, I don't know. I expect there is
non-portable platform-specific magic going on, and you might find better
information in a group dedicated to that platform. (Is this some sort
of embedded system?)
Nov 20 '08 #17
ri*****@cogsci.ed.ac.uk (Richard Tobin) writes:
[...]
But (type *)0 is always a null-pointer constant: if null pointers have
some odd representation, the compiler must recognise the construct and
generate that odd representation.
[...]

Quibble: (type*)0 isn't a null pointer constant, unless "type" is
void. But 0 is a null pointer constant, and a null pointer constant
converted to a pointer type is guaranteed to yield a null pointer of
that type.

The language could just as easily defined the term "null pointer
constant" to include (type*)0 for any type "type", so this isn't a
huge deal.

--
Keith Thompson (The_Other_Keith) ks***@mib.org <http://www.ghoti.net/~kst>
Nokia
"We must do something. This is something. Therefore, we must do this."
-- Antony Jay and Jonathan Lynn, "Yes Minister"
Nov 20 '08 #18
On Thu, 20 Nov 2008 10:34:12 -0800 (PST), jameskuyper
<ja*********@verizon.netwrote:
>We don't know what GetByte() will do with that pointer - you haven't told
us what GetByte() does. I would guess that this call to GetBytes()
copies 1 byte from that location into Dest.
I don't know what it does, either. I'm assuming that it does as you
speculate... copies 1 byte into Dest.

To answer Nate's question... yes, it's an embedded system, uses an
ARM7-based controller. There is quite a bit of, as you say,
non-portable platform-specific magic going on. I could, as you
suggest, find an ARM7 group and ask there, but mostly I'm just asking
from a standards-based perspective.

Thanks to all for your help...

Nov 20 '08 #19
Eric wrote:
[...]
bool result;
bool GetByte( char *theAddr, int theCount, char *theDest);

char Dest[ SOME_SIZE ];

result =
GetByte( ( char * ) &( ( struct aStruct * ) 0 )->Addr,
1, ( char * ) ( &Dest ) );

My question is... does the struct aStruct live at address 0, or does
address 0 contain a pointer to wherever aStruct actually lives? Seems
to me like the "&" ahead of ( ( struct aStruct * ) 0 )->Addr would
indicate the latter...
struct aStruct lives at add8uH(UOPUREi0-()_*$%*()U$(T(UO$TH(UH#%

That is, you get undefined behavior, since you're dereferencing a null
pointer. If you truely want an aStruct at address zero, do one of the
following, which I believe is merely implementation-defined:

typedef struct aStruct type;

unsigned long zero = 0;
type* at_zero = (type*) zero;

type* at_zero = ((type*) sizeof (type)) - 1;

You can't just calculate the address of one directly at zero because the
compiler specially handles conversion from a constant integer of value
zero, yielding a null pointer whose representation may NOT be zero. The
first approach converts a NON-constant integer (unsigned long to quiet any
pointless compiler warnings about zero not having enough bits for a
pointer, even though we're converting FROM the int, not to it), the second
finds the address of an aStruct at a non-zero address and then decrements
it back to zero.

If your system has a POINTER to an aStruct at address zero, change the
typedef to "typedef struct aStruct* type".

An easy way to find out whether you're doing it correctly is to print the
address with printf:

printf( "%p\n", (void*) at_zero ); //value of at_zero pointer
printf( "%p\n", (void*) &at_zero->member ); // address of member
Nov 20 '08 #20

This discussion thread is closed

Replies have been disabled for this discussion.

Similar topics

8 posts views Thread by Randell D. | last post: by
220 posts views Thread by Brandon J. Van Every | last post: by
699 posts views Thread by mike420 | last post: by
9 posts views Thread by Martin Maney | last post: by
92 posts views Thread by Reed L. O'Brien | last post: by
3 posts views Thread by Ron_Adam | last post: by
12 posts views Thread by Dario | last post: by
30 posts views Thread by James Conrad StJohn Foreman | last post: by
2 posts views Thread by yogesh | last post: by
2 posts views Thread by MrBee | last post: by
By using this site, you agree to our Privacy Policy and Terms of Use.