Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Dangling references and undefined behavior

Assume a dangling reference x. Is it undefined behavior to just write

&x;

or even

x;

?

like image 260
Luchian Grigore Avatar asked Feb 06 '13 13:02

Luchian Grigore


People also ask

What is a dangling reference?

A link or pointer to an instruction, table element, index item, etc. that no longer contains the same content. If the reference is not a currently valid address, or if it is valid but there is no content in that location, it may cause the computer to crash if the software is not programmed carefully.

Why are dangling references created and why are they a problem?

A dangling reference is a reference to an object that no longer exists. Garbage is an object that cannot be reached through a reference. Dangling references do not exist in garbage collected languages because objects are only reclaimed when they are no longer accessible (only garbage is collected).

Why does C have undefined behavior?

C and C++ have undefined behaviors because it allows compilers to avoid lots of checks. Suppose a set of code with greater performing array need not keep a look at the bounds, which avoid the needs for complex optimization pass to check such conditions outside loops.

How is dangling reference addressed?

Sometimes the programmer fails to initialize the pointer with a valid address, then this type of initialized pointer is known as a dangling pointer in C. Dangling pointer occurs at the time of the object destruction when the object is deleted or de-allocated from memory without modifying the value of the pointer.


Video Answer


2 Answers

First off, very interesting question.

I would say it is undefined behaviour, assuming "dangling reference" means "referred-to object's lifetime has ended and the storage the object occupied has been reused or released." I base my reasoning on the following standard rulings:

3.8 §3:

The properties ascribed to objects throughout this International Standard apply for a given object only during its lifetime. [ Note: In particular, before the lifetime of an object starts and after its lifetime ends there are significant restrictions on the use of the object, as described below ...]

All the cases "as described below" refer to

Before the lifetime of an object has started but after the storage which the object will occupy has been allocated38 or, after the lifetime of an object has ended and before the storage which the object occupied is reused or released

1.3.24: undefined behavior

behavior for which this International Standard imposes no requirements [ Note: Undefined behavior may be expected when this International Standard omits any explicit definition of behavior or when a program uses an erroneous construct or erroneous data. ...]

I apply the following train of thoughts to the above quotes:

  1. If the standard doesn't describe behaviour for a situation, the behvaiour is undefined.
  2. The standard only describes behvaiour for objects within their lifetime, and a few special cases near the start/end of their lifetime. None of these apply to our dangling reference.
  3. Therefore, using the danling reference in any way has no behaviour prescribed by the standard, hence the behaviour is undefined.
like image 142
Angew is no longer proud of SO Avatar answered Sep 30 '22 19:09

Angew is no longer proud of SO


Supposing that x was initialized with a valid object, which was then destroyed, §3.8/6 applies:

Similarly, before the lifetime of an object has started but after the storage which the object will occupy has been allocated or, after the lifetime of an object has ended and before the storage which the object occupied is reused or released, any glvalue that refers to the original object may be used but only in limited ways. For an object under construction or destruction, see 12.7. Otherwise, such a glvalue refers to allocated storage (3.7.4.2), and using the properties of the glvalue that do not depend on its value is well-defined. The program has undefined behavior if:

— an lvalue-to-rvalue conversion (4.1) is applied to such a glvalue,

— the glvalue is used to access a non-static data member or call a non-static member function of the object, or

— the glvalue is bound to a reference to a virtual base class (8.5.3), or

— the glvalue is used as the operand of a dynamic_cast (5.2.7) or as the operand of typeid.

So, simply taking the address is well-defined, and (referring to the neighboring paragraphs) can even be productively used to create a new object in place of the old one.

As for not taking the address and just writing x, that really does absolutely nothing, and it is a proper subexpression of &x. So it's also OK.

like image 34
Potatoswatter Avatar answered Sep 30 '22 21:09

Potatoswatter