Initialize reference to itself

L

Luke Meyers

I just spent two and a half days chasing down a bug resulting from
initializing a reference to itself, like so:

struct Bar;
struct Foo {
Bar& bar;
Foo() : bar(bar) {}
};

The compiler I was using (gcc 3.2.3) issued no warning for this. I
assume that any use of bar produces undefined behavior. If this is the
case, then it seems to be a defect in the compiler not to issue a
warning. Is my analysis correct? Specifically:

(1) Is there any conceivable circumstance in which this will produce
anything but undefined behavior?
(2) is there any reason why a compiler would have difficulty detecting
this, in the general case?
(3) Anyone happen to know if later versions of gcc, or other compilers,
address this?

Please note that while I'm referring to a specific compiler here, my
question (at least, part (1)) is really about language behavior, hence
not (IMHO) OT.

Luke
 
B

Bob Hairgrove

I just spent two and a half days chasing down a bug resulting from
initializing a reference to itself, like so:

struct Bar;
struct Foo {
Bar& bar;
Foo() : bar(bar) {}
};

It's about time that you got a copy of the C++ standard. said:
The compiler I was using (gcc 3.2.3) issued no warning for this. I
assume that any use of bar produces undefined behavior. If this is the
case, then it seems to be a defect in the compiler not to issue a
warning. Is my analysis correct? Specifically:

(1) Is there any conceivable circumstance in which this will produce
anything but undefined behavior?

No. See 8.3.2, par. 4. A reference must be initialized with a "valid
object or function". Therefore, a reference cannot be initialized with
itself.
(2) is there any reason why a compiler would have difficulty detecting
this, in the general case?

I'm not sure whether a compiler diagnostic is required here, but it is
UDB in any case. Note that a compiler vendor (or implementation) is
not necessarily required to issue a warning or error when your code
induces UDB.
 
P

Pete Becker

Bob said:
I'm not sure whether a compiler diagnostic is required here, but it is
UDB in any case. Note that a compiler vendor (or implementation) is
not necessarily required to issue a warning or error when your code
induces UDB.

Undefined behavior arises from invalid code for which a diagnostic is
not required. So, no, a conforming implementation is not required to
diagnose this construct. And with good reason: it's hard to formulate
the true rule in a way that can always be diagnosed. In this case it's
easy. In others it's not:

struct node
{
node *next;
};

node nil = { &nil }; // legal and useful
node nil = get_node(&nil);

node get_node(node *ptr)
{ // okay, as above
node n;
n.next = ptr;
return n;
}

node get_node(node *ptr)
{ // trouble
return *ptr;
}
 
L

Luke Meyers

Bob said:
It's about time that you got a copy of the C++ standard. <g>

It's in the mail on its way, don't worry. And the two and a half days
were spent on a chain of inferences and simplification which led me to
actually *look* at the offending line of code, at which time I
immediately realized the problem. The standard wouldn't have helped me
at that point.

The reason the error was introduced originally was that my intent was
to initialize a reference owned by an inner class with a variable of
the same name in its containing class. Dumb mistake, but we all make
those and it's helpful if a compiler can catch the easy ones.
I'm not sure whether a compiler diagnostic is required here, but it is
UDB in any case. Note that a compiler vendor (or implementation) is
not necessarily required to issue a warning or error when your code
induces UDB.

I'm not surprised that it's not required; my point was that this would
be a useful case for a compiler to issue a non-mandatory warning.

Anyway, thanks.

Luke
 
N

Neelesh Bodas

Roman said:
What is UDB?

UDB is an acronym for "Un Defined Behaviour"

<joke>
What it means is that compiler is free to mail all private letters on
your harddrive to all people and newsgroups in your address book,
including comp.lang.c++
</joke>
 
R

Rennie deGraaf

Neelesh said:
UDB is an acronym for "Un Defined Behaviour"

<joke>
What it means is that compiler is free to mail all private letters on
your harddrive to all people and newsgroups in your address book,
including comp.lang.c++
</joke>

Fortunately, not too many compilers do that. Otherwise, the SNR in this
group would be pretty bad.
 
P

Pete Becker

Neelesh said:
UDB is an acronym for "Un Defined Behaviour"

<joke>
What it means is that compiler is free to mail all private letters on
your harddrive to all people and newsgroups in your address book,
including comp.lang.c++
</joke>

More formally, it means that the C++ Language definition doesn't say
what happens when you use that code. In some cases the result is benign
and predictable; in others it's not.
 
J

james01773

You could always get a syntax checker such as pc-lint or another
compiler (just to double check the warnings). Another compiler or
syntax checker may catch stuff which your compiler misses.
 

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
474,170
Messages
2,570,925
Members
47,466
Latest member
DrusillaYa

Latest Threads

Top