Sujet : Re: int a = a
De : tr.17687 (at) *nospam* z991.linuxsc.com (Tim Rentsch)
Groupes : comp.lang.cDate : 22. Mar 2025, 21:59:05
Autres entêtes
Organisation : A noiseless patient Spider
Message-ID : <86a59clr3a.fsf@linuxsc.com>
References : 1 2 3 4 5 6 7 8 9 10 11 12 13 14
User-Agent : Gnus/5.11 (Gnus v5.11) Emacs/22.4 (gnu/linux)
Keith Thompson <Keith.S.Thompson+
u@gmail.com> writes:
David Brown <david.brown@hesbynett.no> writes:
>
[...]I believe it would be much simpler and clearer if attempting
to read an uninitialised and unassigned local variable were
undefined behaviour in every case.
>
I probably agree (I haven't given it all that much thought), but
the committee made a specific decision between C90 and C99 to say
that reading an uninitialized automatic object is *not* undefined
behavior. I'm don't know why they did that (though, all else
being equal, reducing the number of instances of undefined
behavior is a good thing), but reversing that decision for this
one issue is not something they decided to do.
Your description of what was done is wrong. It is still the case in
C99 that trying to access an uninitialized object is undefined
behavior, at least potentially, except for accesses using a type
that either is a character type or has no trap representations (and
all types other than unsigned char may have trap representations,
depending on the implementation). A statement like
int a = a;
may still be given a warning as potential undefined behavior, even
in C99.
Alternatively, it could have said that the value is unspecified
in every case. Then on the IA-64, the compiler would have to
ensure that registers do not have their NaT bit set even if they
are not initialised - this would not be a difficult task.
Enabling use of the NaT bit for detection of bugs could then be a
compiler option if implementations wanted to provide that
feature.
>
The whole point of the NaT bit is to detect accesses to
uninitialized values. Requiring the compiler to arbitrarily clear
that bit doesn't strike me as a good idea.
>
I dislike the way that wording was added to the standard
specifically to cater to one specific CPU (which happens to have
been discontinued later). I would have been happier with a more
general solution. I that making accessing the value of an
uninitialized automatic object UB would have been much cleaner,
and it would have allowed for sensible use of NaT by IA-64
compilers.
I think you may be missing a key point. In both C99 and C11,
accessing an uninitialized object using a character type is defined
(albeit unspecified) behavior. But in C11, because of the changes
in 6.3.2.1, even character types are subject to undefined behavior
when uninitialized objects are accessed (provided of course that
they don't fall under an exception because their address was taken).
The C11 rule does more than allowing undefined behavior just for
non-character types; it extends the possibility of undefined
behavior to character types as well.
But without knowing *why* the committee removed that UB between
C90 and C99, I'm hesitant to say it was a mistake.
The mistake is thinking that UB for uninitialized access was
removed in C99. It wasn't. Narrowed, yes; removed, no. And
later C11 simply widened it back a bit, recovering some of the
territory that had been taken away in C99. The Itanium may
have been what prompted the change, but the change that was made
is one well worth making.