Velocity Reviews - Computer Hardware Reviews

Velocity Reviews > Newsgroups > Programming > C Programming > scanf()

Reply
Thread Tools

scanf()

 
 
Malcolm McLean
Guest
Posts: n/a
 
      08-12-2012
בתאריך יום ראשון, 12 באוגוסט 2012 01:30:46 UTC+1, מאת Keith Thompson:
> Malcolm McLean <(E-Mail Removed)> writes:
>
> > בתאריך יום שבת, 11 באוגוסט 2012 18:40:56 UTC+1, מאת Keith Thompson
> >> Malcolm McLean <(E-Mail Removed)> writes:

>
> >> There are worse possibilities than wrong results. If the input includes
> >> something like "1.0e999999999", the behavior is undefined.
> >>

>
> > But what is the program meant to do with such an input value? UB is
> > probably the best thing that can happen to it.

>
>
> That's absurd. Undefined behavior means that whatever the *worst*
> thing is, it can happen, whether that's crashing the program, or
> continuing to execute quietly with bad data, or reformatting your
> hard drive.
>

It mean the implementation decides what the result of the operation will be..
Of course the implementation is free to choose the worst option, like
reformatting the hard drive. But normally it's choice between terminating,
with an erro message, continuing with a corrupt value, or continuing with
a NaN or infinity. Not all platforms support option 3, which is the probable
best choice.
 
Reply With Quote
 
 
 
 
James Kuyper
Guest
Posts: n/a
 
      08-12-2012
On 08/12/2012 07:07 AM, Malcolm McLean wrote:
> בתאריך יום ראשון, 12 באוגוסט 2012 01:30:46 UTC+1, מאת Keith Thompson:
>> Malcolm McLean <(E-Mail Removed)> writes:
>>
>>> בתאריך יום שבת, 11 באוגוסט 2012 18:40:56 UTC+1, מאת Keith Thompson
>>>> Malcolm McLean <(E-Mail Removed)> writes:

>>
>>>> There are worse possibilities than wrong results. If the input includes
>>>> something like "1.0e999999999", the behavior is undefined.
>>>>

>>
>>> But what is the program meant to do with such an input value? UB is
>>> probably the best thing that can happen to it.

>>
>>
>> That's absurd. Undefined behavior means that whatever the *worst*
>> thing is, it can happen, whether that's crashing the program, or
>> continuing to execute quietly with bad data, or reformatting your
>> hard drive.
>>

> It mean the implementation decides what the result of the operation will be.


Keep in mind that the simplest way for the implementor to deal with that
issue is to ignore it: the implementor may simply write the code be as
fast as possible while meeting it's requirements, of which there are
none that apply when the input is 1.0e9999999999. What happens when that
code deals with such inputs need not be anything that the implementor
bothered thinking about, it's just whatever happens when the assumptions
that went into the design of the code are violated. Plausible
possibilities (not having given any detailed thought to how the code is
likely to be implemented), include silently corrupting the contents of
memory locations that should not be affected by a call to sscanf() with
valid inputs, or getting stuck in an infinite loop.

> Of course the implementation is free to choose the worst option, like
> reformatting the hard drive. But normally it's choice between terminating,
> with an erro message, continuing with a corrupt value, or continuing with
> a NaN or infinity. Not all platforms support option 3, which is the probable
> best choice.


I would favor terminating with an error message over either of the other
two options you mention. I've heard people claim in similar discussion
in the past that there exist programs where it's more important that a
program keep running, regardless of how badly it is malfunctioning, than
that it halt. They say that in certain safety critical contexts, if the
program halts, someone will die. However, it seems to me that in
precisely those same circumstances, if the program malfunctions badly
enough, someone will die anyway, even if it never halts.
--
James Kuyper
 
Reply With Quote
 
 
 
 
Malcolm McLean
Guest
Posts: n/a
 
      08-12-2012
בתאריך יום ראשון, 12 באוגוסט 2012 13:03:23 UTC+1, מאת James Kuyper:
> On 08/12/2012 07:07 AM, Malcolm McLean wrote:
>
> I would favor terminating with an error message over either of the other
> two options you mention. I've heard people claim in similar discussion
> in the past that there exist programs where it's more important that a
> program keep running, regardless of how badly it is malfunctioning, than
> that it halt. They say that in certain safety critical contexts, if the
> program halts, someone will die. However, it seems to me that in
> precisely those same circumstances, if the program malfunctions badly
> enough, someone will die anyway, even if it never halts.
>

A safety critical system in ahospital life support system should crash out on
error. That;s no different to the electricty failing, and the hospital should
have procedures to deal with that eventuality.
However a safety critcal system on an aircraft may need to keep going. There
might be no plausible fallback mechanism. So you've just got to process the
wrogn results and hope they are not sufficiently wrong to bring the plane
down. The same's true of video games. Stopping the game is usually the worst
thing you can do. Making a baddie appear in an unusual place might be accepted
as part of the game.
 
