好奇心的问题。在C中,我们可以直接初始化值,也可以在定义变量后赋值。喜欢
char* pStr = NULL;
或
char* pStr;
pStr = NULL;
功能方面它们很相似,但编译后有什么不同。后期需要额外的指令周期,或者现代编译器是否足够智能以进行优化。
N.B:我正在审查一个旧的代码库,其中第二个案例被广泛使用。这就是为什么我很好奇,如果我可以通过改变所有地方的代码来获得真正的改变。
答案 0 :(得分:4)
第一个代码段使用值初始化变量。第二个默认值 - 初始化它,对于具有自动存储持续时间的指针不执行任何操作,然后分配值。
对于具有自动存储持续时间的非常量指针,应该没有区别,除非您在初始化之前无意中使用它,这将是UB。
例如引用或常量等其他内容需要第一种样式。
答案 1 :(得分:0)
取决于它是本地的还是全球的
int hello;
int world=6;
void fun ( void )
{
int foo;
int bar=5;
foo=4;
hello=2;
}
对于globals你好会落在.bss中(可能需要将bootstrap代码设置为零)并且会创建执行运行时的代码来设置"变量"到2.世界将登陆.data并在编译时设置初始值为6。分配的内存/数据空间将具有该值,但在使用之前可能需要引导来放置该数据。
理想情况下,foo和bar在堆栈上,这是一个运行时"分配"所以在任何一种情况下都需要代码为它们腾出空间以及运行时将它们设置为一个值。如果你把它们变成静态的或基本上是#34;本地全局变量"它们现在与登陆.bss或.data栏中的全局变量属于同一类别,一次初始化为5,但foo是在生成的.text代码中在运行时设置的。简单的例子,编译和反汇编将显示所有这些是如何工作的,由于优化器可能会根据其余代码消除一些您正在寻找的内容,因此这些内容并非无足轻重。 (上面的代码将hello设置为2,foo和bar都是死代码,并且会被优化掉。)
00000000 <fun>:
0: e3a02002 mov r2, #2
4: e59f3004 ldr r3, [pc, #4] ; 10 <fun+0x10>
8: e5832000 str r2, [r3]
c: e12fff1e bx lr
10: 00000000 andeq r0, r0, r0
Disassembly of section .data:
00000000 <world>:
0: 00000006 andeq r0, r0, r6
如果我在没有启动代码的情况下进行非常粗略的链接等,请查看剩下的图片:
00001000 <fun>:
1000: e3a02002 mov r2, #2
1004: e59f3004 ldr r3, [pc, #4] ; 1010 <fun+0x10>
1008: e5832000 str r2, [r3]
100c: e12fff1e bx lr
1010: 00011018 andeq r1, r1, r8, lsl r0
Disassembly of section .data:
00011014 <__data_start>:
11014: 00000006 andeq r0, r0, r6
Disassembly of section .bss:
00011018 <__bss_start>:
11018: 00000000 andeq r0, r0, r0
我们看到你好和世界,但是foo和bar都被优化了。