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?
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.
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.
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.
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.
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
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With