Qry : Behaviour of fgets -- ?

K

kuyper

Richard said:
kuyper said: ....

I'm just trying to imagine what kind of bozo would alias a data buffer
with a stream pointer.

Um, yeah, okay, maybe it's not so hard to imagine. Sturgeon and all
that. I retract the "misplaced".

I agree that Sturgeon's law is the most reason why such code might be
written; and I believe that alone is sufficient reason to apply the
qualifiers.

However, Sturgeon's law is not the only way this issue could come up..
I can easily imagine legitimate, though non--portable, reasons why
someone might do something like that. If they understood the
implementation-specific details about how a FILE structure is layed
out and used by the implementation, I could imagine wanting to save
that information to a strean (which might be the same stream) for
later examination. By that same token, of course, if they understood
enough to want to do that, they should also understand enough to know
why it's unsafe to do it that way; the best that can be done is to
save a copy of the FILE structure, rather than the one in actual use.
Therefore, Sturgeon's Law remains the most likely cause of such code.
 
R

Richard Heathfield

Harald van D?k said:
Either the DS9K obeys the laws of physics, or you don't have a DS9K.
Choose one.

There ain't no such animal as "the laws of physics". They are myths,
make-believe, mere models made by mankind to satisfy his need for
labelling things. Reality does not have "obeys all laws of physics as
discovered (so far) by Sol III's scientists" written on the box lid.
 
H

Harald van =?UTF-8?B?RMSzaw==?=

Richard said:
Harald van D?k said:

There ain't no such animal as "the laws of physics". They are myths,
make-believe, mere models made by mankind to satisfy his need for
labelling things. Reality does not have "obeys all laws of physics as
discovered (so far) by Sol III's scientists" written on the box lid.

I didn't say "the laws of physics as discovered (so far)", I copied Bart van
Ingen Schenau's unqualified "the laws of physics", which do exist even if
we don't fully know them yet. And regardless of whether you want to make
that distinction, I doubt you honestly believe anyone's neighbour turned
into a piano. Some more context:

"The standard does indeed not require that UB causes my next door
neighbour to turn into a piano, but that appears to be exactly the
behaviour of my DeathStation 9000.
Are you claiming that this behaviour is not correct?" - Bart v Ingen Schenau
 
D

Douglas A. Gwyn

CBFalconer said:
Not allowed by the C standard. Just because it will work on _some_
systems doesn't make it viable. Undefined behaviour includes doing
what you think is right.

It will in fact work on any actual platform. If that isn't
good enough for the fellow, then what would be?
 
H

Harald van =?UTF-8?B?RMSzaw==?=

Douglas said:
It will in fact work on any actual platform. If that isn't
good enough for the fellow, then what would be?

That's a bold claim. With fgets, it would work on my implementation. With
strlen for example, it would not, because <string.h>'s macro definition of
strcpy refers to it by name. Are you sure no implementation does anything
similar with fgets?
 
W

Wojtek Lerch

CBFalconer said:
They certainly do convey useful information. They advise the
compiler of the fgets software that using *stream will not affect
*s, and vice-versa. This enables more extensive optimization, and
thus faster code.

No. In a function *definition*, they do what you said. When an implementor
writes their C library in C, adding restrict qualifiers to the function
definitions might indeed enable some optimizations.

In a function *declaration*, these qualifiers are meaningless to the
compiler. Since adding or removing qualifiers to the type of a parameter
doesn't affect the compatibility of function types, the presence or absence
of the qualifiers in a function *declaration* does not affect the
assumptions that the compiler is allowed to make about the definition.
 
M

Mark McIntyre

It will in fact work on any actual platform.

I'd be interested to see proof that it works on "any actual platform"
- presumably including platforms no longer manufactured. Do we get to
include platforms still being built, and yet to be invented?
If that isn't good enough for the fellow, then what would be?

Personally I prefer not to rely on purely empirical evidence. After
all if we did that, we'd still be sticking straws into pingpong balls
and calling it a model of a solid, quantum computers would be
impossible and Schroedinger's cat would be well and truly dead.

--
Mark McIntyre

"Debugging is twice as hard as writing the code in the first place.
Therefore, if you write the code as cleverly as possible, you are,
by definition, not smart enough to debug it."
--Brian Kernighan
 
D

Douglas A. Gwyn

Harald said:
That's a bold claim. With fgets, it would work on my implementation. With
strlen for example, it would not, because <string.h>'s macro definition of
strcpy refers to it by name. Are you sure no implementation does anything
similar with fgets?

I think you missed the fact that <stdio.h> is *not* #included in
the context in which the "fgets" layering macro is defined and used.
<mystdio.h> is #included, as a *replacement* for i#ncluding <stdio.h>,
but it does not itself #include <stdio.h>, and no other header used
by the application should #include <stdio.h> either. (The other
standard headers won't, and they also won't define fgets.) The
identifier "fgets" is therefore reserved only if used to refer to
external linkage, which it doesn't (being a macro).

This kind of "layering" of standard functions is fairly common,
especially for adding debugging checks like the original requestor
wanted.
 
D

Douglas A. Gwyn

Mark said:
I'd be interested to see proof that it works on "any actual platform"
- presumably including platforms no longer manufactured. Do we get to
include platforms still being built, and yet to be invented?

Well, they have to be standard conforming.
 
D

Douglas A. Gwyn

