Address constant expression

O

Old Wolf

The code is:
extern int x[1];

char *ptr1 = 8 + (char *)&x;
char *ptr2 = (char *)(8 + (unsigned)&x);

My understanding is that the ptr1 declaration is correct but the
ptr2 is not, and the compiler can reject it (even if the compiler
has a meaningful definition of integer<->pointer conversions).

The expression "&x" certainly is an address constant. C99 6.6/7
says that the initializer of a static object can be an address
constant plus or minus an integer constant, which is certainly
what we have for ptr1. It seems to be intentionally worded to
allow the initializer to not point to an lvalue in this case.

Howver, it 6.6/9 says that an address constant must be either a
null pointer, a function designator, or a pointer to an lvalue
designating an object. (It goes on to give rules for how that pointer
can be formed). Since (8 + (unsigned)&x) could be pointing off
into the wild, it does not designate an lvalue, so it is not an
address
constant, so the initialization is ill-formed.

Is this correct?
 
R

Richard Heathfield

Old Wolf said:
The code is:
extern int x[1];

char *ptr1 = 8 + (char *)&x;
char *ptr2 = (char *)(8 + (unsigned)&x);

My understanding is that the ptr1 declaration is correct

No, the ptr1 declaration is not correct unless sizeof(int) >= 8. You can
legitimately form a pointer into an object, and you can point "one
past" the tail end of an array of objects. If sizeof(int) is 8 or more,
then x will have a size of 8 (or more) bytes, and thus &x is a pointer
to an array of at least 8 bytes, and thus 8 + (char *)&x will put you
either somewhere in x or one past the end. But if int is smaller than 8
bytes, then the pointer is not legitimate.
 
G

Guest

Old said:
Old Wolf said:
The code is:
extern int x[1];
char *ptr1 = 8 + (char *)&x;
char *ptr2 = (char *)(8 + (unsigned)&x);
My understanding is that the ptr1 declaration is correct

No, the ptr1 declaration is not correct unless sizeof(int) >= 8.

Is the compiler allowed to reject ptr1's declaration at compile-time?

It is, if (and only if) the initialisation would be performed during
every run of the program. Address constants are only relevant if ptr1
and ptr2 have static storage duration, and in that case, the
initialisation would always be performed, so the compiler is allowed
to reject it.
 

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

No members online now.

Forum statistics

Threads
473,955
Messages
2,570,117
Members
46,705
Latest member
v_darius

Latest Threads

Top