初始化变量并在声明后立即赋值给它是否有区别?
假设一个纯粹的非优化编译器,在初始化变量并在声明后为其赋值时,机器代码是否存在差异?
初始化方法 :
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.使用赋值运算符的等效项也相当繁琐。
在我的第三个例子中,成员foo
和bar
将被初始化为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中描述了这一点。