[LLVMdev] Uninitialized variable - question

john skaller skaller at users.sourceforge.net
Sat Nov 24 04:14:32 PST 2012


On 24/11/2012, at 10:21 PM, Nick Lewycky wrote:

> 
> Passing an uninitialized value as a function argument is undefined behaviour on the spot, regardless of what the callee does (even if it never references that argument).

Cite reference? No? Then you're guessing ;)

> 
> That aside, there is no way that 'i' has the same value, since it has no value.

This is definitely NOT correct in ISO C. It has an unspecified value,
and in C99 that may be a "trap value".

You state the rules generically but both C99 and C++ have special
rules for unsigned char, where use of an uninitialised value
is definitely not undefined.

> I should mention that the above is for C++, and I don't have a copy of any of the standards handy, but I expect the rules to be the same for C and C++ here.

It's VERY unwise to make such assumptions regarding conformance
issues since C and C++ have completely distinct conformance models.
They also treat uninitialised variables distinctly: the rules in C++ were
constructed independently of ISO C rules, particularly as in C++ there
are classes with constructors etc to consider, and generalised rules
covering such cases as well as scalars and aggregates are likely
to be distinct and have different consequences in their details.

One must be aware that Standards are imperfect documents and often
specifications in one place are incomplete or even wrong, unless
some other place is also considered. You need to be a Standards guru
to really know where to find all the relevant clauses.

Even then, as I pointed out in my prior post on this topic, the Standard
itself can be inconsistent, or fail to achieve a normative requirement
despite the intent of the committee. This is the case with integer
representation rules in C99: it looks reasonable but is actually
non-normative gibberish. However the rules do have an impact,
and they have a very unfortunate impact in over-constraining
integer representations.

In particular if, by specification of your vendor, you have a full
twos complement representation of "int" all possible values of an uninitialised
int variable are valid ints and the behaviour of all mathematical operations
and copying is then specified by the usual rules: it's undefined only if there
is overflow, division by zero, or whatever.

On a 64 bit machine like x86_64 the usual representations of
integers are full, and therefore copying and other operations
are well defined (allowing for undefined behaviour on division
by zero etc).

In particular:

	int x[2]; int y[2];
	x[0]=y[0];
	x[1]=y[1];

is a perfectly valid way to copy a possibly incompletely
filled array provided int has a full representation.

Historically, C was a real mess, with the most traditional
copying of arrays of chars aliasing other values being undefined.

C++ did NOT follow C here. It invented its own, more consistent, set
of rules. Not sure about C++11 though.

--
john skaller
skaller at users.sourceforge.net
http://felix-lang.org







More information about the llvm-dev mailing list