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

时间:2013-04-25 14:42:47

标签: c assembly initialization variable-assignment c99

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

初始化方法

int x = 2;

作业方法

int x;
x = 2;

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

movl    $2, 12(%esp)

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

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

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

4 个答案:

答案 0 :(得分:7)

  

假设一个纯粹的非优化编译器,是否有任何区别   初始化变量并为其赋值的机器代码   宣言后?

不确定

  • 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增加了范围,更不用说类型融合和许多其他与变量相关的方面,以及初始化(你可以从前面的例子中看到,但不幸的是 不一样)。

  

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

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

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

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

在我的第三个例子中,成员foobar将被初始化为13和42,而剩余的,未初始化的成员将被初始化为0.使用赋值运算符的等价物将是相当的虽然我偶尔使用复合文字来获得类似的结果,但这很乏味。

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

答案 1 :(得分:5)

添加const限定符时,一个重要的区别就在于:

int const x = 2;

是有效的C

int const x;
x = 2;

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

static int x = f();

无效C

static int x;
x = f();

有效。

答案 2 :(得分:4)

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

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

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标准并未强制生成的代码相同或不相同。它只强制要求在这两种情况下程序的相同行为。而这种相同的行为并不一定意味着相同的机器代码。

答案 3 :(得分:0)

int x = 2;

计算机将创建变量x,并在几乎同时为其分配值


int x;
x = 2;

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

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

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

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

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