Reputation: 7193
In C is it valid to use a variable in the same statement in which it is declared?
In both gcc 4.9 and clang 3.5 the following program compiles and runs without error:
#include "stdio.h"
int main() {
int x = x;
printf("%d\n", x);
}
In gcc it outputs 0
and in clang 32767
(which is largest positive 2-byte integer value).
Why does this not cause a compilation error? Is this valid in any particular C specification? Is its behavior explicitly undefined?
Upvotes: 0
Views: 66
Reputation: 263197
int x = x;
This is "valid" in the sense that it doesn't violate a constraint or syntax rule, so no compile-time diagnostic is required. The name x
is visible within the initializer, and refers to the object being declared. The scope is defined in N1570 6.2.1 paragraph 7:
Any other identifier [other than a struct, union, or enum tag, or an enum constant] has scope that begins just after the completion of its declarator.
The declarator in this case is int x
.
This allows for things like:
int x = 10, y = x + 1;
But the declaration has undefined behavior, because the initializer refers to an object that hasn't been initialized.
The explicit statement that the behavior is undefined is in N1570 6.3.2.1 paragraph 2, which describes the "conversion" of an lvalue (an expression that designates an object) to the value stored in that object.
Except when [list of cases that don't apply here], an lvalue that does not have array type is converted to the value stored in the designated object (and is no longer an lvalue); this is called lvalue conversion.
[...]
If the lvalue designates an object of automatic storage duration that could have been declared with theregister
storage class (never had its address taken), and that object is uninitialized (not declared with an initializer and no assignment to it has been performed prior to use), the behavior is undefined.
The object in question is x
, referenced in the initializer. At that point, no value has been assigned to x
, so the expression has undefined behavior.
In practice, you'll probably get a compile-time warning if you enable a high enough warning level. The actual behavior might be the same as if you had omitted the initializer:
int x;
but don't count on it.
Upvotes: 4
Reputation: 726479
According to the language specification
6.7.8.10 If an object that has automatic storage duration is not initialized explicitly, its value is indeterminate.
Further, it says
6.7.8.11 The initializer for a scalar shall be a single expression, optionally enclosed in braces. The initial value of the object is that of the expression (after conversion).
Hence, the value of the initializer expression (x
to the right of =
) is indeterminate, so we are dealing with undefined behavior, because initializer reads from variable x
that has indeterminate value.
Various compilers provide warning settings to catch such conditions.
Upvotes: 2
Reputation: 1295
Clang does warn about this:
$ clang -c -Wall ub_or_not_ub.c
ub_or_not_ub.c:4:11: warning: variable 'x' is uninitialized when used within its own initialization [-Wuninitialized]
int x = x;
~ ^
So I guess it's undefined behavior.
Upvotes: 1
Reputation: 206567
int x = x;
is cause for undefined behavior. Don't count on any predictable behavior.
Upvotes: 1