Wojtek said:
In a function *declaration*, these qualifiers are meaningless to the
compiler. Since adding or removing qualifiers to the type of a parameter
doesn't affect the compatibility of function types, the presence or absence
of the qualifiers in a function *declaration* does not affect the
assumptions that the compiler is allowed to make about the definition.

However, it certainly affects the assumptions that the programmer
should make.
 
C

CBFalconer

Richard said:
You have obviously never read much about quantum physics. And yes,
when the Standard does not define what a piece of code does but
leaves it up to the compiler, and when that compiler does not care
to make sure that that code does something specific but leaves it
up to the accidents of microprocessor behaviour (which both could
very well do, and with good reason), then quantum physics really
can toss the coin about how that code behaves, on that day, on
that computer.

My compilers exercise a random generator on each ++ (or --) call.
If two of them on the same object occur between sequence points it
uses the last random value to select a function to call. This can
be any function in any process, live or not (and requires system
specific code). This produces an amazing density of nasal demons.
Someday it may well launch WWIII. It is standard conforming.
 
C

CBFalconer

Rainer said:
Would you please stop bombarding me with this trash? I am not
trying to argue for the standpoint you would like to impose onto
me and if you haven't understood that by now, the chances that
you ever will are slim.

All he is doing is helpfully trying to point out some of the
possibilities of invoking undefined behaviour. He isn't imposing
anything on you. I suggest waking up and recognizing reality.
 
W

Wojtek Lerch

Douglas A. Gwyn said:
However, it certainly affects the assumptions that the programmer
should make.

That would be clearer if the normative text actually said that the Synopsis
of each library function is meant to specify the exact type the function
must be defined with, rather than just be a declaration suitable for copying
into a program or a standard header.

Or was it meant to be something in between? I don't see why the standard
would want to forbid implementors to define putchar() as

int putchar( int const ch ) {
return putc( ch, stdout );
}
 
R

Richard Heathfield

Harald van D?k said:
I didn't say "the laws of physics as discovered (so far)", I copied
Bart van Ingen Schenau's unqualified "the laws of physics", which do
exist even if we don't fully know them yet.

No, they don't. Nature has no laws. Nature has behaviour. We observe
that behaviour, and formulate "laws" which explain it. Nature, however,
is under no obligation to observe those "laws" (and indeed frequently
breaks them). For example, the vast majority of gases don't observe the
gas laws.
And regardless of whether
you want to make that distinction, I doubt you honestly believe
anyone's neighbour turned into a piano.

I don't know for sure that they didn't. :)
Some more context:

"The standard does indeed not require that UB causes my next door
neighbour to turn into a piano, but that appears to be exactly the
behaviour of my DeathStation 9000.
Are you claiming that this behaviour is not correct?" - Bart v Ingen
Schenau

It's not incorrect, as far as the Standard is concerned.
 
C

Charlie Gordon

Douglas A. Gwyn said:
However, it certainly affects the assumptions that the programmer
should make.

Not really: programmers refer to the function prototype for argument
ordering and syntax, they would be well advised to refer to the
documentation for actual constraints on the arguments. The only information
provided by the restrict keyword in the prototype for fgets is ludicrous
(thou shalt not pass an alias to the stream pointer as the destination
buffer). Much more important would be some indication that NULL for either
argument invokes undefined behaviour, or some constraint that the
destination buffer should be at least as large as the size argument says.
Alas, adding a _NonNull qualifier or some syntax for buffer size constraints
and enforcing these constraints on the callers would be too far reaching,
much worse even than const poisonning.
 
R

Richard Bos

Douglas A. Gwyn said:
It did allow us to not put in all those extra chunks of wording
saying that the pointed-to objects shall not overlap.

On strcpy(), yes, but on fgets()? A char * and a FILE * can only overlap
if a. you're invoking UB anyway, by scribbling wildly into the FILE
object through a mispointed char *, or b. you're invoking UB anyway, by
scribbling neatly into the FILE object using undefined and unportable
assumptions about the layout of the FILE.

Richard
 
C

Chris Dollin

Rainer said:
Put straight into context: There are many instance of beahviour not
defined by the C standard, and since you are claiming to discuss the
C-standard, you spend an enourmous amount of typing to publish wild
speculations about things not defined by the C-standard?

Nobody's "publishing wild speculation". In particular, no-one is
/seriously/ claiming that implementations /will/ do specific
unlikely things. They're saying that the implementation is not
constrained by the standard /in any way/ at various points,
and using humerous exaggeration to do so.

Odd that you didn't answer my evil twin's point (b).
Does that sound a little contradictory?
No.

What's YOUR problem with accepting that what isn't there
simply isn't there?

I don't have a problem in that regard.
And could you perhaps discuss this with a professional?

Being obnoxious does not improve your argument.
 
C

Charlie Gordon

Richard Bos said:
On strcpy(), yes, but on fgets()? A char * and a FILE * can only overlap
if a. you're invoking UB anyway, by scribbling wildly into the FILE
object through a mispointed char *, or b. you're invoking UB anyway, by
scribbling neatly into the FILE object using undefined and unportable
assumptions about the layout of the FILE.

FILE may even be an incomplete type, there is no guarantee that a FILE *
properly cast to a char * can be safely dereferenced at all.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
474,097
Messages
2,570,622
Members
47,235
Latest member
LuisaHamle

Latest Threads

Top