在C中重新声明变量

时间:2017-02-02 03:10:07

标签: c

我已经看到了类似的问题,问了c ++,Does redeclaring variables in C++ cost anything?

但是C怎么样?在C中重新声明变量会有任何明显的影响吗?这通常被认为是不好的代码组织吗?

for(;;) {
   int y = 1 + 2 + 3; // some kind of repeated redeclaration? 
}

编辑:

加强我的要求。

如果我在函数中有一个循环,则会调用' int y = 1 + 2 + 3;'一遍又一遍被允许?它会引起问题吗?它做了什么,声明y一次?

2 个答案:

答案 0 :(得分:6)

大多数C编译器都会尽可能地优化所有内容。

如果你想真正找到带有标志的编译来查看汇编代码并看看它在做什么。就像有人说如果它是一个简单类型(没有构造函数),特别是如果你使用所有文字,编译器可能只是在每次迭代时将固定值移动到寄存器中,或者如果在迭代之间没有任何改变变量的话,甚至都不会打扰

我刚刚检查了你的例子,如下所示,并且还修改了它以修改循环中的变量,你可以看到生成的汇编代码是如何变化的。

在第一个例子中,注意LBB0_1的循环,它只是一个movl指令。

在第二个例子中,它仍然非常简单,但即使没有使用结果,它仍然可以将内容保存在堆栈中。我添加了一些注释来解释循环正在做什么。

$ cc -fno-asynchronous-unwind-tables -S dummy.c

int main(void) { 
    for(;;) {
        int y = 1 + 2 + 3;
    }
}

$ cat dummy.s

    .section    __TEXT,__text,regular,pure_instructions
    .macosx_version_min 10, 12
    .globl  _main
    .align  4, 0x90
_main:                                  ## @main
## BB#0:
    pushq   %rbp
    movq    %rsp, %rbp
    movl    $0, -4(%rbp)
LBB0_1:                                 ## =>This Inner Loop Header: Depth=1
    movl    $6, -8(%rbp)
    jmp LBB0_1

.subsections_via_symbols

$ cc -fno-asynchronous-unwind-tables -S dummy.c

int main(void) { 
    int i = 0;
    for(;;) {
        int y = i + 2 + 3;
        i++;
    }
}

$ cat dummy.s

        .section        __TEXT,__text,regular,pure_instructions
        .macosx_version_min 10, 12
        .globl  _main
        .align  4, 0x90
_main:                                  ## @main
## BB#0:
        pushq   %rbp
        movq    %rsp, %rbp
        movl    $0, -4(%rbp)            
        movl    $0, -8(%rbp)            ## i = 0
LBB0_1:                                 
        movl    -8(%rbp), %eax          ## y = i
        addl    $2, %eax                ## y += 2
        addl    $3, %eax                ## y += 3
        movl    %eax, -12(%rbp)         ## -12(rbp) = y
        movl    -8(%rbp), %eax          ## eax = i
        addl    $1, %eax                ## i++
        movl    %eax, -8(%rbp)          ## -8(rbp) = i
        jmp     LBB0_1

.subsections_via_symbols

答案 1 :(得分:6)

C语言具有变量范围的概念。简而言之,每对{}引入新范围,变量绑定到这些范围。您可以声明具有相同名称的变量,只要它们位于不同的范围内即可。

这就是你有效的原因:

if(...) {
    int y; # y is valid here
}          # end of scope, y is not valid here
if(...) {  # new scope
    int y; # That's another y
}

这是无效的:

if(...) {
    int y;
    int y; # error, redeclaration
}

此外,声明是源代码属性,而不是运行时程序属性。

所以,如果你写:

for(;;) {
   int y = 1 + 2 + 3;
}

您宣布y 一次(因为您已经写过一次),而不是无限次。