คุณสมบัติหลักของ C99 สองประการที่ C ++ 11 ขาดกล่าวถึง“ ตัวเริ่มต้นที่กำหนดและ C ++”
ฉันคิดว่า 'ตัวเริ่มต้นที่กำหนด' เกี่ยวข้องกับการเพิ่มประสิทธิภาพที่เป็นไปได้ ที่นี่ฉันใช้“ gcc / g ++” 5.1 เป็นตัวอย่าง
#include <stdio.h>
#include <stdlib.h>
#include <assert.h>
struct point {
int x;
int y;
};
const struct point a_point = {.x = 0, .y = 0};
int foo() {
if(a_point.x == 0){
printf("x == 0");
return 0;
}else{
printf("x == 1");
return 1;
}
}
int main(int argc, char *argv[])
{
return foo();
}
เรารู้ว่าในเวลารวบรวมa_point.x
เป็นศูนย์เพื่อให้เราสามารถคาดหวังว่ามีการเพิ่มประสิทธิภาพเป็นหนึ่งfoo
printf
$ gcc -O3 a.c
$ gdb a.out
(gdb) disassemble foo
Dump of assembler code for function foo:
0x00000000004004f0 <+0>: sub $0x8,%rsp
0x00000000004004f4 <+4>: mov $0x4005bc,%edi
0x00000000004004f9 <+9>: xor %eax,%eax
0x00000000004004fb <+11>: callq 0x4003a0 <printf@plt>
0x0000000000400500 <+16>: xor %eax,%eax
0x0000000000400502 <+18>: add $0x8,%rsp
0x0000000000400506 <+22>: retq
End of assembler dump.
(gdb) x /s 0x4005bc
0x4005bc: "x == 0"
foo
ได้รับการปรับให้เหมาะกับการพิมพ์x == 0
เท่านั้น
สำหรับเวอร์ชัน C ++
#include <stdio.h>
#include <stdlib.h>
#include <assert.h>
struct point {
point(int _x,int _y):x(_x),y(_y){}
int x;
int y;
};
const struct point a_point(0,0);
int foo() {
if(a_point.x == 0){
printf("x == 0");
return 0;
}else{
printf("x == 1");
return 1;
}
}
int main(int argc, char *argv[])
{
return foo();
}
และนี่คือผลลัพธ์ของโค้ดแอสเซมบลีที่ปรับให้เหมาะสม
g++ -O3 a.cc
$ gdb a.out
(gdb) disassemble foo
Dump of assembler code for function _Z3foov:
0x00000000004005c0 <+0>: push %rbx
0x00000000004005c1 <+1>: mov 0x200489(%rip),%ebx # 0x600a50 <_ZL7a_point>
0x00000000004005c7 <+7>: test %ebx,%ebx
0x00000000004005c9 <+9>: je 0x4005e0 <_Z3foov+32>
0x00000000004005cb <+11>: mov $0x1,%ebx
0x00000000004005d0 <+16>: mov $0x4006a3,%edi
0x00000000004005d5 <+21>: xor %eax,%eax
0x00000000004005d7 <+23>: callq 0x400460 <printf@plt>
0x00000000004005dc <+28>: mov %ebx,%eax
0x00000000004005de <+30>: pop %rbx
0x00000000004005df <+31>: retq
0x00000000004005e0 <+32>: mov $0x40069c,%edi
0x00000000004005e5 <+37>: xor %eax,%eax
0x00000000004005e7 <+39>: callq 0x400460 <printf@plt>
0x00000000004005ec <+44>: mov %ebx,%eax
0x00000000004005ee <+46>: pop %rbx
0x00000000004005ef <+47>: retq
เราจะเห็นได้ว่านั่นa_point
ไม่ใช่ค่าคงที่ของเวลาคอมไพล์