2

Is there any section in the C++ standard the shows that NULL references are ill-formed? I am trying to show my lecturer (this is for an assignment for which I am being graded) that the following expression is undefined behaviour:

AClass* ptr = 0;
AClass& ali = *ptr;
std::cout << "\n" << (AClass*) &ali << '\n';

The violations I see, is dereferencing of a null pointer, and then referencing a null reference. In an a program he is using as a correct example, he is comparing the return of the dereferenced pointer reference:

(AClass*) &ali != (AClass*) 0

As a test for an objects validity. I saw this as completely undefined behavior; I want to find a quote from the standard that is a bit more concrete for my explanation.

If I'm wrong, then please show where I have made an error.

Jan Schultke
  • 17,446
  • 6
  • 47
  • 96
hiddensunset4
  • 5,825
  • 3
  • 39
  • 61
  • 1
    related: http://stackoverflow.com/questions/2474018/when-does-invoking-a-member-function-on-a-null-instance-result-in-undefined-behav/2474021#2474021 – BlueRaja - Danny Pflughoeft Apr 08 '11 at 01:43
  • 1
    While you're correct that it's undefined behavior, in practice it's likely to work just because of the way references are usually implemented. The problem is that relying on "usually" is a very bad idea. – Mark Ransom Apr 08 '11 at 02:21
  • I saw the error as soon as I read his code, but originally decided to go with it, until I began receiving segmentation faults, in which I investigated to find it was not returning a null address, it was returning 0x1. This was consistent on Ubuntu, but inconsistent on Windows. – hiddensunset4 Apr 08 '11 at 06:20
  • 1
    @Mark: Well, usually :) – BlueRaja - Danny Pflughoeft Apr 08 '11 at 13:53

2 Answers2

6

§8.5.3/1: "A variable declared to be a T&, that is “reference to type T” (8.3.2), shall be initialized by an object, or function, of type T or by an object that can be converted into a T."

The code above does not initialize the reference with an object or function of type T or an object that can be converted to T. The violates the "shall". At that point, the only room for question is whether it's undefined behavior, or whether this qualifies as a diagnosable rule, in which case the compiler would be required to give an error message. Either way, it's clearly wrong though.

Jerry Coffin
  • 476,176
  • 80
  • 629
  • 1,111
0

You should use pointers, and not references, if you wish to reassign. References are initialized once and for all and cannot be reassigned. Pointers can be created but left uninitialized, plus they can be reassigned.

8.3.2/1:

A reference shall be initialized to refer to a valid object or function. 
[Note: in particular, a null reference 
cannot exist in a well-defined program, because the only way to create such 
a reference would be to bind it to the    
“object” obtained by dereferencing a null pointer, which causes undefined 
behavior. As described in 9.6, a reference cannot be bound directly to a bit-field]

1.9/4:

Certain other operations are described in this International Standard as undefined 
(for example, the effect of dereferencing the null pointer)
kiriloff
  • 25,609
  • 37
  • 148
  • 229