visc
visc

Reputation: 4959

Redeclaring variables in C

I've seen a similar question asked wrt c++, Does redeclaring variables in C++ cost anything?

But what about C? Will redeclaring a variable in C have any noticeable affect? Is this generally considered bad code organization?

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

EDIT:

Enhancing my ask.

If I have a loop in a function, would calling 'int y = 1 + 2 + 3;' over and over again be allowed? Will it cause problems? What does it do, declare y once?

Upvotes: 12

Views: 9993

Answers (2)

clearlight
clearlight

Reputation: 12615

Most C compilers optimize everything away that they can.

If you want to really find out, compile with the flag to look at the assembly code and see what it's doing. Like someone said, if it's a simple type (doesn't have a constructor), and particularly if you're using all literals, the compiler will probably just move a fixed value into a register each iteration, or not even bother, if nothing changes the variable between iterations

I just checked your example as shown below, and also changed it to modify a variable in the loop, and you can see how the assembly code generated changes.

In the first example, notice the loop at LBB0_1, it's just a movl instruction.

In the 2nd example, it's still pretty simple, but even though the results aren't used, it still saves things on the stack. I added some comments to explain what the loop is doing.

$ 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

Upvotes: 8

C language has the concept of variable scope. Ina a nutshell, each pair of { and } introduce new scope, and variables are bound to those scopes. You can declare variables with the same name, as long they are in different scopes.

That's why you that's valid:

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

And that's not valid:

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

Moreover declaration is a source code property, not runtime program property.

So, if you write:

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

You declare y once (because you have written it once), not infinite number of times.

Upvotes: 16

Related Questions