Is int const myNull 0 a null pointer constant?

Is int const myNull 0 a null pointer constant?

Post by kanz » Thu, 26 Aug 2004 13:27:46



No problem. If we assign myNull to an int, the implicit conversion
takes place.

The problem is that we are not assigning myNull to an int, but to a
pointer. And that there is no implicite conversion int->pointer. To
initialize a pointer with an int, the int must be a null pointer
constant. And the definition for null pointer constant says explicitly
that it must be an rvalue.

The real question is: does an rvalue to lvalue conversion take place in
this case, and if it does, why does the standard explicitly say rvalue
here.


#include <cstddef>

void f( void* ) ;

int
main()
{
int const myNull = 0 ;
f( myNull ) ;
return 0 ;
}

G++ 3.4.0 says:
nullptr.cc: In function `int main()':
nullptr.cc:10: error: invalid conversion from `int' to `void*'
nullptr.cc:10: error: initializing argument 1 of `void f(void*)'

G++ 2.95.2 accepts it, so presumably, they added the error check
explicitly, because they read the standard literally.

James Kanze GABI Software http://www.yqcomputer.com/
Conseils en informatique orient objet/
Beratung in objektorientierter Datenverarbeitung
9 place Sard, 78210 St.-Cyr-l'ole, France, +33 (0)1 30 23 00 34

---
[ comp.std.c++ is moderated. To submit articles, try just posting with ]
[ your news-reader. If that fails, use mailto:std-c++@ncar.ucar.edu ]
[ --- Please see the FAQ before posting. --- ]
[ FAQ: http://www.yqcomputer.com/ ]
 
 
 

Is int const myNull 0 a null pointer constant?

Post by kanz » Fri, 27 Aug 2004 02:17:02

XXXX@XXXXX.COM (Bob Hairgrove) wrote in message
news:< XXXX@XXXXX.COM >...








But that is exactly the question. Should the lvalue be converted to an
rvalue? The text in .10/1 seems to say that the expression itself
must be an rvalue, not that it must be something convertable into an
rvalue. If an lvalue is also acceptable, why the word "rvalue" in the
definition.

Note too that the definition insists on integer type. An integral
constant expression can have an enum type, but apparently, something
like "enum { myNull = 0 } ;" does not define a null pointer constant
either.

Since I don't know what the original authors actually had in mind when
they formulated that paragraph, I'm asking here. I have my opinion as
to what the standard actually says (it actually seems pretty clear), but
I'd like an authorative answer as to whether this is what it was
actually meant to say (or whether I've missed something important).

I'm also curious whether this is a "regression error" in g++, or whether
they did it intentionally, because they read the same sentence in the
standard that I did. I rather suspect the latter, especially as "myNull
+ 0" is treated as a null pointer constant, but of course, only the
people who made the change in g++ can say for sure.

For what it's worth, even g++ 2.95.2 and VC++ 6.0 reject the enum,
although Sun CC accepts it. So even compiler implementors don't seem to
be completely in agreement. Given the following program:

void f( void* ) ;

void
g()
{
int const myNull = 0 ;
f( myNull ) ; // line 8
f( myNull + 0 ) ; // line 9
}

void
h()
{
enum { myNull = 0 } ;
f( myNull ) ; // line 16
f( myNull + 0 ) ; // line 17
}

One compiler I have access to (Sun CC 5.1) compiles it without errors,
two (g++ 2.95.2 and VC++ 6.0) give an error on line 16 only, and one
(g++ 3.4.0) gives errors on both line 8 and line 16.

I don't know if it is worth mentionning, but in C, line 16 IS a legal
null pointer constant, because enum constants in C have type int. It's
entirely possible that Sun CC accepts it simply for reasons of backwards
compatibility. (Sun CC does a lot of things for reasons of backwards
compatibility.)

Finally (just to open another can of worms), there is a problem if we
accept the rvalue to lvalue conversion -- the conversion strips away the
const. Frankly, I'm not sure what the implications of this really
are:-). (Probably nothing, really, since .19/1 is pretty clear that
such a variable can be used in a integral constant expression. But I
like the idea that a non const type can result in a constant
expression. It's along the same lines as the fact that a null pointer
constant cannot have a pointer type:-).)

James Kanze GABI Software http://www.gabi-soft.fr
Conseils en informatique orient objet/
Beratung in objektorientierter Datenverarbeitung
9 place Sard, 78210 St.-Cyr-l'ole, France, +33 (0)1 30 23 00 34

---
[ comp.std.c++ is moderated. To submit articles, try just posting with ]
[ your news-reader. If that fails, use mailto:std-c++@ncar.ucar.edu ]
[ --- Please see the FAQ before posting. --- ]
[ FAQ: http://www.jamesd.demon.co.uk/csc/faq.html ]


 
 
 

Is int const myNull 0 a null pointer constant?

Post by johnchx » Fri, 27 Aug 2004 02:23:54


XXXX@XXXXX.COM (Bob Hairgrove) wrote


I think that's correct, but it may be a defect in the standard.
Consider:


extern const int i; // defined in another translation unit

int main () {
void* p = i;
}

The validity of the assignment depends on the availability of the
conversion from const int to pointer type, which in turn depends on
the *value* of i.

Off the top of my head, I can't think of any other situation in which
the existence of an implicit conversion from type T1 to type T2
depends on the value of the particular object of type T1 under
consideration.

It looks like there are two issues here:

(1) Wouldn't it make sense to restrict the use of const variables
to variables defined in the current translation unit?

(2) The idea of making the "type-correctness" of a statement or
expression dependent on the value of one of the operands seems
just wrong. It's against nature. (The solution would be a
first-class null pointer constant built into the language,
which, I gather, is currently under consideration.)

---
[ comp.std.c++ is moderated. To submit articles, try just posting with ]
[ your news-reader. If that fails, use mailto:std-c++@ncar.ucar.edu ]
[ --- Please see the FAQ before posting. --- ]
[ FAQ: http://www.yqcomputer.com/ ]
 
 
 

Is int const myNull 0 a null pointer constant?

Post by invali » Fri, 27 Aug 2004 09:05:27


I believe it should take place, but only in the special case where the
lvalue has the value zero (or evaluates to 0). At least that is how I
understand it. After all, paragraph 7 of section 3.10 says:

"Whenever an lvalue appears in a context where an rvalue is expected,
the lvalue is converted to an rvalue; see 4.1, 4.2 and 4.3".

Now 4.1, 4.2 and 4.3 don't seem to shed any light on the subject, so I
assume that the authors of the standard mean exactly what they have
written.

Interestingly enough, in "TC++PL" section 5.1.1 "Zero" (3rd edition,
page 88) Bjarne Stroustrup recommends declaring NULL like this:
const int NULL = 0;
instead of using a macro, or else using a literal value of 0. I
believe that this makes the *intention* of the standard quite clear.

---
[ comp.std.c++ is moderated. To submit articles, try just posting with ]
[ your news-reader. If that fails, use mailto:std-c++@ncar.ucar.edu ]
[ --- Please see the FAQ before posting. --- ]
[ FAQ: http://www.yqcomputer.com/ ]
 
 
 

Is int const myNull 0 a null pointer constant?

Post by bjarn » Fri, 27 Aug 2004 15:18:56


Yes.


It's a bug in GCC 3.4.0

-- Bjarne Stroustrup; http://www.yqcomputer.com/ ~bs

---
[ comp.std.c++ is moderated. To submit articles, try just posting with ]
[ your news-reader. If that fails, use mailto:std-c++@ncar.ucar.edu ]
[ --- Please see the FAQ before posting. --- ]
[ FAQ: http://www.yqcomputer.com/ ]
 
 
 

Is int const myNull 0 a null pointer constant?

Post by llewelly.a » Sat, 28 Aug 2004 02:41:53


XXXX@XXXXX.COM writes:





[snip]

There was a bugzilla item opened on this bug some time back, and it
was closed as not a bug on the same logic you use:
http://www.yqcomputer.com/

---
[ comp.std.c++ is moderated. To submit articles, try just posting with ]
[ your news-reader. If that fails, use mailto:std-c++@ncar.ucar.edu ]
[ --- Please see the FAQ before posting. --- ]
[ FAQ: http://www.yqcomputer.com/ ]
 
 
 

Is int const myNull 0 a null pointer constant?

Post by kanz » Sat, 28 Aug 2004 02:42:19


Agreed. This paragraph does seem conclusive. (I suppose one might
argue that we only expect an rvalue because it is a null pointer
constant, that it isn't a null pointer constant until the conversion
takes place, and that the conversion doesn't take place until we expect
an rvalue, but that sounds rather farfetched to me.)


Now I'm left with the question, why does .10/1 insist on rvalue, if
you can use an lvalue as well?

James Kanze GABI Software http://www.yqcomputer.com/
Conseils en informatique orient objet/
Beratung in objektorientierter Datenverarbeitung
9 place Sard, 78210 St.-Cyr-l'ole, France, +33 (0)1 30 23 00 34

---
[ comp.std.c++ is moderated. To submit articles, try just posting with ]
[ your news-reader. If that fails, use mailto:std-c++@ncar.ucar.edu ]
[ --- Please see the FAQ before posting. --- ]
[ FAQ: http://www.yqcomputer.com/ ]
 
 
 

Is int const myNull 0 a null pointer constant?

Post by llewelly.a » Sat, 28 Aug 2004 04:25:50


XXXX@XXXXX.COM writes:




[snip]

If they did so, they did so mistakenly:

http://www.yqcomputer.com/ #456

---
[ comp.std.c++ is moderated. To submit articles, try just posting with ]
[ your news-reader. If that fails, use mailto:std-c++@ncar.ucar.edu ]
[ --- Please see the FAQ before posting. --- ]
[ FAQ: http://www.yqcomputer.com/ ]
 
 
 

Is int const myNull 0 a null pointer constant?

Post by falk.tannh » Sat, 28 Aug 2004 04:25:58


I don't think that 'i' qualifies as a constant expression in
the sense of 5.19/1 - you can't do
extern int const i;
char foo[i];
either - there is generally no way for the compiler to determine
if 'i' was actually initialised with a constant expression as
required by 5.19/1, since
int const i = static_ca<t(std::time(0));
or
int const i = std::rand();
are valid definitions of 'i'.

Falk

---
[ comp.std.c++ is moderated. To submit articles, try just posting with ]
[ your news-reader. If that fails, use mailto:std-c++@ncar.ucar.edu ]
[ --- Please see the FAQ before posting. --- ]
[ FAQ: http://www.yqcomputer.com/ ]
 
 
 

Is int const myNull 0 a null pointer constant?

Post by invali » Sat, 28 Aug 2004 05:22:31

On Thu, 26 Aug 2004 06:18:56 GMT, XXXX@XXXXX.COM (Bjarne Stroustrup)





"johnchx" has brought up an interesting point in this same thread
which has started me thinking:

What if myNull is defined in a different translation unit? How can the
compiler resolve the value at compile time?

I think his proposal to restrict things to variables in the current
translation unit would at least have the merit of making things a lot
easier on implementors (especially since myNull could be defined in a
shared library). OTOH, his restriction would remove much of the
incentive for declaring myNull this way in the first place (which IMHO
might not be a bad idea ... using the literal "0" everywhere seems
good enough to me).

Or is this something which is already covered somewhere by the
standard?

---
[ comp.std.c++ is moderated. To submit articles, try just posting with ]
[ your news-reader. If that fails, use mailto:std-c++@ncar.ucar.edu ]
[ --- Please see the FAQ before posting. --- ]
[ FAQ: http://www.yqcomputer.com/ ]
 
 
 

Is int const myNull 0 a null pointer constant?

Post by gdr » Sun, 29 Aug 2004 04:19:43


XXXX@XXXXX.COM writes:

[...]

| > What is the error shown by g++ 3.4.0 and the context in which it
| > happens?
|
| #include <cstddef>
|
| void f( void* ) ;
|
| int
| main()
| {
| int const myNull = 0 ;
| f( myNull ) ;
| return 0 ;
| }
|
| G++ 3.4.0 says:
| nullptr.cc: In function `int main()':
| nullptr.cc:10: error: invalid conversion from `int' to `void*'
| nullptr.cc:10: error: initializing argument 1 of `void f(void*)'

As I said elsewhere, that was an -unintended- behaviour. A regression.

| G++ 2.95.2 accepts it, so presumably, they added the error check
| explicitly, because they read the standard literally.

No, it was a fallaout for something else, not a behaviour that was intended.

--
Gabriel Dos Reis
XXXX@XXXXX.COM
Texas A&M University -- Computer Science Department
301, Bright Building -- College Station, TX 77843-3112

---
[ comp.std.c++ is moderated. To submit articles, try just posting with ]
[ your news-reader. If that fails, use mailto:std-c++@ncar.ucar.edu ]
[ --- Please see the FAQ before posting. --- ]
[ FAQ: http://www.yqcomputer.com/ ]
 
 
 

Is int const myNull 0 a null pointer constant?

Post by gdr » Sun, 29 Aug 2004 11:52:35


XXXX@XXXXX.COM writes:

[...]

| > Seems to me that this is definitely not conforming behavior according
| > to the current standard. "int const MyNull" is definitely a constant
| > integral value (see 5.9 and 4.10 of the standard), and the lvalue
| > should be implicitly converted to an rvalue here (see 3.10).
|
| But that is exactly the question. Should the lvalue be converted to an
| rvalue?

Yes, because myNull is used in a context where an rvalue is expected
and lvalue->rvalue automatically happens in such contexts.

[...]

| I'm also curious whether this is a "regression error" in g++, or whether

It is. While having the null discussion on fr.comp.lang.c last early
July, Bjarne brought to my attention that GCC was misbehaving on that
very same example. I immediately reported the regression and it got
fixed for GCC-3.4.2.

| they did it intentionally, because they read the same sentence in the
| standard that I did.

That never was an intentional behaviour.

--
Gabriel Dos Reis
XXXX@XXXXX.COM
Texas A&M University -- Computer Science Department
301, Bright Building -- College Station, TX 77843-3112

---
[ comp.std.c++ is moderated. To submit articles, try just posting with ]
[ your news-reader. If that fails, use mailto:std-c++@ncar.ucar.edu ]
[ --- Please see the FAQ before posting. --- ]
[ FAQ: http://www.yqcomputer.com/ ]
 
 
 

Is int const myNull 0 a null pointer constant?

Post by johnchx » Sun, 29 Aug 2004 11:53:38


XXXX@XXXXX.COM (Falk Tannhser) wrote


Just because it's manifestly impossible doesn't mean that the standard
doesn't require it. :-)

I was actually surprised not to find language in the standard
outlawing this, since "everybody knows" that the value of an integral
constant expression has to be availabe to the compiler at compile
time. And I suspect that it would be easy to drop in a line or two of
standardese to close the loophole. (I also suspect that I'm just
overlooking something, which someone will point me to at any
moment....)

I think the bigger picture issue is the essential "uncleanness" of
making the type-correctness of something depend on a value. You can
convert an int to a pointer, but only if it's the *magic* int?

I have the impression that this uglyness exists only to allow us to
write:

foo* p = 0;

because there's simply no other way to write down the notion "null
pointer" (and that's how C does it). I gather that the committee is
working on a proposal for a real name for the null pointer (nullptr)
which should allow us to deprecate this strangeness:

http://www.yqcomputer.com/

---
[ comp.std.c++ is moderated. To submit articles, try just posting with ]
[ your news-reader. If that fails, use mailto:std-c++@ncar.ucar.edu ]
[ --- Please see the FAQ before posting. --- ]
[ FAQ: http://www.yqcomputer.com/ ]
 
 
 

Is int const myNull 0 a null pointer constant?

Post by gdr » Sun, 29 Aug 2004 12:34:48


XXXX@XXXXX.COM (llewelly) writes:

[...]

| There was a bugzilla item opened on this bug some time back, and it
| was closed as not a bug on the same logic you use:
| http://www.yqcomputer.com/

That was a mistake. See

http://www.yqcomputer.com/

--
Gabriel Dos Reis
XXXX@XXXXX.COM
Texas A&M University -- Computer Science Department
301, Bright Building -- College Station, TX 77843-3112

---
[ comp.std.c++ is moderated. To submit articles, try just posting with ]
[ your news-reader. If that fails, use mailto:std-c++@ncar.ucar.edu ]
[ --- Please see the FAQ before posting. --- ]
[ FAQ: http://www.yqcomputer.com/ ]
 
 
 

Is int const myNull 0 a null pointer constant?

Post by gdr » Sun, 29 Aug 2004 12:35:15


XXXX@XXXXX.COM (johnchx) writes:

[...]

| I think that's correct, but it may be a defect in the standard.
| Consider:
|
|
| extern const int i; // defined in another translation unit
|
| int main () {
| void* p = i;
| }
|
| The validity of the assignment depends on the availability of the
| conversion from const int to pointer type, which in turn depends on
| the *value* of i.

The validity of the assignment depends on the presence of the
initializer. At the point of use of "i" in main(), all available
declarations for "i" do no provide an initializer, therefore it cannot
be deemed integral constant.
Forget about null pointer. Consider

extern const i;

enum E { e = i };

--
Gabriel Dos Reis
XXXX@XXXXX.COM
Texas A&M University -- Computer Science Department
301, Bright Building -- College Station, TX 77843-3112

---
[ comp.std.c++ is moderated. To submit articles, try just posting with ]
[ your news-reader. If that fails, use mailto:std-c++@ncar.ucar.edu ]
[ --- Please see the FAQ before posting. --- ]
[ FAQ: http://www.yqcomputer.com/ ]