Re: Insufficient guarantees for null pointers?



Wojtek Lerch wrote:
Harald van Dijk wrote:
Wojtek Lerch wrote:
The way I imagine it, a pointer would need to contain at least
these pieces:
...

This way would avoid one problem. Another that isn't solved by this,
even with extra info stored in pointers or before any object, is
conversions to/from char *. When combined with unions and offsetof, how
will the compiler know what the bounds are after converting that char *
to an int *, if it could point to either of two arrays which happen to
overlap?

That may be easy or difficult or impossible, depending on the exact
rules; unfortunately, the text of the standard doesn't tell us the exact
rules. If you read it literally, the only thing it guarantees about
converting your int* pointer to char* and back is that the result
compares equal to the original pointer. There are no words there that
promise that the double conversion preserves the array bounds associated
with the pointer; in particular, there's no guarantee that the converted
pointer points to an object rather than to one past the end of an array.
Everybody knows that the intent was to promise more than the literal
reading does (as a matter of fact, a lot of people seem not to notice
how little the literal reading guarantees); but I doubt everybody agrees
on the exact interpretation of what exactly the promise was meant to be,
especially when applied to really obscure cases involving pointer
conversions and unions or allocated memory.

I'm not sure I'm understanding correctly. I will assume offsetof is
supposed to be useful.

struct S { union U {
int a[1][3];
int b[2][2];
} u; } s;
int *p1 = &s.u.a[1][0];
int *p2 = (int *) ((char *) &s + offsetof(struct S, u.a[1][0]));
int *p3 = &s.u.b[1][1];
int *p4 = (int *) ((char *) &s + offsetof(struct S, u.b[1][1]));

p1, p2, p3 and p4 all compare equal, right? I was concerned with the
different bounds for p2 and p4, since the exact same constant is added
to both, but you're saying that depending on the interpretation of the
standard, only 0 or 1 can be added to either of them, even when more is
allowed for p1 and p3? If that interpretation is correct, then I have
no more doubts about the possibility of a strict bounds-checking C
compiler right now. This is a bit of a surprise to me though, I
would've thought p1 and p2 could be used interchangeably, and the same
for p3 and p4.

.



Relevant Pages

  • Re: Alignment of foo[1][1][1][1]
    ... guaranteed by the standard, but will work on any sane implementation. ... as an exception to the general rules for pointer conversions ... it talks about array subscripts. ...
    (comp.lang.c)
  • Re: Is this valid C statement?
    ... > Where does the standard say that a conversion between a function ... > pointer and an object pointer, even with an explicit cast, is allowed? ... C99 6.3.2.3 enumerates a number of kinds of conversions that are ... I've tried the following program with several C compilers: ...
    (comp.lang.c)
  • Re: Please help me to clarify the invalid values of unary operator *
    ... Conversions from another pointer type that could otherwise create ... Do you mean the conversion itself has undefined behavior? ... the anti-aliasing rules listed in 6.5p6, so it seems redundant to list ...
    (comp.std.c)
  • Re: K&R2 , exercise 7.6
    ... tightly restricted than casts (explicit conversions). ... and let the compiler generate the conversion for you. ... If you get the type right, the cast is harmless and completely ... NULL is a macro that expands to a null pointer constant. ...
    (comp.lang.c)
  • Re: Is this valid C statement?
    ... >>Where does the standard say that a conversion between a function ... >>pointer and an object pointer, even with an explicit cast, is allowed? ... So if it's a case of undefined behavior, then it's "allowed", in the ... C99 6.3.2.3 specifies what pointer conversions are ...
    (comp.lang.c)