Reply With Quote
 
Keith Thompson
Guest
Posts: n/a
 
      08-12-2012
Malcolm McLean <(E-Mail Removed)> writes:
> בתאריך יום ראשון, 12 באוגוסט 2012 01:30:46 UTC+1, מאת Keith Thompson:
>> Malcolm McLean <(E-Mail Removed)> writes:
>> > בתאריך יום שבת, 11 באוגוסט 2012 18:40:56 UTC+1, מאת Keith Thompson
>> >> Malcolm McLean <(E-Mail Removed)> writes:
>> >> There are worse possibilities than wrong results. If the input includes
>> >> something like "1.0e999999999", the behavior is undefined.

>>
>> > But what is the program meant to do with such an input value? UB is
>> > probably the best thing that can happen to it.

>>
>> That's absurd. Undefined behavior means that whatever the *worst*
>> thing is, it can happen, whether that's crashing the program, or
>> continuing to execute quietly with bad data, or reformatting your
>> hard drive.
>>

> It mean the implementation decides what the result of the operation will be.


No, the implementation needn't decide *anything*.

[...]

--
Keith Thompson (The_Other_Keith) http://www.velocityreviews.com/forums/(E-Mail Removed) <http://www.ghoti.net/~kst>
Will write code for food.
"We must do something. This is something. Therefore, we must do this."
-- Antony Jay and Jonathan Lynn, "Yes Minister"
 
Reply With Quote
 
Malcolm McLean
Guest
Posts: n/a
 
      08-12-2012
בתאריך יום ראשון, 12 באוגוסט 2012 21:39:54 UTC+1, מאת Keith Thompson:
> Malcolm McLean <(E-Mail Removed)> writes:
>
>
> > It mean the implementation decides what the result of the operation will
> > be.

>
> No, the implementation needn't decide *anything*.
>

Someone writes scanf(). It's possible, though unlikely for someone given
such a job, that he's never considered that exponents might be out of
range. If he has considered that possibility, he must decide what to do
with such input. He might write an error message, quietly return a NaN, or
return a corrupted result which retain backwards comptability with a previous
version of the function. There's a case for all of these. But he's got to
opt for something.


 
Reply With Quote
 
Keith Thompson
Guest
Posts: n/a
 
      08-12-2012
Malcolm McLean <(E-Mail Removed)> writes:
> בתאריך יום ראשון, 12 באוגוסט 2012 21:39:54 UTC+1, מאת Keith Thompson:
>> Malcolm McLean <(E-Mail Removed)> writes:
>> > It mean the implementation decides what the result of the operation will
>> > be.

>>
>> No, the implementation needn't decide *anything*.
>>

> Someone writes scanf(). It's possible, though unlikely for someone given
> such a job, that he's never considered that exponents might be out of
> range. If he has considered that possibility, he must decide what to do
> with such input. He might write an error message, quietly return a NaN, or
> return a corrupted result which retain backwards comptability with a previous
> version of the function. There's a case for all of these. But he's got to
> opt for something.


As you acknowledge, the developer needn't even consider the
possibility that exponents might be out of range -- or that there
might be a sufficiently long sequence of digits to produce an
out-of-range value without using an exponent.

