初始化变量并在声明后立即赋值给它是否有区别?

假设一个纯粹的非优化编译器,在初始化变量并在声明后为其赋值时,机器代码是否存在差异?

初始化方法

int x = 2; 

作业方式

 int x; x = 2; 

我使用GCC输出为这两种不同方法生成的程序集,并且两者都产生了一条机器指令:

 movl $2, 12(%esp) 

该指令只是将x变量保存的内存设置为值2 。 GCC可能正在优化这一点,因为它可以识别操作的最终结果; 但我认为这是解释这两个版本的唯一方法。 我的理由是两个版本都做同样的事情:将内存的一部分设置为特定值。

那么,如果生成的机器代码相同,那么为什么通常会在术语“ 初始化 ”和“ 赋值 ”之间进行区分?

术语“ 初始化 ”是否纯粹用于区分具有特定值的变量,这些变量具有在内存中留下任何垃圾值的那些(非初始化)变量?

行为必须相同,但生成的代码中的任何差异实际上都取决于编译器。

例如,编译器可以为初始化变量生成:

 somefunction: pushl %ebp movl %esp, %ebp pushl $2 ; allocate space for x and store 2 in it ... 

这对于未初始化但后来分配的变量:

 somefunction: pushl %ebp movl %esp, %ebp subl $4, %esp ; allocate space for x ... movl $2, -4(%ebp) ; assign 2 to x ... 

在这些情况下,C标准并未强制生成的代码相同或不相同。 它只强制要求在这两种情况下程序的相同行为。 并且相同的行为并不一定意味着相同的机器代码。

假设一个纯粹的非优化编译器,在初始化变量并在声明后为其赋值时,机器代码是否存在差异?

当然。

  • char fubar[] = "hello world"; 已validation。
  • char fubar[]; fubar = "hello world"; 不是。

更多?

  • int fubar[128] = { [60] = 42 }; 已validation。
  • int fubar[128]; fubar = { [60] = 42 }; 不是。

更多?

  • struct foo bar = { .foo = 13, .bar = 42 }; 已validation。
  • struct foo bar; bar = { .foo = 13, .bar = 42 }; 不是。

更多?

  • const int fubar = 0; 已validation。
  • const int fubar; fubar = 0; 不是。

我可以继续……因此,机器代码可能存在一个而它很可能不会存在另一个。 在那个问题上,您是否听说过C的实现不是编译器?

那么,如果生成的机器代码相同,那么为什么通常会在初始化和赋值之间进行区分?

C编程语言中的变量概念对于低级机器代码表示来说太高级了。 在机器代码中,寄存器没有范围。 C增加了范围,更不用说类型融合和许多其他与变量相关的方面,以及初始化(你可以从前面的例子中看到,但不幸的是不一样)。

术语“初始化”是否纯粹用于区分具有特定值的变量,这些变量具有在内存中留下任何垃圾值的那些(非初始化)变量?

虽然“初始化”的变量不包含任何“垃圾值”(或陷阱表示),但这并不是它唯一的影响。

在我的第一个例子中,初始化将提供否则不完整的数组的大小。 使用赋值运算符的等价物需要显式提供数组的长度并使用strcpy ,结果非常繁琐。

在我的第二个例子中,索引60处的int将初始化为40,而其余的未初始化项将初始化为0.使用赋值运算符的等效项也相当繁琐。

在我的第三个例子中,成员foobar将被初始化为13和42,而其余的,未初始化的成员将被初始化为0.使用赋值运算符的等价将是相当繁琐的,尽管我偶尔使用复合文字来实现类似的结果。

在我的第四个例子中,初始化设置变量将包含的整个生命周期的值。 此变量无法分配。

添加const限定符时,一个重要的区别就会发挥作用:

 int const x = 2; 

是有效的C.

 int const x; x = 2; 

不是。 另一个重要的区别是static变量:

 static int x = f(); 

是无效的C.

 static int x; x = f(); 

已validation。

 int x = 2; 

计算机将创建变量x并几乎在同一时刻为其赋值2。


 int x; x = 2; 

计算机将创建变量x。 然后它将它分配给它值2.似乎没有任何差别, ……

…让我们假设您的代码是这样的:

 int x; {some operators}; x = 2; 

计算机可能必须访问变量x才能为其赋值2.这意味着在运行程序计算机时会花费更多时间来访问x以向它提供某些值,这与它创建变量并在此时确定此变量不同。

无论如何,Deitel HM,Deitel PJ在C How to Program中描述了这一点。