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.?
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.
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.
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).
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.
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.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With