假设一个纯粹的非优化编译器,在初始化变量和声明后为其赋值之间的机器代码有什么区别吗?
初始化方法 :
int x = 2;
分配方法 :
int x;
x = 2;
我使用 GCC 来输出为这两种不同方法生成的程序集,并且都生成了一条机器指令:
movl $2, 12(%esp)
这条指令只是设置了
x
所持有的内存。变量为 2
的值. GCC 可能会对此进行优化,因为它可以识别操作的最终结果;但我认为这是解释两个版本的唯一方法。我的推理是两个版本都做同样的事情:将一部分内存设置为特定值。如果结果机器码相同,为什么通常会区分术语“ 初始化”和“ 赋值”?
术语“ 初始化”是否纯粹用于区分具有特定值的变量,而不是那些(未初始化的)变量,这些变量在内存中留下了任何垃圾值?
最佳答案
Assuming a purely non-optimizing compiler, is there any difference in machine code between initializing a variable and assigning it a value after declaration?
当然。
char fubar[] = "hello world";
已验证。 char fubar[]; fubar = "hello world";
不是。 更多的?
int fubar[128] = { [60] = 42 };
已验证。 int fubar[128]; fubar = { [60] = 42 };
不是。 更多的?
struct foo bar = { .foo = 13, .bar = 42 };
已验证。 struct foo bar; bar = { .foo = 13, .bar = 42 };
不是。 更多的?
const int fubar = 0;
已验证。 const int fubar; fubar = 0;
不是。 我可以继续下去......因此,机器代码可能存在于一个而它很可能不存在于另一个。关于这一点,您是否听说过不是编译器的 C 实现?
Why is it then that a distinction is often made between initialization and assignment if the resulting machine code is the same?
C 编程语言中变量的概念对于低级机器代码表示来说太高级了。在机器代码中,寄存器没有作用域。 C 增加了作用域,更不用说类型融合和许多其他与变量相关的方面,以及初始化(你可以从前面的例子中看到,但不幸的是不一样)。
Is the term "initialization" used purely to differentiate variables which have a specific value assigned over those (non-initialized) variables which have whatever garbage value was left in memory?
尽管“初始化”的变量不会包含任何“垃圾值”(或陷阱表示),但这并不是它的唯一影响。
在我的第一个示例中,初始化将提供否则不完整数组的大小。使用赋值运算符的等效项需要明确提供数组的长度并使用
strcpy
,结果证明这很乏味。在我的第二个例子中,
int
在索引 60 处将被初始化为 40 而其余的,否则未初始化的项目将被初始化为 0。使用赋值运算符的等效项也将相当乏味。在我的第三个例子中,成员
foo
和 bar
将被初始化为 13 和 42 而其余的,否则未初始化的成员将被初始化为 0。使用赋值运算符的等效项将非常乏味,尽管我偶尔会使用复合文字来实现类似的结果。在我的第四个示例中,初始化设置了变量在其整个生命周期中将包含的值。不能对这个变量赋值。
关于c - 初始化变量和声明后立即赋值有区别吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/16217839/