Someone implementing scanf() might simply perform a series of
arithmetic operations that will work correctly with in-range
values, and *assume* that it will fail in some clean fashion with
out-of-range values. He might fail to consider what could happen
with all the compilers under which the code might run (run-time
libraries aren't necessarily tied to specific compilers), or how
optimization might affect the results. Adding code to allow for
overflow might significantly slow down cases that *don't* overflow;
he might deliberately choose performance over clean behavior for
undefined cases. Or he might simply take the standard's statement
that the behavior is undefined as a license not to worry about it.

Treating undefined behavior as if it were merely unspecified or
implementation-defined is foolish.

--
Keith Thompson (The_Other_Keith) (E-Mail Removed) <http://www.ghoti.net/~kst>
Will write code for food.
"We must do something. This is something. Therefore, we must do this."
-- Antony Jay and Jonathan Lynn, "Yes Minister"
 
Reply With Quote
 
Seungbeom Kim
Guest
Posts: n/a
 
      08-13-2012
On 2012-08-11 13:34, Malcolm McLean wrote:
> בתאריך יום שבת, 11 באוגוסט 2012 18:40:56 UTC+1, מאת Keith Thompson:
>> Malcolm McLean <(E-Mail Removed)> writes:
>>
>> There are worse possibilities than wrong results. If the input includes
>> something like "1.0e999999999", the behavior is undefined.
>>

> But what is the program meant to do with such an input value? UB is probably the
> best thing that can happen to it.


The best that can happen is for the library function (sscanf here)
to report an error to its caller in a well-defined way and let the
program stay in a well-defined state.

Look what the strto* functions do, for example: they return HUGE_VAL*
or *LONG_{MIN,MAX} and set errno to ERANGE. The caller can examine
these conditions and decide what to do in case of an error.

The problem with this kind of UB caused by bad user input, contrary to
another kind of UB caused by bad programmer input, is that there's no
defense for the program. Calling strlen with a null pointer is UB, but
it's a bug the programmer can fix/prevent/get around. It's not the case
with calling sscanf with a bad string or calling gets with a long string,
and that's why these functions are inherently unsafe.

--
Seungbeom Kim
 
Reply With Quote
 
Heinrich Wolf
Guest
Posts: n/a
 
      08-13-2012

"Malcolm McLean" <(E-Mail Removed)> schrieb im Newsbeitrag
news:(E-Mail Removed)...
בתאריך יום ראשון, 12 באוגוסט 2012 21:39:54 UTC+1, מאת Keith Thompson:
> Malcolm McLean <(E-Mail Removed)> writes:
>
>
> > It mean the implementation decides what the result of the operation will
> > be.

>
> No, the implementation needn't decide *anything*.
>

Someone writes scanf(). It's possible, though unlikely for someone given
such a job, that he's never considered that exponents might be out of
range. If he has considered that possibility, he must decide what to do
with such input. He might write an error message, quietly return a NaN, or
return a corrupted result which retain backwards comptability with a
previous
version of the function. There's a case for all of these. But he's got to
opt for something.

--------------------------------------------------
I tried to read "3.1415e999999" with scanf and with strtod on 3 different
compilers. All of them say they have processed 13 characters and scanf
always returns the same as strtod. My very old Turbo C 2.0 however does a
bad job and returns in 1.798e+308. My Borland C++Builder 5 and my gcc on
Fedora 14 return +INF. Still strtod is better than scanf, because I have the
chance to go back the stream as far as I have loaded it into my buffer and
interpret it differently.

 
Reply With Quote
 
Phil Carmody
Guest
Posts: n/a
 
      09-04-2012
"Heinrich Wolf" <(E-Mail Removed)> writes:
> "Malcolm McLean" <(E-Mail Removed)> schrieb im
> Newsbeitrag
> news:(E-Mail Removed)...
> , 12 2012 21:39:54 UTC+1, Keith Thompson:
> > Malcolm McLean <(E-Mail Removed)> writes:
> >
> >
> > > It mean the implementation decides what the result of the operation will
> > > be.

> >
> > No, the implementation needn't decide *anything*.
> >

> Someone writes scanf(). It's possible, though unlikely for someone given
> such a job, that he's never considered that exponents might be out of
> range. If he has considered that possibility, he must decide what to do


^^

> with such input. He might write an error message, quietly return a NaN, or
> return a corrupted result which retain backwards comptability with a
> previous
> version of the function. There's a case for all of these. But he's got to
> opt for something.


Unless he hasn't. See the "if" above, and presume falsity of the predicate.

Phil
--
> I'd argue that there is much evidence for the existence of a God.

Pics or it didn't happen.
-- Tom (/. uid 822)
 
Reply With Quote
 
Tim Rentsch
Guest
Posts: n/a
 
      09-07-2012
Keith Thompson <(E-Mail Removed)> writes:

> Malcolm McLean <(E-Mail Removed)> writes:
>> Keith Thompson:
>>> Malcolm McLean <(E-Mail Removed)> writes:
>>>
>>> There are worse possibilities than wrong results. If the input includes
>>> something like "1.0e999999999", the behavior is undefined.
>>>

>> But what is the program meant to do with such an input value? UB is probably the
>> best thing that can happen to it.

>
> That's absurd. Undefined behavior means that whatever the *worst*
> thing is, it can happen, whether that's crashing the program, or
> continuing to execute quietly with bad data, or reformatting your
> hard drive. [snip elaboration]


It doesn't. I admit that's often a useful way of thinking about
undefined behavior, but that isn't what the term actually means
(and I'm sure I'm not saying anything you don't already know).
When the Standard says "undefined behavior", that means it
imposes no requirements: as far as the Standard is concerned,
anything goes and everything is acceptable.

But, the Standard isn't the only force operating here. There is
also the compiler that was used; the operating system within
which the program is being run; possibly multiple levels of
those if the program is being run in a virtual environment; the
physical hardware that the program is being run on; and, going
all the way to the bottom, the physical universe we all live in.
Any one of those levels could serve to limit or define the set of
potential behaviors available.

So, at the same time that I agree that thinking of undefined
behavior as meaning "anything can happen", I would argue that it's
also important to keep in mind the actual implications of undefined
behavior, which can be a positive in some circumstances. I might
not have chosen his phrasing, but the basic point Malcolm is making
is essentially correct - "undefined behavior" is never really
"undefined", but rather defined by elements and forces outside the
sphere of what the Standard chooses to address. Not knowing what
defines the behavior or what the definition is doesn't mean they
don't exist.
 
Reply With Quote
 
 
 
Reply

Thread Tools

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off
Trackbacks are On
Pingbacks are On
Refbacks are Off




Advertisments