I compiled the following program with MSVC /O2
and clang:
int i;
constexpr int& ir = i;
constexpr int* ip = &i;
int main()
{
ir = 1;
*ip = 2;
}
MSVC /O2 clang
=========================== =============================================
int i DD 01H DUP (?) ; i i:
_DATA SEGMENT .long 0 # 0x0
int & ir DQ FLAT:int i ; ir
_DATA ENDS ir:
.quad i
ir
, but not from ip
(code from main
is omitted above). See on godbolt . Why are ir
and ip
different? I learnt, that in assembly code references and pointers are the same. Gcc does an even stranger thing. I compiled the following program with gcc -O0
and -O2
:
int i;
constexpr int& ir1 = i;
constexpr int* ir1p1 = &i;
constexpr int& ir2 = i;
constexpr int* ir2p1 = &i;
constexpr int* ir2p2 = &i;
constexpr int& ir3 = i;
constexpr int* ir3p1 = &i;
constexpr int* ir3p2 = &i;
constexpr int* ir3p3 = &i;
gcc -O0 gcc -O2
========= ==================
i: ir3:
.zero 4 .quad i
ir1: ir2:
.quad i .quad i
.quad i ir1:
ir2: .quad i
.quad i i:
.quad i .zero 4
.quad i
ir3:
.quad i
.quad i
.quad i
.quad i
-O0
why are there several .quad i
's under the reference variables?-O2
code is generated from references, but not from pointers. Why is this difference? See on godbolt . Aside from the directives issue, this is just linkage : constexpr
implies const
(on the variable itself, not its referent, if any), and thereby gives internal linkage to your pointers. (This is a hack to allow namespace-scope named constants in header files prior to C++17's inline variables; it's unfortunate that we have to remember it now.) Since no other translation unit can refer to them, there's no need to emit symbols for them; the references, however, can be declared and used elsewhere:
extern int &ir;
void count() {++ir;}
and so there must be a symbol to which to attach such uses.
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.