In question Declaration difference? it was asked what the difference is between
int i;
for (i=0; i<100; i++) {
//some loop....
}
and:
for (int i=0; i<100; i++) {
//some loop....
}
The answers are clear; the 2nd is C99 and the scope of i
is limited to the loop. I don't have C99 so I can't test and hence ask it as a question: what would be the resolution in the following case:
int i = 32;
for (int i=i; i<100; i++) {
// some loop
}
Would the "new" i
be initialized with the "old" i
? Or would the old i
already be inaccessible becaus a new i
has already been declared?
The part of the program to which a name applies is called the scope of the declaration of that name. In most cases, the scope of the declaration of a name is determined entirely by the position where the name is declared within the program.
Declaration means that variable is only declared and memory is allocated, but no value is set. However, definition means the variables has been initialized. The same works for variables, arrays, collections, etc.
The definition of a declaration is a formal announcement. An example of a declaration is a government's statement about a new law. noun.
A declaration is a written statement submitted to a court in which the writer swears 'under penalty of perjury' that the contents are true. That is, the writer acknowledges that if he is lying, he may be prosecuted for perjury.
In this for loop statement
int i = 32;
for (int i = i; i < 100; i++) {
// some loop
}
variable i
declared in the for statement has indeterminate value. The problem is that as soon as a declarator is defined (in this case it consists from identifier i
) it hides an entity with the same name in the given scope. So in this declaration
int i = i;
variable i refers to itself in the right side of the =
.
Another similar example. Let's assume that you have a typedef.
typedef int Int;
You may write after its definition
Int Int;
In this case the name Int
of the object of type Int
hides the typedef definition and you may not already write
Int Another_Int;
because the compiler will issue an error.
According to the C Standard (6.2.1 Scopes of identifiers)
4 ...If the declarator or type specifier that declares the identifier appears inside a block or within the list of parameter declarations in a function definition, the identifier has block scope, which terminates at the end of the associated block.
A more clear is written in the C++ Standard (3.3.2 Point of declaration)
1 The point of declaration for a name is immediately after its complete declarator (Clause 8) and before its initializer (if any), except as noted below. [ Example:
int x = 12;
{ int x = x; }
Here the second x is initialized with its own (indeterminate) value. —end example ]
Take into account that in this code snippet
int i = 10;
{
int i[i];
}
inside the compound statement there is declared array int i[10];
that is outer variable i
is used as the array size because inner variable i
will be declared only when its declarator will be completed.
See C11 6.8.5.3: "If clause-1 is a declaration, the scope of any identifiers it declares is the remainder of the declaration and the entire loop, including the other two expressions".
The 2nd i
refers to the i
being defined, not the old one.
The whole thing is UB because you are using the value of i
(the i
being defined inside the loop) without a previous assignment (or initialization).
Edit with working (but different) example
You can still use the old value through the use of a pointer
int i = 42;
int *old_i = &i;
for (int i = *old_i; i < 50; i++) printf("%d ", i);
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