3

假设一个纯粹的非优化编译器,初始化变量和声明后为其赋值之间的机器代码有什么区别吗?

初始化方法

int x = 2;

赋值方法

int x;
x = 2;

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

movl    $2, 12(%esp)

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

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

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

4

4 回答 4

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

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

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

在我的第一个示例中,初始化将提供不完整数组的大小。使用赋值运算符的等效项需要显式提供数组的长度和 using strcpy,这变得非常乏味。

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

在我的第三个示例中,成员foobar将被初始化为 13 和 42,而其余未初始化的成员将被初始化为 0。使用赋值运算符的等效项将非常乏味,尽管我偶尔使用复合文字来实现类似的结果。

在我的第四个示例中,初始化设置了变量在其整个生命周期中将包含的值。不能对该变量进行赋值。

于 2013-04-25T15:22:52.940 回答
5

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

int const x = 2;

有效 C

int const x;
x = 2;

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

static int x = f();

无效 C

static int x;
x = f();

已验证。

于 2013-04-25T15:22:56.730 回答
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 标准不要求生成的代码相同或不相同。它只要求在这两种情况下程序的行为相同。并且相同的行为并不一定意味着相同的机器代码。

于 2013-04-25T15:18:18.573 回答
0
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中对此进行了描述。

于 2013-04-25T15:33:17.897 回答