Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Redeclaring variables in C

Tags:

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?

like image 410
visc Avatar asked Feb 02 '17 03:02

visc


People also ask

Can I Redeclare a variable in C?

Redeclaration: In C, you cannot redeclare a variable within the same scope. However, you can overwrite a global variable's declaration locally. This is generally a bad practice, unless you have a global variable that behaves(should take some other value) differently in certain functions.

What does Redeclaring a variable mean?

Redeclaring a variable is useful in situations where it cannot be known if the variable has already been defined. By redeclaring a variable conditionally, as Google Analytics tracking code does, it allows for a variable to safely originate from more than one place.

Can you redeclare a variable?

You can't redeclare a variable which has already been declared in the same block. However, variables can be redeclared in short multi-variable declarations where at least one new variable is introduced.


2 Answers

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.

like image 114
el.pescado - нет войне Avatar answered Nov 13 '22 16:11

el.pescado - нет войне


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
like image 7
clearlight Avatar answered Nov 13 '22 16:11

clearlight