Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

(&const_object) can be evaluated to address of temporary

I had a discussion with one programmer, and its main point was that the following assertion in foo can be passed or not, depending on compiler.

#include <cassert> 

const int i = 0 ; 

void foo ( const int& i ) 
{  
    assert( &::i == &i ) ; 
} 

int main ( ) 
{ 
    foo( i ) ; 
} 

he told me, that (&i) expression can be evaluated to address of some temporary object. since i have doubts, i'm here. how reference to temp can be passed to a function, if in function I can check and do whatever I want with i's and parameter's addresses and expected semantics must be kept.? for example

#include <initializer_list>

const int i = 0 ;

bool func ( const int & i ) 
{ 
    return &::i == & i ; 
}

int main ()
{
    const int i = 0 ;
    for ( const int * each : { &::i , &i , } )
         if ( func( * each ) ) break ; // etc
}

probably such thing can occur somewhere, but not for this case. that is how i think, but i cannot get complete proof from standard.

what i have found already (thanks to npw) :

from [expr.call#5] :

Where a parameter is of const reference type a temporary object is introduced if needed ([dcl.type], [lex.literal], [lex.string], [dcl.array], [class.temporary])

first four references are not applicable to my case, but fifth gives a hope.

so my question is : does standard give guaranties, that assertion in foo will be hold.?

like image 763
Volodymyr Boiko Avatar asked Mar 30 '17 22:03

Volodymyr Boiko


People also ask

What does parenthesis look like?

Parentheses are a pair of punctuation marks that are most often used to add additional nonessential information or an aside to a sentence. Parentheses resemble two curved vertical lines: ( ). A single one of these punctuation marks is called a parenthesis.

What is this {} called?

The "{}" are referred to as curly brackets or braces while "<>" are often called angle brackets or braces. The term "curly braces" is more favored in the U.S., while "brackets" is more widely used in British English.

What is this bracket called <>?

The four main paired punctuation symbols are the bracket (or square bracket; also called parenthesis in British English), the parenthesis (plural: parentheses), the brace (curly bracket in British English), and the inequality sign (pointy bracket).

What is the difference between () and [] in math?

The notation may be a little confusing, but just remember that square brackets mean the end point is included, and round parentheses mean it's excluded. If both end points are included the interval is said to be closed, if they are both excluded it's said to be open.


1 Answers

In the first code sample, the &::i == &i condition is always true. A reference of type const int& binds directly to an object of type const int. There is no temporary object created.

C++14 [dcl.init.ref]/5:

A reference to type “cv1 T1” is initialized by an expression of type “cv2 T2” as follows:

  • If the reference is an lvalue reference and the initializer expression
    • is an lvalue (but is not a bit-field), and “ cv1 T1” is reference-compatible with “ cv2 T2,” or
    • [...], then the reference is bound to the initializer expression lvalue in the first case [...]

A type is reference-compatible with itself.

The second example is similar: certainly, initializing a pointer with the address of an object does not create a temporary. It points to the object.

like image 128
M.M Avatar answered Oct 02 '22 02:10

M.M