假设一个纯粹的非优化编译器,初始化变量和声明后为其赋值之间的机器代码有什么区别吗?
当然。
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 实现?
如果生成的机器代码相同,为什么通常在初始化和赋值之间进行区分?
C 编程语言中变量的概念对于低级机器代码表示来说太高级了。在机器代码中,寄存器没有作用域。C 增加了作用域,更不用说类型融合和许多其他与变量相关的方面,以及初始化(您可以从前面的示例中看到完全一致,但不幸的是不一样)。
术语“初始化”是否纯粹用于区分具有特定值的变量,而不是那些(非初始化)变量,这些变量具有留在内存中的任何垃圾值?
尽管“初始化”的变量不会包含任何“垃圾值”(或陷阱表示),但这并不是它的唯一影响。
在我的第一个示例中,初始化将提供不完整数组的大小。使用赋值运算符的等效项需要显式提供数组的长度和 using strcpy
,这变得非常乏味。
在我的第二个示例中,int
索引处的 60 将被初始化为 40,而其余未初始化的项将被初始化为 0。使用赋值运算符的等效项也将相当乏味。
在我的第三个示例中,成员foo
和bar
将被初始化为 13 和 42,而其余未初始化的成员将被初始化为 0。使用赋值运算符的等效项将非常乏味,尽管我偶尔使用复合文字来实现类似的结果。
在我的第四个示例中,初始化设置了变量在其整个生命周期中将包含的值。不能对该变量进行赋值。