Reputation: 4959
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
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
Reputation: 19216
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