U
Urs Thuermann
I have again a question that I don't find a definitve answer for in my
draft copy of ISO 9899-99: Is it allowed to add an integer to a null
pointer and what will be the result?
See the following short example:
char *a = 0, *b = 0, *p, *q;
void f(void)
{
p = a + 0;
q = a + 10;
}
I only could find constraints for pointers that point to an object in
section "6.5.6 Additive operators":
Constraints
[#2] For addition, either both operands shall have
arithmetic type, or one operand shall be a pointer to an
object type and the other shall have integer type.
(Incrementing is equivalent to adding 1.)
So the pointer must have object type (as opposed to void*), but does
not need to point to an object. Right? Then (char*)0 would be ok.
[#7] For the purposes of these operators, a pointer to a
nonarray object behaves the same as a pointer to the first
element of an array of length one with the type of the
object as its element type.
[#8] When an expression that has integer type is added to or
subtracted from a pointer, the result has the type of the
pointer operand. If the pointer operand points to an
element of an array object, ...
The null pointer is neither a pointer to a nonarray object nor a
pointer to an array element. So [#8] only says that (char*)0 + 1 is
of type (char*), but the rest is irrelvant.
So is that addition allowed? And is there a guarantee, that
(char*)0 + 0 == (char*)0
and
(char*)0 + 1 != (char*)0
It is clear that allmost all implementations will do so but can one
rely on this? This question turned up to me when I was writing a
short code snippet, similar to this:
char *s = 0, *old;
size_t size = 0, len = 0, n;
for (...) {
do {
n = snprintf(s + len, size - len, fmt, ...);
if (n >= size - len) {
old = s;
size += 1024;
s = realloc(s, size);
if (!s) {
goto error;
}
}
} while (s != old);
len += n;
}
The term s + len will be null pointer plus 0 in the first iteration.
(BTW, snprint(NULL, 0, ...) is allowed by ISO C, no problem here).
urs
draft copy of ISO 9899-99: Is it allowed to add an integer to a null
pointer and what will be the result?
See the following short example:
char *a = 0, *b = 0, *p, *q;
void f(void)
{
p = a + 0;
q = a + 10;
}
I only could find constraints for pointers that point to an object in
section "6.5.6 Additive operators":
Constraints
[#2] For addition, either both operands shall have
arithmetic type, or one operand shall be a pointer to an
object type and the other shall have integer type.
(Incrementing is equivalent to adding 1.)
So the pointer must have object type (as opposed to void*), but does
not need to point to an object. Right? Then (char*)0 would be ok.
[#7] For the purposes of these operators, a pointer to a
nonarray object behaves the same as a pointer to the first
element of an array of length one with the type of the
object as its element type.
[#8] When an expression that has integer type is added to or
subtracted from a pointer, the result has the type of the
pointer operand. If the pointer operand points to an
element of an array object, ...
The null pointer is neither a pointer to a nonarray object nor a
pointer to an array element. So [#8] only says that (char*)0 + 1 is
of type (char*), but the rest is irrelvant.
So is that addition allowed? And is there a guarantee, that
(char*)0 + 0 == (char*)0
and
(char*)0 + 1 != (char*)0
It is clear that allmost all implementations will do so but can one
rely on this? This question turned up to me when I was writing a
short code snippet, similar to this:
char *s = 0, *old;
size_t size = 0, len = 0, n;
for (...) {
do {
n = snprintf(s + len, size - len, fmt, ...);
if (n >= size - len) {
old = s;
size += 1024;
s = realloc(s, size);
if (!s) {
goto error;
}
}
} while (s != old);
len += n;
}
The term s + len will be null pointer plus 0 in the first iteration.
(BTW, snprint(NULL, 0, ...) is allowed by ISO C, no problem here).
urs