Velocity Reviews

Velocity Reviews (http://www.velocityreviews.com/forums/index.php)
-   C Programming (http://www.velocityreviews.com/forums/f42-c-programming.html)
-   -   Undefined behavior in standards (http://www.velocityreviews.com/forums/t724853-undefined-behavior-in-standards.html)

xlar54 06-05-2010 07:57 AM

Undefined behavior in standards
 
Ive lurked a bit, always reading and learning (thank you all).
Regarding undefined behaviors.. in some cases I can understand, but in
others I dont fully get it. Why would the standards committee allow
an undefined behavior? Why not define it? Granted when pointers are
involved, you're often at the mercy of the system itself, but for
something like reading a variable before it is initialized... seems to
me that this could be easily standardized as a compile-time error.
Your thoughts?

Ike Naar 06-05-2010 08:48 AM

Re: Undefined behavior in standards
 
In article <5bb7443e-4dac-4144-93b4-926e6c7f186b@j4g2000yqh.googlegroups.com>,
xlar54 <scott.hutter@gmail.com> wrote:
>Ive lurked a bit, always reading and learning (thank you all).
>Regarding undefined behaviors.. in some cases I can understand, but in
>others I dont fully get it. Why would the standards committee allow
>an undefined behavior? Why not define it? Granted when pointers are
>involved, you're often at the mercy of the system itself, but for
>something like reading a variable before it is initialized... seems to
>me that this could be easily standardized as a compile-time error.


It is not always possible to detect this situation at compile-time.

extern init(double*);

int main(void)
{
double d;
init(&d);
return d; /* reading d, but is d initialized? */
}

Seebs 06-05-2010 10:38 AM

Re: Undefined behavior in standards
 
On 2010-06-05, xlar54 <scott.hutter@gmail.com> wrote:
> Ive lurked a bit, always reading and learning (thank you all).
> Regarding undefined behaviors.. in some cases I can understand, but in
> others I dont fully get it. Why would the standards committee allow
> an undefined behavior? Why not define it?


Usually because there are machines on which the most natural behavior
is some kind of trap or interrupt, and avoiding this would be EXTREMELY
expensive.

> Granted when pointers are
> involved, you're often at the mercy of the system itself, but for
> something like reading a variable before it is initialized... seems to
> me that this could be easily standardized as a compile-time error.


No, it couldn't. Halting problem.

int i, n = 0;
scanf("%d", &n);
if (n != 1) {
i = 0;
}
i; /* do we read i before it is initialized? */

> Your thoughts?


In general, undefined behavior occurs when you do something fundamentally
incoherent, and the cost of expecting a compiler to check for it or deal
with it is very large, and the cost of telling you not to do that is small.

-s
--
Copyright 2010, all wrongs reversed. Peter Seebach / usenet-nospam@seebs.net
http://www.seebs.net/log/ <-- lawsuits, religion, and funny pictures
http://en.wikipedia.org/wiki/Fair_Game_(Scientology) <-- get educated!

Ben Bacarisse 06-05-2010 01:33 PM

Re: Undefined behavior in standards
 
Seebs <usenet-nospam@seebs.net> writes:

> On 2010-06-05, xlar54 <scott.hutter@gmail.com> wrote:

<snip asking about why some things are undefined in C>

>> Granted when pointers are
>> involved, you're often at the mercy of the system itself, but for
>> something like reading a variable before it is initialized... seems to
>> me that this could be easily standardized as a compile-time error.

>
> No, it couldn't. Halting problem.


Yes, though your example might confuse someone expecting to see how the
halting problem relates to this question.

> int i, n = 0;
> scanf("%d", &n);
> if (n != 1) {
> i = 0;
> }
> i; /* do we read i before it is initialized? */


This example is ironic since it introduces another source of UB: the
scanf call can produce UB when otherwise well-formed input can't be
represented as an int. That does not matter to the point you are
making, but something entirely well-defined like a simple getchar call
would have avoided the irony.

The irony is significant in that the OP is wondering why so many things
are UB in C and this is one of the most infuriating examples with, in my
opinion, the weakest justification. It means you can't use any of the
scanf family for numeric input if you take UB and corner cases
seriously. You can cripple the input with a length limit (%9ld for
example) but that is hardly satisfactory.

[Aside: my preference would be for a correctly formatted but
unrepresentable input to be classed as a matching failure.]

>> Your thoughts?

>
> In general, undefined behavior occurs when you do something fundamentally
> incoherent, and the cost of expecting a compiler to check for it or deal
> with it is very large, and the cost of telling you not to do that is
> small.


Ack "in general" but in the specific case you introduced I don't think
the cost would be very large and the benefit would be significant but
maybe I am missing the reason for this specific UB. (I'd alter atoi to
be well-defined as well, though there are relatively simple solutions
for that function.)

--
Ben.

Eric Sosman 06-05-2010 02:09 PM

Re: Undefined behavior in standards
 
On 6/5/2010 3:57 AM, xlar54 wrote:
> Ive lurked a bit, always reading and learning (thank you all).
> Regarding undefined behaviors.. in some cases I can understand, but in
> others I dont fully get it. Why would the standards committee allow
> an undefined behavior? Why not define it? Granted when pointers are
> involved, you're often at the mercy of the system itself, but for
> something like reading a variable before it is initialized... seems to
> me that this could be easily standardized as a compile-time error.


There've been several responses on the specific issue of
using uninitialized variables, but on the wider question of "Why
is some behavior left undefined?" here are a few quotes from
Section 3 of the Rationale:

"The terms unspecified behavior, undefined behavior, and
implementation-defined behavior are used to categorize the
result of writing programs whose properties the Standard
does not, or cannot, completely describe. The goal of adopting
this categorization is to allow a certain variety among
implementations which permits quality of implementation to be
an active force in the marketplace as well as to allow certain
popular extensions, without removing the cachet of conformance
to the Standard."

"Undefined behavior gives the implementor license not to catch
certain program errors that are difficult to diagnose. It also
identifies areas of possible conforming language extension:
the implementor may augment the language by providing a
definition of the officially undefined behavior."

I'd read this as saying there are multiple reasons to leave some
behaviors undefined. Here are my paraphrases of a few:

- Some errors are difficult to detect (most of the responses about
uninitialized variables have mentioned this aspect), so the
Standard places the burden for their detection on the programmer
rather than on the compiler. Looking at it another way, getting
the program to run correctly is a shared responsibility, and the
compiler shouldn't have to shoulder all of it unaided.

- Leaving some behaviors undefined may lead to higher-quality
implementations of defined behaviors. For example, strcpy()
may be able to use high-speed in-line instruction sequences
that would be unsuitable if it had to worry about predictable
behavior when source and destination overlap. By leaving the
behavior on overlap undefined, the Standard permits strcpy()
implementations that are faster than they might be otherwise.

- Leaving some behaviors undefined allows opportunity for language
and library extensions. If *all* behaviors were nailed down,
extensions would be impossible. (It is interesting, although
discouraging, to note that some of the more virulent anti-Standard
posters to this forum are the same people who make extensive use
of the freedoms the Standard grants them.)

Finally, there's a further argument for undefined behavior, one
that neither the Standard nor the Rationale appears to state out loud:
It's *really* *hard* to define everything precisely! If the writers
had withheld the Standard until every single corner had been smoothed,
primed, and varnished, we would still be waiting for the first version.

--
Eric Sosman
esosman@ieee-dot-org.invalid

xlar54 06-05-2010 03:22 PM

Re: Undefined behavior in standards
 
Thanks all. Really interesting answers, and I appreciate the
explanations.

Lew Pitcher 06-05-2010 06:05 PM

Re: Undefined behavior in standards
 
On June 5, 2010 14:02, in comp.lang.c, a@b.c.invalid wrote:

>
> "Ike Naar" <> ha scritto nel messaggio
> news:hud30e$pt5$1@news.eternal-september.org...
>> In article
>> <5bb7443e-4dac-4144-93b4-926e6c7f186b@j4g2000yqh.googlegroups.com>,
>> xlar54 <> wrote:
>>>Ive lurked a bit, always reading and learning (thank you all).
>>>Regarding undefined behaviors.. in some cases I can understand, but in
>>>others I dont fully get it. Why would the standards committee allow
>>>an undefined behavior? Why not define it? Granted when pointers are
>>>involved, you're often at the mercy of the system itself, but for
>>>something like reading a variable before it is initialized... seems to
>>>me that this could be easily standardized as a compile-time error.

>>
>> It is not always possible to detect this situation at compile-time.
>>
>> extern init(double*);
>>
>> int main(void)
>> {
>> double d;
>> init(&d);
>> return d; /* reading d, but is d initialized? */
>> }

>
> i not find the problem
> if someone want to eliminate this UB it is easy
> "double d;" could mean "double d=0.0;"
> in each compiler => no UB in this case


Except that the current standards do not support such behaviour. If, in a
*new* standard, it was specified that explicitly uninitialized automatic
variables take on a zero (or floatingpoint zero, or NULL, or zero-like (for
structures and unions) ) value, then your plan would work. But, right now,
the standards say (for instance, in C90, Section 6.7.8, paragraph 10)
"If an object that has automatic storage duration is not initialized
explicitly, its value is indeterminate."

Your
double d;
declares d to be an object of type double, with automatic storage duration,
not initialized to any set value. And, thus 6.7.8 #10 applies, and the
value of d is indeterminate /as far as the standard is concerned/, no
matter /what/ individual compilers do.



--
Lew Pitcher
Master Codewright & JOAT-in-training | Registered Linux User #112576
Me: http://pitcher.digitalfreehold.ca/ | Just Linux: http://justlinux.ca/
---------- Slackware - Because I know what I'm doing. ------



Peter Nilsson 06-07-2010 04:54 AM

Re: Undefined behavior in standards
 
Richard Heathfield <r...@see.sig.invalid> wrote:
> ... to avoid imposing a hidden runtime penalty, C doesn't
> zero out auto scope objects by default, and it places the
> burden on you the programmer...


Which is in contrast to your own policy of initialising
all objects explicitly. Given that modern compilers can
detect uninitialised objects in most cases, it seems
reasonable to believe they can detect unnecessary
initialisation with equal success.

I can understand how the initial standards didn't want to
impose burdens on implementations on small systems, but
people these days almost exclusively use cross compilers
on large systems when targetting embedded platforms.

--
Peter

Nick Keighley 06-07-2010 07:06 AM

Re: Undefined behavior in standards
 
On 5 June, 19:05, Lew Pitcher <lpitc...@teksavvy.com> wrote:
> On June 5, 2010 14:02, in comp.lang.c, a...@b.c.invalid wrote:
> > "Ike Naar" <> ha scritto nel messaggio
> >news:hud30e$pt5$1@news.eternal-september.org...
> >> In article
> >> <5bb7443e-4dac-4144-93b4-926e6c7f1...@j4g2000yqh.googlegroups.com>,
> >> xlar54 *<> wrote:


> >>>Ive lurked a bit, always reading and learning (thank you all).
> >>>Regarding undefined behaviors.. in some cases I can understand, but in
> >>>others I dont fully get it. *Why would the standards committee allow
> >>>an undefined behavior? *Why not define it? *Granted when pointers are
> >>>involved, you're often at the mercy of the system itself, but for
> >>>something like reading a variable before it is initialized... seems to
> >>>me that this could be easily standardized as a compile-time error.


it couldn't be a compile time error, in general it's too hard to
detect. Halting Problem too hard.

> >> It is not always possible to detect this situation at compile-time.

>
> >> *extern init(double*);

>
> >> *int main(void)
> >> *{
> >> * *double d;
> >> * *init(&d);
> >> * *return d; /* reading d, but is d initialized? */
> >> *}

>
> > i not find the problem
> > if someone want to eliminate this UB it is easy
> > "double *d;" could mean "double *d=0.0;"
> > in each compiler => no UB in this case


that wouldn't help you detect the error at compile time which is what
you suggested. I'm guessing they didn't do this becuase it has a
slight cost.

> Except that the current standards do not support such behaviour.


since he's asking why the standard is the way it is, this is a bit of
a daft answer

> If, in a
> *new* standard, it was specified that explicitly uninitialized automatic
> variables take on a zero (or floatingpoint zero, or NULL, or zero-like (for
> structures and unions) ) value, then your plan would work. But, right now,
> the standards say (for instance, in C90, Section 6.7.8, paragraph 10)
> * "If an object that has automatic storage duration is not initialized
> * *explicitly, its value is indeterminate."
>
> Your
> * * double d;
> declares d to be an object of type double, with automatic storage duration,
> not initialized to any set value. And, thus 6.7.8 #10 applies, and the
> value of d is indeterminate /as far as the standard is concerned/, no
> matter /what/ individual compilers do.



--

Avoid hyperbole at all costs,
it's the most destructive argument on the planet.
- Mark McIntyre in comp.lang.c


Tim Rentsch 06-20-2010 01:24 AM

Re: Undefined behavior in standards
 
Eric Sosman <esosman@ieee-dot-org.invalid> writes:

> On 6/5/2010 3:57 AM, xlar54 wrote:
>[why is there undefined behavior]
>
> There've been several responses on the specific issue of
> using uninitialized variables, but on the wider question of "Why
> is some behavior left undefined?" here are a few quotes from
> Section 3 of the Rationale:
>
> [various good reasons given, including some by ES]
>
> Finally, there's a further argument for undefined behavior, one
> that neither the Standard nor the Rationale appears to state out loud:
> It's *really* *hard* to define everything precisely! [snip]


I don't buy this argument. It might be hard to identify
where the line is, but it's the Standard's job to draw that
line sharply and precisely. Once the line is drawn, it's
very easy to say "everything on <side X> of the line causes
the program to stop termination immediately; all actions
before have been done, all actions following have not been
started." It's easy to give a definition. What makes the
question hard is /what/ definition to give -- that's why there
is undefined behavior, to avoid having to be pinned down to a
single answer.

(I should add that the rest of Eric's comments were spot on.)


All times are GMT. The time now is 08:05 AM.

Powered by vBulletin®. Copyright ©2000 - 2014, vBulletin Solutions, Inc.
SEO by vBSEO ©2010, Crawlability, Inc.