469,366 Members | 2,205 Online
Bytes | Developer Community
New Post

Home Posts Topics Members FAQ

Post your question to a community of 469,366 developers. It's quick & easy.

Qry : Behaviour of fgets -- ?


Machine 1 :
bash-3.00$ uname -a
SunOS <hostname5.10 Generic_118822-30 sun4u sparc SUNW,Sun-Fire-280R

bash-3.00$ gcc -v
Reading specs from /usr/local/lib/gcc-lib/sparc-sun-solaris2.8/2.95.3/
specs
gcc version 2.95.3 20010315 (release)
Machine 2:
bash-2.05b$ uname -a
Linux <hostname2.4.21-4.EL #1 Fri Oct 3 18:13:58 EDT 2003 i686 i686
i386 GNU/Linux

bash-2.05b$ gcc -v
Reading specs from /usr/lib/gcc-lib/i386-redhat-linux/3.2.3/specs
Configured with: ../configure --prefix=/usr --mandir=/usr/share/man --
infodir=/usr/share/info --enable-shared --enable-threads=posix --
disable-checking --with-system-zlib --enable-__cxa_atexit --host=i386-
redhat-linux
Thread model: posix
gcc version 3.2.3 20030502 (Red Hat Linux 3.2.3-20)

bash-2.05b$ cat fgets_fail_test.c
#include<stdio.h>
#include <string.h>
#include<stdlib.h>

/* Demo fgets failed by Raxit Sheth & Gaurav Gupta */

int main()
{
char spcontent[100],sendrepfile[100];
FILE *spfp=NULL;
memset(sendrepfile,0,100);
strcpy(sendrepfile,"/tmp/filenotexists");
if ((spfp = fopen(sendrepfile, "r")) == (FILE *)NULL)
{
printf("error in opening file %s",sendrepfile);fflush(stdout);
}
memset(spcontent, 0, sizeof(spcontent));

while (fgets(spcontent,40, spfp)!=NULL)
{
printf("The value of spcontent is
[%s]",spcontent);fflush(stdout);;
}
return 0;
}
<simillar core dump occurs on both the system>
bash-2.05b$ gcc -Wall fgets_fail_test.c -o test
bash-2.05b$ ./test
error in opening file /tmp/filenotexistsSegmentation fault (core
dumped)
bash-2.05b$ gdb ./test ./core.27887
GNU gdb Red Hat Linux (5.3.90-0.20030710.40rh)
Copyright 2003 Free Software Foundation, Inc.
GDB is free software, covered by the GNU General Public License, and
you are
welcome to change it and/or distribute copies of it under certain
conditions.
Type "show copying" to see the conditions.
There is absolutely no warranty for GDB. Type "show warranty" for
details.
This GDB was configured as "i386-redhat-linux-gnu"...(no debugging
symbols found)...Using host libthread_db library "/lib/tls/
libthread_db.so.1".

Core was generated by `./test'.
Program terminated with signal 11, Segmentation fault.
Reading symbols from /lib/tls/libc.so.6...(no debugging symbols
found)...done.
Loaded symbols for /lib/tls/libc.so.6
Reading symbols from /lib/ld-linux.so.2...(no debugging symbols
found)...done.
Loaded symbols for /lib/ld-linux.so.2
#0 0xb7506444 in fgets () from /lib/tls/libc.so.6
(gdb) where
#0 0xb7506444 in fgets () from /lib/tls/libc.so.6
#1 0x0804854b in main ()
(gdb) frame 0
#0 0xb7506444 in fgets () from /lib/tls/libc.so.6
(gdb) print errno
Cannot access memory at address 0xb74a7008
char *fgets(char *s, int n, FILE *stream)
Qry : What is the Behaviour if stream is NULL. ?

As per our understanding fgets should return NULL < and internally
gets should put check on stream, if it is not NULL then only should do
additional access of stream.

please ignore if it is known and would be great if you can point out
in the implementation detail.
--Gaurav Gupta & Raxit Sheth
http://www.barcamp.org/BarCampMumbaiOct2007 <----BarCampMumbaiOct2007

Sep 6 '07
285 7860
Bart van Ingen Schenau wrote:
>
.... snip ...
>
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?
That depends. Is he in tune? :-)

--
Chuck F (cbfalconer at maineline dot net)
Available for consulting/temporary embedded and systems.
<http://cbfalconer.home.att.net>

--
Posted via a free Usenet account from http://www.teranews.com

Sep 8 '07 #51
Keith Thompson <ks***@mib.orgwrites:

[snip]
>As a programmer, of course, I can't depend on any such checks, since
not all implementations perform them, and that's going to remain the
case for a long time. It's still entirely *my* responsibility to
avoid passing invalid arguments to fgets. If the implementation helps
me out by catching certain errors, that's great (unless it imposes too
much of a burden on *correct* calls), but I can't count on it. If I
don't trust myself to get this right, I can always write a wrapper
that checks the arguments before calling fgets.
Indeed. One may as well expect strcpy to return EFAULT when provided
arguments in which the destination pointer refers to an
unmapped portion of the virtual address space (or a portion mapped
read-only, or a portion to which the process has no access).

This was actually proposed to the X/Open group at one point and was
quickly rejected due to performance and correctness constraints.

scott
Sep 8 '07 #52
In article <11**********************@22g2000hsm.googlegroups. com>,
Sheth Raxit <ra************@gmail.comwrote:
don't you think instead of "not saying" or "saying undefined
behaviour" any additional checks are put itself in std ?
This would be redundant and inefficient. Instead of the programmer
checking the return value of fopen() once, all the I/O functions would
have to check the value of the stream every time.

Consider an inner loop calling fgetc(). This is a very simple
operation, probably only about 5-10 instructions most of the time
(because of buffering -- if there's data in the buffer it just has to
copy one byte and increment the buffer pointer). Adding the NULL check
would slow it down by 20-30%, I suspect.

--
Barry Margolin, ba****@alum.mit.edu
Arlington, MA
*** PLEASE post questions in newsgroups, not directly to me ***
*** PLEASE don't copy me on replies, I'll read them in the group ***
Sep 8 '07 #53
CBFalconer wrote:
jacob navia wrote:
>Casper H.S. Dik wrote:
... snip ...
>>Dumping core is a good thing; you have a bug, it was caught.
Now go and fix your code.

Casper
Why error analysis is necessary?

Error analysis means trying to have a defined an in all cases
identical reaction to program errors.

This means that for each function we write, we try to
return a specified error report value if things go wrong.

In the case of fgets this implies:
o Testing for NULL.
o Testing for a bad value of n (<= 0)
o Testing for a NULL value in the receiving buffer.

NULLs are allowed in the receiving buffer, and don't matter since
they will either be beyond the line end or overwritten. It helps
to get the objective right before trying to code for it.

One is also allowed to snip obvious signatures, even though the
originator neglected to include a proper sig. marker. There are no
prizes for extreme laziness or rudeness.
Canonically,

char buff[80];
size_t size = sizeof buff;
while (fgets(buff, size, stream)) {
....
}
fgets will return NULL at EOF or error. The EOF condition is the normal
exit from the while loop.

fgets returns the value buff if it read something. We use strchr to
check for '\n' in buff indicating a complete line.

If the line is incomplete, either the line is longer than buff or it is
the last line of the stream and doesn't terminate with '\n'. To find out
which we use strchr searching for '\0' which will always succeed. If the
NUL is at buff[size-1] we assume the line is longer than buff. If the
NUL occurs earlier we assume an unterminated last line.

For well formed input we have enough information to do 'the right thing'
with the data.

Perversity.
It is apparently legal, if unusual, to have '\0' characters in text
files. fgets makes no exception for these NUL characters. If a too-long
line has a NUL in it, my logic above gets it wrong by assuming an
unterminated last line. Even if the line is terminated with '\n', if it
also contains NUL then using strcpy to move it from buff will fail
miserably.

All because NUL is legal in text streams. Or is it?

--
Joe Wright
"Everything should be made as simple as possible, but not simpler."
--- Albert Einstein ---
Sep 8 '07 #54
Joe Wright wrote:
CBFalconer wrote:
>jacob navia wrote:
>>Casper H.S. Dik wrote:
... snip ...
>>>Dumping core is a good thing; you have a bug, it was caught.
Now go and fix your code.

Casper
Why error analysis is necessary?

Error analysis means trying to have a defined an in all cases
identical reaction to program errors.

This means that for each function we write, we try to
return a specified error report value if things go wrong.

In the case of fgets this implies:
o Testing for NULL.
o Testing for a bad value of n (<= 0)
o Testing for a NULL value in the receiving buffer.

NULLs are allowed in the receiving buffer, and don't matter since
they will either be beyond the line end or overwritten. It helps
to get the objective right before trying to code for it.

One is also allowed to snip obvious signatures, even though the
originator neglected to include a proper sig. marker. There are no
prizes for extreme laziness or rudeness.

Canonically,

char buff[80];
size_t size = sizeof buff;
while (fgets(buff, size, stream)) {
....
}
fgets will return NULL at EOF or error. The EOF condition is the
normal exit from the while loop.

fgets returns the value buff if it read something. We use strchr
to check for '\n' in buff indicating a complete line.

If the line is incomplete, either the line is longer than buff or
it is the last line of the stream and doesn't terminate with '\n'.
To find out which we use strchr searching for '\0' which will
always succeed. If the NUL is at buff[size-1] we assume the line
is longer than buff. If the NUL occurs earlier we assume an
unterminated last line.

For well formed input we have enough information to do 'the right
thing' with the data.

Perversity.
It is apparently legal, if unusual, to have '\0' characters in
text files. fgets makes no exception for these NUL characters. If
a too-long line has a NUL in it, my logic above gets it wrong by
assuming an unterminated last line. Even if the line is terminated
with '\n', if it also contains NUL then using strcpy to move it
from buff will fail miserably.
The constant response to all line lengths thing is easily handled
by ggets. If the NULLs in the line are affecting you, you could
easily modify ggets.zip to ignore them (which may not be the right
cure). See:

<http://cbfalconer.home.att.net/download/>

Barring i/o or malloc failures ggets always returns complete lines,
with the final '\n' removed. The penalty is exercising the malloc
subsystem.

It has been pointed out that ggets is vulnerable to deliberate
interference, since it continues to expand the buffer as long as
input is arriving (without a '\n'). I think this is negligible,
partly because it is hard to provide a continuous input. It
actually doesn't tie up indefinitely, since once the malloc system
refuses to expand it exits with error.

--
Chuck F (cbfalconer at maineline dot net)
Available for consulting/temporary embedded and systems.
<http://cbfalconer.home.att.net>
--
Posted via a free Usenet account from http://www.teranews.com

Sep 8 '07 #55
On Sat, 08 Sep 2007 10:03:32 -0400, Joe Wright wrote:
[...]To find out
which we use strchr searching for '\0' which will always succeed. If the
NUL is at buff[size-1] we assume the line is longer than buff.
Doesn't strlen(buf) != size - 1 do the same without looking that
weird?
--
Army1987 (Replace "NOSPAM" with "email")
If you're sending e-mail from a Windows machine, turn off Microsoft's
stupid “Smart Quotes” feature. This is so you'll avoid sprinkling garbage
characters through your mail. -- Eric S. Raymond and Rick Moen

Sep 8 '07 #56
Joe Wright <jo********@comcast.netwrites:
[...]
Canonically,

char buff[80];
size_t size = sizeof buff;
while (fgets(buff, size, stream)) {
....
}
[...]
If the line is incomplete, either the line is longer than buff or it
is the last line of the stream and doesn't terminate with '\n'. To
find out which we use strchr searching for '\0' which will always
succeed. If the NUL is at buff[size-1] we assume the line is longer
than buff. If the NUL occurs earlier we assume an unterminated last
line.
[...]

strchr? Just use strlen.

--
Keith Thompson (The_Other_Keith) ks***@mib.org <http://www.ghoti.net/~kst>
San Diego Supercomputer Center <* <http://users.sdsc.edu/~kst>
"We must do something. This is something. Therefore, we must do this."
-- Antony Jay and Jonathan Lynn, "Yes Minister"
Sep 8 '07 #57
CBFalconer <cb********@yahoo.comwrites:
[...]
It has been pointed out that ggets is vulnerable to deliberate
interference, since it continues to expand the buffer as long as
input is arriving (without a '\n'). I think this is negligible,
partly because it is hard to provide a continuous input.
actually doesn't tie up indefinitely, since once the malloc system
refuses to expand it exits with error.
No, it's not hard to provide a continuous input. In fact, it's
trivial, as I've demonstrated:

./my_program < /dev/zero
It
actually doesn't tie up indefinitely, since once the malloc system
refuses to expand it exits with error.
Which is not necessarily benign.

--
Keith Thompson (The_Other_Keith) ks***@mib.org <http://www.ghoti.net/~kst>
San Diego Supercomputer Center <* <http://users.sdsc.edu/~kst>
"We must do something. This is something. Therefore, we must do this."
-- Antony Jay and Jonathan Lynn, "Yes Minister"
Sep 8 '07 #58
Keith Thompson wrote:
CBFalconer <cb********@yahoo.comwrites:
[...]
>It has been pointed out that ggets is vulnerable to deliberate
interference, since it continues to expand the buffer as long as
input is arriving (without a '\n'). I think this is negligible,
partly because it is hard to provide a continuous input.
actually doesn't tie up indefinitely, since once the malloc system
refuses to expand it exits with error.

No, it's not hard to provide a continuous input. In fact, it's
trivial, as I've demonstrated:

./my_program < /dev/zero
>actually doesn't tie up indefinitely, since once the malloc system
refuses to expand it exits with error.

Which is not necessarily benign.
However, this assumes the evildoer has access to the machine, and
can access devices, and can redirect input to access such a device,
etc. etc. I don't think this generally applies.

Actually the suggestion I made earlier in this thread, of making
ggets ignore a zero byte, would foul this attack entirely. Since
ggets is intended to input text this is probably a harmless change
and doesn't affect the .h linkage file in the least.

--
Chuck F (cbfalconer at maineline dot net)
Available for consulting/temporary embedded and systems.
<http://cbfalconer.home.att.net>
--
Posted via a free Usenet account from http://www.teranews.com

Sep 8 '07 #59
In article <46***************@yahoo.com>,
CBFalconer <cb********@maineline.netwrote:
>No, it's not hard to provide a continuous input. In fact, it's
trivial, as I've demonstrated:

./my_program < /dev/zero
>However, this assumes the evildoer has access to the machine, and
can access devices, and can redirect input to access such a device,
etc. etc. I don't think this generally applies.
What kind of input would someone have that *wouldn't* allow them that
kind of access? In the old days they might be sitting at a dumb
terminal, but now almost all remote access is from another computer
that can generate arbitrary data.

On the other hand, most remote access these days is probably through
HTTP, and for that the size of the data is usually known before the
remote application gets hold of it. It can be very big of course.

-- Richard
--
"Consideration shall be given to the need for as many as 32 characters
in some alphabets" - X3.4, 1963.
Sep 8 '07 #60
CBFalconer <cb********@yahoo.comwrites:
Keith Thompson wrote:
>CBFalconer <cb********@yahoo.comwrites:
[...]
>>It has been pointed out that ggets is vulnerable to deliberate
interference, since it continues to expand the buffer as long as
input is arriving (without a '\n'). I think this is negligible,
partly because it is hard to provide a continuous input.
actually doesn't tie up indefinitely, since once the malloc system
refuses to expand it exits with error.

No, it's not hard to provide a continuous input. In fact, it's
trivial, as I've demonstrated:

./my_program < /dev/zero
>>actually doesn't tie up indefinitely, since once the malloc system
refuses to expand it exits with error.

Which is not necessarily benign.

However, this assumes the evildoer has access to the machine, and
can access devices, and can redirect input to access such a device,
etc. etc. I don't think this generally applies.
Sure it does. On a typical system, if the "evildoer" is able to run
the program at all, he can redirect its input from anywhere he likes.
Actually the suggestion I made earlier in this thread, of making
ggets ignore a zero byte, would foul this attack entirely. Since
ggets is intended to input text this is probably a harmless change
and doesn't affect the .h linkage file in the least.
That only affects the specific case of reading from /dev/zero (or
something equivalent). You could read from any arbitrary binary file;
depending on the kind of file, it might happen to contain an
arbitrarily long sequence of bytes containing neither '\n' nor '\0'.

And that's just something that can happen entirely by accident. I've
done that kind of thing myself trying to run "less" on a binary file
(it hangs until I kill it from another window). Given a malicious
attacker ("Here, take a look at this file!"), generating arbitrarily
long lines is trivial.

My examples are Unix-specific, but similar problems can occur on other
systems.

--
Keith Thompson (The_Other_Keith) ks***@mib.org <http://www.ghoti.net/~kst>
San Diego Supercomputer Center <* <http://users.sdsc.edu/~kst>
"We must do something. This is something. Therefore, we must do this."
-- Antony Jay and Jonathan Lynn, "Yes Minister"
Sep 9 '07 #61
Keith Thompson wrote:
CBFalconer <cb********@yahoo.comwrites:
>Keith Thompson wrote:
>>CBFalconer <cb********@yahoo.comwrites:
[...]
It has been pointed out that ggets is vulnerable to deliberate
interference, since it continues to expand the buffer as long as
input is arriving (without a '\n'). I think this is negligible,
partly because it is hard to provide a continuous input.

No, it's not hard to provide a continuous input. In fact, it's
trivial, as I've demonstrated:

./my_program < /dev/zero

actually doesn't tie up indefinitely, since once the malloc system
refuses to expand it exits with error.

Which is not necessarily benign.

However, this assumes the evildoer has access to the machine, and
can access devices, and can redirect input to access such a device,
etc. etc. I don't think this generally applies.

Sure it does. On a typical system, if the "evildoer" is able to run
the program at all, he can redirect its input from anywhere he likes.
>Actually the suggestion I made earlier in this thread, of making
ggets ignore a zero byte, would foul this attack entirely. Since
ggets is intended to input text this is probably a harmless change
and doesn't affect the .h linkage file in the least.

That only affects the specific case of reading from /dev/zero (or
something equivalent). You could read from any arbitrary binary file;
depending on the kind of file, it might happen to contain an
arbitrarily long sequence of bytes containing neither '\n' nor '\0'.

And that's just something that can happen entirely by accident. I've
done that kind of thing myself trying to run "less" on a binary file
(it hangs until I kill it from another window). Given a malicious
attacker ("Here, take a look at this file!"), generating arbitrarily
long lines is trivial.

My examples are Unix-specific, but similar problems can occur on other
systems.
Generating such a file is a non-trivial exercise, as I discovered
when I created some long lines for ggets testing in the first
place. They have to ban the use of a byte holding numeric 10
everywhere, since this will always create a line ending. I
maintain the routine is no more dangerous than an ordinary program
that reads a file into memory, using malloc to create the storage.
Either can lead to harassment, admittedly, but they cannot form a
security hole. Almost anything that does input can be harassed in
the same general way.

--
Chuck F (cbfalconer at maineline dot net)
Available for consulting/temporary embedded and systems.
<http://cbfalconer.home.att.net>

--
Posted via a free Usenet account from http://www.teranews.com

Sep 9 '07 #62
On Sat, 08 Sep 2007 21:48:19 +0200, Army1987 wrote:
On Sat, 08 Sep 2007 10:03:32 -0400, Joe Wright wrote:
>[...]To find out
which we use strchr searching for '\0' which will always succeed. If the
NUL is at buff[size-1] we assume the line is longer than buff.

Doesn't strlen(buf) != size - 1 do the same without looking that
weird?
Or better, set buff[size - 1] to a nonzero value, call fgets, and
check whether buff[size - 1] is zero. This takes O(1) time.
--
Army1987 (Replace "NOSPAM" with "email")
If you're sending e-mail from a Windows machine, turn off Microsoft's
stupid “Smart Quotes” feature. This is so you'll avoid sprinkling garbage
characters through your mail. -- Eric S. Raymond and Rick Moen

Sep 9 '07 #63
On Fri, 07 Sep 2007 17:38:50 +0000, Douglas A. Gwyn wrote:
/* mystdio.h */
#include <stdio.h> // just for FILE
extern char *myfgets(char *, int, FILE *);
#undef fgets // in case <stdio.hdefined it
#define fgets myfgets
You're not allowed to do that.
/* ... and others ... */

/* myfgets.c */
#include <stddef.h> // for size_t
stdio.h defines size_t, too.
#include <stdio.h>
[snip]
--
Army1987 (Replace "NOSPAM" with "email")
If you're sending e-mail from a Windows machine, turn off Microsoft's
stupid “Smart Quotes” feature. This is so you'll avoid sprinkling garbage
characters through your mail. -- Eric S. Raymond and Rick Moen

Sep 9 '07 #64
On Fri, 07 Sep 2007 17:52:16 +0000, Douglas A. Gwyn wrote:
Sheth Raxit wrote:
>Is Assert-ing for NULL is better than Undefined Behaviour ?
Good for Buggy program. Good for platform ?

A failed assert() is generally not a good way of handling an
error, since the application and its supporting libraries are
not given a chance to clean up (flush changes to databases,
etc.). Interrupting the application's procedure in the
middle of some chain of actions could have horrible
consequences. Consider if the error occurs between the
time when the medical equipment starts a pump to inject some
drug into a patient and the time when it stops the pump.
A segmentation violation in this situation would be not any better
than a failed assertion. I consider them both to be bugs. One
should only use assert() to verify conditions which one believes
to be mathematically and logically impossible to ever be false, so
that a failed assertion makes it clear that there is a non-obvious
bug. And for safety-critical applications, one should not use
untested code.

--
Army1987 (Replace "NOSPAM" with "email")
If you're sending e-mail from a Windows machine, turn off Microsoft's
stupid “Smart Quotes” feature. This is so you'll avoid sprinkling garbage
characters through your mail. -- Eric S. Raymond and Rick Moen

Sep 9 '07 #65
CBFalconer wrote:
Bart van Ingen Schenau wrote:
>>
... snip ...
>>
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?

That depends. Is he in tune? :-)
I really can't tell. His wife immediately moved out, taking him with
her, after it happened. :-)
She seemed rather upset.

Bart v Ingen Schenau
--
a.c.l.l.c-c++ FAQ: http://www.comeaucomputing.com/learn/faq
c.l.c FAQ: http://www.eskimo.com/~scs/C-faq/top.html
c.l.c++ FAQ: http://www.parashift.com/c++-faq-lite/
Sep 9 '07 #66
Army1987 <ar******@NOSPAM.itwrites:
On Sat, 08 Sep 2007 21:48:19 +0200, Army1987 wrote:
>On Sat, 08 Sep 2007 10:03:32 -0400, Joe Wright wrote:
>>[...]To find out
which we use strchr searching for '\0' which will always succeed. If the
NUL is at buff[size-1] we assume the line is longer than buff.

Doesn't strlen(buf) != size - 1 do the same without looking that
weird?
Or better, set buff[size - 1] to a nonzero value, call fgets, and
check whether buff[size - 1] is zero. This takes O(1) time.
This is a neat solution because it also works in the peculiar case of
a line with embedded nulls.

--
Ben.
Sep 9 '07 #67
CBFalconer <cb********@yahoo.comwrites:
Keith Thompson wrote:
<snip>
> You could read from any arbitrary binary file;
depending on the kind of file, it might happen to contain an
arbitrarily long sequence of bytes containing neither '\n' nor '\0'.
<snip>
Generating such a file is a non-trivial exercise, as I discovered
when I created some long lines for ggets testing in the first
place.
Off topic (in c.l.c), but

tr -d '\n' </usr/dict/words

is hardly complex. Indeed, the above with any import will make one
long line.

--
Ben.
Sep 9 '07 #68
"Keith Thompson" <ks***@mib.orga crit dans le message de news:
ln************@nuthaus.mib.org...
Chris Dollin <ch**********@hp.comwrites:
>jacob navia wrote:
[...]
>>In the case of fgets this implies:
o Testing for NULL.
o Testing for a bad value of n (<= 0)
o Testing for a NULL value in the receiving buffer.
[...]
>
>o Testing that the non-null buffer points to a legal C object
containing at least the `n` characters required

o Testing that the non-null stream points to a legal C object

Of course these last two may be impossible to check unless the
implementation keep track of *all* objects, which would impose a
tremendous overhead.
Only the char * pointer would be hard to verify, the stream pointer should
be easy to check against open streams handled by the library, as any
conforming library needs to account for at least those open for write and
update:

7.19.5.2p3 If stream is a null pointer, the fflush function performs this
flushing action on all
streams for which the behavior is defined above.

C libraries used to allocate FILE structures from a static array: checking
for valid FILE pointers was pretty easy then. I would be surprised if
current implementations could no longer do this efficiently.

Chqrlie.
Sep 9 '07 #69
"Keith Thompson" <ks***@mib.orga crit dans le message de news:
ln************@nuthaus.mib.org...
>
Here's the declaration of fgets:

char *fgets(char * restrict s, int n, FILE * restrict stream);
This has probably been discussed before, but I couldn't find a relevant
reference.

Why do we have restrict keywords on s and stream in this function prototype?
They seem to convey no useful information here.

Can anyone explain ?

--
Chqrlie.
Sep 10 '07 #70
Charlie Gordon said:
"Keith Thompson" <ks***@mib.orga crit dans le message de news:
ln************@nuthaus.mib.org...
>>
Here's the declaration of fgets:

char *fgets(char * restrict s, int n, FILE * restrict stream);

This has probably been discussed before, but I couldn't find a
relevant reference.

Why do we have restrict keywords on s and stream in this function
prototype? They seem to convey no useful information here.

Can anyone explain ?
Probably misplaced zeal. The Rationale explains that it's to promise the
compiler that s and stream are not aliaseseseses of each other. Um,
yes, okay, er... fine.

--
Richard Heathfield <http://www.cpax.org.uk>
Email: -www. +rjh@
Google users: <http://www.cpax.org.uk/prg/writings/googly.php>
"Usenet is a strange place" - dmr 29 July 1999
Sep 10 '07 #71
"Army1987" <ar******@NOSPAM.itwrote...
On Fri, 07 Sep 2007 17:38:50 +0000, Douglas A. Gwyn wrote:
/* mystdio.h */
#include <stdio.h// just for FILE
extern char *myfgets(char *, int, FILE *);
#undef fgets // in case <stdio.hdefined it
#define fgets myfgets
You're not allowed to do that.
Not allowed by whom? The program may not be strictly conforming,
but it should still work. If you want to get really fussy about it, make
"mystdio.h" define FILE without including <stdio.h(which requires
some implementation-dependent kludgery); then the fgets-redefining
macro is "allowed".
stdio.h defines size_t, too.
Thanks. The redundant header <stddef.hcould be omitted,
although it didn't hurt to include it.
Sep 10 '07 #72
Keith Thompson <ks***@mib.orgwrites:
Rainer Weikusat <rw*******@mssgmbh.comwrites:
>Jonathan Leffler <jl******@earthlink.netwrites:
>>Rainer Weikusat wrote:
[...]
>>>Any statement ascribing properties to areas not defined by the
C-standard is a statement about something which is not part of C, as
defined by this standard.

Read up on 'Nasal Demons' (Google - 4th entry when I looked). In
comp.std.c land, undefined behaviour means exactly that.

Well, I wasn't about writing 'preferred phantasies of comp.std.c
regulars' but about C. And from the perpsective of the standard text,
claiming that

a = 3;
a = ++a;

results in any particular value for a is as wrong as claiming that it
may cause your next door neighbour to turn into a piano. If it may can
be determined empirically and both the answer and the means for
determining it are not part of the C programming language.

We don't claim (except jokingly) that executing those statements
*will* cause demons to fly out of your nose. The claim is merely that
nasal demons are one of the infinitely many behaviors permitted by the
standard.
It is one of the infinitely many things humans make up because
something like an inbred horror vacui compels them to fill any void
with something. But any example of "behaviour" is necessarily
defined and not undefined.
Sep 10 '07 #73
Bart van Ingen Schenau <ba**@ingen.ddns.infowrites:
Rainer Weikusat wrote:
>Jonathan Leffler <jl******@earthlink.netwrites:
>>Read up on 'Nasal Demons' (Google - 4th entry when I looked). In
comp.std.c land, undefined behaviour means exactly that.

Well, I wasn't about writing 'preferred phantasies of comp.std.c
regulars' but about C. And from the perpsective of the standard text,
claiming that

a = 3;
a = ++a;

results in any particular value for a is as wrong as claiming that it
may cause your next door neighbour to turn into a piano.

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?
I claim that this behaviour is highly illegal and would suggest that
you should try to get a different computer. Apart from that, since no
(standard) definition of 'correct behaviour' exists for this
particular case, its 'correctness' cannot be argued about without
refering to some definition of 'correct behaviour' which is not the
C-standard.
Sep 10 '07 #74
Ben Bacarisse <be********@bsb.me.ukwrites:
>Army1987 <ar******@NOSPAM.itwrites:
>On Sat, 08 Sep 2007 21:48:19 +0200, Army1987 wrote:
>>On Sat, 08 Sep 2007 10:03:32 -0400, Joe Wright wrote:
[...]To find out
which we use strchr searching for '\0' which will always succeed. If the
NUL is at buff[size-1] we assume the line is longer than buff.

Doesn't strlen(buf) != size - 1 do the same without looking that
weird?
Or better, set buff[size - 1] to a nonzero value, call fgets, and
check whether buff[size - 1] is zero. This takes O(1) time.
>This is a neat solution because it also works in the peculiar case of
a line with embedded nulls.

But does the standard restrict writes to the part of the buffer
where no data was read, i.e., is a standard conforming
implementation allowed to start fgets with:

memset(s, '\0', n);
....
Casper
--
Expressed in this posting are my opinions. They are in no way related
to opinions held by my employer, Sun Microsystems.
Statements on Sun products included here are not gospel and may
be fiction rather than truth.
Sep 10 '07 #75
Rainer Weikusat <rw*******@mssgmbh.comwrote:
Keith Thompson <ks***@mib.orgwrites:
We don't claim (except jokingly) that executing those statements
*will* cause demons to fly out of your nose. The claim is merely that
nasal demons are one of the infinitely many behaviors permitted by the
standard.

It is one of the infinitely many things humans make up because
something like an inbred horror vacui compels them to fill any void
with something. But any example of "behaviour" is necessarily
defined and not undefined.
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.

Richard
Sep 10 '07 #76
Rainer Weikusat wrote:
It is one of the infinitely many things humans make up because
something like an inbred horror vacui compels them to fill any void
with something. But any example of "behaviour" is necessarily
defined and not undefined.
(a) There are many instances of behaviour not defined /by the C standard/,
which is the backdrop to our usage here.

(b) There are many instances of behaviour that are not /defined/ at all;
just look out of your window.

--
Chris "theories, not definitions" Dollin

Hewlett-Packard Limited registered no:
registered office: Cain Road, Bracknell, Berks RG12 1HN 690597 England

Sep 10 '07 #77
rl*@hoekstra-uitgeverij.nl (Richard Bos) writes:
Rainer Weikusat <rw*******@mssgmbh.comwrote:
>Keith Thompson <ks***@mib.orgwrites:
We don't claim (except jokingly) that executing those statements
*will* cause demons to fly out of your nose. The claim is merely that
nasal demons are one of the infinitely many behaviors permitted by the
standard.

It is one of the infinitely many things humans make up because
something like an inbred horror vacui compels them to fill any void
with something. But any example of "behaviour" is necessarily
defined and not undefined.

You have obviously never read much about quantum physics.
You have obviously some trouble in understanding to concept of
'abstractly defined semantic'. Since they are a) abstract and b)
exist-only-as-defined, whatever you believe to not know about physics
simply does not apply here.
And yes, when the Standard does not define what a piece of code does
Then the standard does not define what a piece of code does. And
that's the end of it in this respect. But fwiw,
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
It is not (generally) possible to execute microprocessor instructions
which don't do something specific. But this speculation is besides the
point. The bheaviours is undefined. This means it is undefined.
Sep 10 '07 #78
Rainer Weikusat <rw*******@mssgmbh.comwrites:
Keith Thompson <ks***@mib.orgwrites:
[...]
>We don't claim (except jokingly) that executing those statements
*will* cause demons to fly out of your nose. The claim is merely that
nasal demons are one of the infinitely many behaviors permitted by the
standard.

It is one of the infinitely many things humans make up because
something like an inbred horror vacui compels them to fill any void
with something. But any example of "behaviour" is necessarily
defined and not undefined.
The behavior is not defined *by the standard*. If it happens to be
defined by something else, that's fine, but it's not relevant here in
comp.{lang,std}.c.

--
Keith Thompson (The_Other_Keith) ks***@mib.org <http://www.ghoti.net/~kst>
San Diego Supercomputer Center <* <http://users.sdsc.edu/~kst>
"We must do something. This is something. Therefore, we must do this."
-- Antony Jay and Jonathan Lynn, "Yes Minister"
Sep 10 '07 #79
Chris Dollin <ch**********@hp.comwrites:
Rainer Weikusat wrote:
>It is one of the infinitely many things humans make up because
something like an inbred horror vacui compels them to fill any void
with something. But any example of "behaviour" is necessarily
defined and not undefined.

(a) There are many instances of behaviour not defined /by the C standard/,
which is the backdrop to our usage here.
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?

Does that sound a little contradictory? What's YOUR problem with
accepting that what isn't there simply isn't there?

And could you perhaps discuss this with a professional?
Sep 10 '07 #80
On Sep 8, 8:07 am, Barry Margolin <bar...@alum.mit.eduwrote:
In article <1189149497.959132.199...@22g2000hsm.googlegroups. com>,
Sheth Raxit <raxitsheth2...@gmail.comwrote:
don't you think instead of "not saying" or "saying undefined
behaviour" any additional checks are put itself in std ?

This would be redundant and inefficient. Instead of the programmer
checking the return value of fopen() once, all the I/O functions would
have to check the value of the stream every time.

Consider an inner loop calling fgetc(). This is a very simple
operation, probably only about 5-10 instructions most of the time
(because of buffering -- if there's data in the buffer it just has to
copy one byte and increment the buffer pointer). Adding the NULL check
would slow it down by 20-30%, I suspect.
really valid/worth and to the point description. Thanks a lot,

-Raxit
>
--
Barry Margolin, bar...@alum.mit.edu
Arlington, MA
*** PLEASE post questions in newsgroups, not directly to me ***
*** PLEASE don't copy me on replies, I'll read them in the group ***

Sep 10 '07 #81
Keith Thompson <ks***@mib.orgwrites:
Rainer Weikusat <rw*******@mssgmbh.comwrites:
>Keith Thompson <ks***@mib.orgwrites:
[...]
>>We don't claim (except jokingly) that executing those statements
*will* cause demons to fly out of your nose. The claim is merely that
nasal demons are one of the infinitely many behaviors permitted by the
standard.

It is one of the infinitely many things humans make up because
something like an inbred horror vacui compels them to fill any void
with something. But any example of "behaviour" is necessarily
defined and not undefined.

The behavior is not defined *by the standard*. If it happens to be
defined by something else, that's fine, but it's not relevant here in
comp.{lang,std}.c.
You misunderstand my point. To state that 'the behavious is undefined'
means 'no information regarding this behaviour is available'. This
makes (as I have already written) the claim that 'anything can happen'
as wrong as the claim that 'it will cause global warming to stop' or
'nothing will happen' or 'it will cause a to be incremented twice' or
any other conceivable description of any something. The defined
reality of this place is void and any discussion going beyond stating
the the behaviour of ... is undefined is a discussion about something
which is not part of the C programming language as defined by the
C-standard.

As soon as you (or anyvbody else) claims that such-and-such a thing
may happen, you are not talking about C anymore.

Sep 10 '07 #82
Rainer Weikusat wrote:
You misunderstand my point. To state that 'the behavious is undefined'
means 'no information regarding this behaviour is available'.
No, it means -- here -- that no restrictions on the behaviour have been
given by the standard.

Although it's just occurred to me to wonder why, say, `i += 1` can't
deliver nasal demons. After all, the Standard only covers the abstract
behaviour of the implementation. An implementation where every addition
operation nasalised you wouldn't be conformant /just because of that/,
would it?

--
Chris "ha-SHOO!" Dollin

Hewlett-Packard Limited registered office: Cain Road, Bracknell,
registered no: 690597 England Berks RG12 1HN

Sep 10 '07 #83
Casper H.S. Dik <Ca********@Sun.COMwrites:
Ben Bacarisse <be********@bsb.me.ukwrites:
>>Army1987 <ar******@NOSPAM.itwrites:
>>On Sat, 08 Sep 2007 21:48:19 +0200, Army1987 wrote:

On Sat, 08 Sep 2007 10:03:32 -0400, Joe Wright wrote:
[...]To find out
which we use strchr searching for '\0' which will always succeed. If the
NUL is at buff[size-1] we assume the line is longer than buff.

Doesn't strlen(buf) != size - 1 do the same without looking that
weird?
Or better, set buff[size - 1] to a nonzero value, call fgets, and
check whether buff[size - 1] is zero. This takes O(1) time.
>>This is a neat solution because it also works in the peculiar case of
a line with embedded nulls.


But does the standard restrict writes to the part of the buffer
where no data was read, i.e., is a standard conforming
implementation allowed to start fgets with:

memset(s, '\0', n);
....
I think not, though there is wriggle room. There is no wriggle room
in the case of no data being read: "[if] no characters have been read
into the array, the contents of the array remain unchanged" so fgets
can't start that way.

Reading one character and then filling with nulls might, just, pass
the other wording but the description is mechanical enough to suggest
the very minimal tampering with the buffer is expected:

"The fgets function reads at most one less than the number of
characters specified by n from the stream pointed to by stream into
the array pointed to by s. No additional characters are read after a
new-line character (which is retained) or after end-of-file. A null
character is written immediately after the last character read into
the array."

--
Ben.
Sep 10 '07 #84
In article <87************@fever.mssgmbh.com>,
Rainer Weikusat <rw*******@mssgmbh.comwrote:
>You misunderstand my point. To state that 'the behavious is undefined'
means 'no information regarding this behaviour is available'.
In the context of the C standard, "the behaviour is undefined" doesn't
mean that. It means that no information regarding it is available
*in the C standard*.
>This
makes (as I have already written) the claim that 'anything can happen'
as wrong as the claim that 'it will cause global warming to stop'
And given the correct interpretation, that claim is right. The C
standard does not prohibit the implementation from stopping global
warming.

Discussion of nasal daemons and the like is not intended to describe
the real world, it's intended to elucidate a technical term, so
rejecting it on practical grounds is pointless.

-- Richard
--
"Consideration shall be given to the need for as many as 32 characters
in some alphabets" - X3.4, 1963.
Sep 10 '07 #85
Rainer Weikusat wrote:
>
rl*@hoekstra-uitgeverij.nl (Richard Bos) writes:
[...]
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

It is not (generally) possible to execute microprocessor instructions
which don't do something specific. But this speculation is besides the
point. The bheaviours is undefined. This means it is undefined.
You've never run on a CPU which can perform more than one
instruction at a time, have you?

Consider, for example:

int i;
...
i = i++;

There is no reason to expect that the compiler can't generate
something along the lines of:

something \ These two instructions run in parallel
load r1,i /

store r1,i \ As do these
incr i /

This isn't an issue with "j = i++" because the store will write
to j. However, in this case, both instructions attempt to write
to i, causing a bus conflict and locking the system.

Perhaps the system has some protection against this, but it will
still fail depending on the value in i. Perhaps, for example, if
i is 0xffffffff and the increment causes an overflow exception to
occur while it is handling the collision exception.

Okay, I suppose you could say that this behavior is "defined" in
the sense that the outcome is not dependent on quamtum physics,
but it's still not "defined" in the sense that "the answer must
be A or B". (There are many people who stongly believe that the
only possible outcome of "i=3; i=i++;" is that i must contain the
value 3, and there are others who know about sequence points who
will insist that the only possible answers are that i contain the
value 3 or 4.)

And, regardless, the behavior is still "undefined" as far as the
C standard is concerned. Code that depends on a particular
compiler's particular code generator's output is asking for
trouble.

--
+-------------------------+--------------------+-----------------------+
| Kenneth J. Brody | www.hvcomputer.com | #include |
| kenbrody/at\spamcop.net | www.fptech.com | <std_disclaimer.h|
+-------------------------+--------------------+-----------------------+
Don't e-mail me at: <mailto:Th*************@gmail.com>
Sep 10 '07 #86
CBFalconer wrote:
>
Bart van Ingen Schenau wrote:
... snip ...

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?

That depends. Is he in tune? :-)
He's tuned a little high. That middle C sounds like a C#. :-)

--
+-------------------------+--------------------+-----------------------+
| Kenneth J. Brody | www.hvcomputer.com | #include |
| kenbrody/at\spamcop.net | www.fptech.com | <std_disclaimer.h|
+-------------------------+--------------------+-----------------------+
Don't e-mail me at: <mailto:Th*************@gmail.com>
Sep 10 '07 #87
"Kenneth Brody" <ke******@spamcop.neta crit dans le message de news:
46***************@spamcop.net...
CBFalconer wrote:
>>
Bart van Ingen Schenau wrote:
>
... snip ...
>
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?

That depends. Is he in tune? :-)

He's tuned a little high. That middle C sounds like a C#. :-)
Not a surprise: he lives in the D flat.

--
Chqrlie.
Sep 10 '07 #88
Richard Heathfield wrote:
Charlie Gordon said:
"Keith Thompson" <ks***@mib.orga crit dans le message de news:
ln************@nuthaus.mib.org...
>
Here's the declaration of fgets:

char *fgets(char * restrict s, int n, FILE * restrict stream);
This has probably been discussed before, but I couldn't find a
relevant reference.

Why do we have restrict keywords on s and stream in this function
prototype? They seem to convey no useful information here.

Can anyone explain ?

Probably misplaced zeal. The Rationale explains that it's to promise the
compiler that s and stream are not aliaseseseses of each other. Um,
yes, okay, er... fine.
I'm not sure I follow the "misplaced zeal' comment. Do you really want
the standard to say that fgets() must behave as described, even if s
happens to alias stream? The purpose for which 'restrict' was invented
was to convey the fact that such situations are to be avoided.

Sep 10 '07 #89
Kenneth Brody <ke******@spamcop.netwrites:
Rainer Weikusat wrote:
>rl*@hoekstra-uitgeverij.nl (Richard Bos) writes:
[...]
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

It is not (generally) possible to execute microprocessor instructions
which don't do something specific. But this speculation is besides the
point. The bheaviours is undefined. This means it is undefined.

You've never run on a CPU which can perform more than one
instruction at a time, have you?
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.

So leave it.
Sep 10 '07 #90
Rainer Weikusat wrote:
....
You misunderstand my point.
No, we understand your point, which is how we realized that it's in
need of correction.
... To state that 'the behavious is undefined'
means 'no information regarding this behaviour is available'.
That might be what the phrase means in ordinary English; it's not
what the phrase means in the C standard. The C standard explicitly
defines "undefined behavior" as referring to "behavior ... upon which
THIS INTERNATIONAL STANDARD imposes no requirements" (emphasis
added). You yourself have quoted this text, but seem to have
forgotten the significance of the part that I emphasized: it means
that the behavior is undefined, as far as the standard is concerned,
even if something other than the standard does provide a definition..
Within the context of the C standard, that's what the phrase means;
it's meaning in ordinary English is irrelevant.

That's a pretty good thing because if the standard used your
definition of "undefined behavior" it would require implementors to
detect code which has undefined behavior (which is currently not
required, and infeasible because in some cases it's equivalent to
solving the halting problem). Implementations would have to make sure
that it's impossible to collect any information about what the actual
behavior would be when the behavior is undefined. I don't see any way
for a compiler to render such data collection impossible. In
particular, I don't see any way the implementation can prevent
collection of the following information about the behavior: "the
behavior will be consistent with physical law". Therefore, I'm glad
that the standard doesn't mandate the hiding of such information.
... This
makes (as I have already written) the claim that 'anything can happen'
as wrong as the claim that 'it will cause global warming to stop' or
'nothing will happen' or 'it will cause a to be incremented twice' or
any other conceivable description of any something.
There's a big difference between stating that some particular thing
must happen (which is a direct contradiction of the idea that the
behavior is undefined), and stating that some particular thing may
happen (which is an explicit example of precisely the same idea that
is conveyed by the phrase "undefined behavior"). I can't figure out
your reasoning that leads you to see "As far as the standard is
concerned, such code may cause nasal deamons" as contradictory to
either your definition of "undefined behavior", or the standard's
definition. With your definition, it's quite clear that there's no
information allowing you to reject nasal daemons as a possible
outcome, With the standard's definition, it's clear that the standard
contains no wording which forbids nasal daemons as an outcome. The
only difference is that the standard's definition allows reality to
impose a constraint due to the non-existence of nasal deamons. Your
definition would mandate that the implementation must ensure that
nasal daemons are a possibility, whether or not reality cooperates.
As soon as you (or anyvbody else) claims that such-and-such a thing
may happen, you are not talking about C anymore.
I don't see how you can reach that conclusion - the most plausible
interpretation I can come up with which makes that a reasonable
conclusions is that you are confusing "may" with "must", but that
doesn't seem very plausible either. Saying that "anything can happen"
is a valid way of restating the fact the the C standard fails to
impose any requirements on the behavior. Saying that some particular
thing "may happen" provides a specific example of what "anything may
happen" means, and it's useful didactically because well chosen
examples of behavior that is not prohibitied help motivate developers
to avoid writing code with undefined behavior.

Sep 10 '07 #91
kuyper said:
Richard Heathfield wrote:
>Charlie Gordon said:
<snip>
>
Why do we have restrict keywords on s and stream in this function
prototype? They seem to convey no useful information here.

Can anyone explain ?

Probably misplaced zeal. The Rationale explains that it's to promise
the compiler that s and stream are not aliaseseseses of each other.
Um, yes, okay, er... fine.

I'm not sure I follow the "misplaced zeal' comment. Do you really want
the standard to say that fgets() must behave as described, even if s
happens to alias stream? The purpose for which 'restrict' was invented
was to convey the fact that such situations are to be avoided.
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".
--
Richard Heathfield <http://www.cpax.org.uk>
Email: -www. +rjh@
Google users: <http://www.cpax.org.uk/prg/writings/googly.php>
"Usenet is a strange place" - dmr 29 July 1999
Sep 10 '07 #92
"Richard Heathfield" <rj*@see.sig.invalida crit dans le message de news:
_o******************************@bt.com...
Charlie Gordon said:
>"Keith Thompson" <ks***@mib.orga crit dans le message de news:
ln************@nuthaus.mib.org...
>>>
Here's the declaration of fgets:

char *fgets(char * restrict s, int n, FILE * restrict stream);

Why do we have restrict keywords on s and stream in this function
prototype? They seem to convey no useful information here.

Can anyone explain ?

Probably misplaced zeal. The Rationale explains that it's to promise the
compiler that s and stream are not aliaseseseses of each other. Um,
yes, okay, er... fine.
That's what I was inferring, is the Rationale available for download ?

restrict is basically a promise by the programmer to the compiler that the
parts of objects read and modified by restrict-qualified pointers do not
overlap.
Specifying restrict on arguments in function prototypes gives no indication
to the compiler, and only a vague hint to the programmer, quite insufficient
to avoid undefined behaviour or to generate appropriate warnings.

Why should the compiler complain about the following:
char buf[100];
memcpy(buf, buf + 10, 10); // both pointers point to the same object, but
the data accessed thru them do not overlap.
memcpy(buf, buf, 0); // pointers are identical! yet behaviour is defined, no
data is accessed.

What about this example:
const char *modestr = "r";
FILE *fp = fopen(modestr, modestr);

What is wrong with that code ? why does fopen specify restrict on its const
char * parameters ? why should aliassing be a problem in this case as
neither string is modified ?
It looks like unnecessary noise for no benefits.
--
Chqrlie.
Sep 10 '07 #93
"Richard Heathfield" <rj*@see.sig.invalida crit dans le message de news:
BN******************************@bt.com...
kuyper said:
>Richard Heathfield wrote:
>>Charlie Gordon said:
<snip>
>>
Why do we have restrict keywords on s and stream in this function
prototype? They seem to convey no useful information here.

Can anyone explain ?

Probably misplaced zeal. The Rationale explains that it's to promise
the compiler that s and stream are not aliaseseseses of each other.
Um, yes, okay, er... fine.

I'm not sure I follow the "misplaced zeal' comment. Do you really want
the standard to say that fgets() must behave as described, even if s
happens to alias stream? The purpose for which 'restrict' was invented
was to convey the fact that such situations are to be avoided.

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".
Still not a good reason to pollute the library spec with useless restrict
keywords:

fread(stdin, sizeof(*stdin), 1, stdin); invokes undefined behaviour and
could be detected because of the restrict qualification.... but
fread(stdout, sizeof(*stdout), 1, stdin); is just as bad and will go
unnoticed ;-)

--
Chqrlie.
Sep 10 '07 #94
Charlie Gordon said:

<snip>
is the Rationale available for download ?
Yes - if you search for C99 Rationale, it will probably be the top hit.

--
Richard Heathfield <http://www.cpax.org.uk>
Email: -www. +rjh@
Google users: <http://www.cpax.org.uk/prg/writings/googly.php>
"Usenet is a strange place" - dmr 29 July 1999
Sep 10 '07 #95
Charlie Gordon wrote:
>
"Kenneth Brody" <ke******@spamcop.neta crit dans le message de news:
46***************@spamcop.net...
CBFalconer wrote:
>
Bart van Ingen Schenau wrote:

... snip ...

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?

That depends. Is he in tune? :-)
He's tuned a little high. That middle C sounds like a C#. :-)

Not a surprise: he lives in the D flat.
Ask a joke writer, you're a natural. Such things are not my forte,
but I won't rest until I can coda response that will make you quaver
in anticipation.

--
+-------------------------+--------------------+-----------------------+
| Kenneth J. Brody | www.hvcomputer.com | #include |
| kenbrody/at\spamcop.net | www.fptech.com | <std_disclaimer.h|
+-------------------------+--------------------+-----------------------+
Don't e-mail me at: <mailto:Th*************@gmail.com>

Sep 10 '07 #96
Rainer Weikusat wrote:
... But any example of "behaviour" is necessarily
defined and not undefined.
No, in many cases C-standard "undefined behavior" has no definition
anywhere and is in generally unpredictable. For example, what
happens when you pass a pointer to a random place instead of a
valid FILE object to a stdio function? Almost anything could
happen, depending on what happens to be stored at that location.

The point about "undefined behavior" is to completely avoid
producing it in maximally portable code, and to follow local
implementation guidelines when the implementation chooses to
provided a definition for specific cases of behavior that the
C standard labels "undefined".
Sep 10 '07 #97
Charlie Gordon wrote:
Specifying restrict on arguments in function prototypes gives no indication
to the compiler, and only a vague hint to the programmer, quite insufficient
to avoid undefined behaviour or to generate appropriate warnings.
It did allow us to not put in all those extra chunks of wording
saying that the pointed-to objects shall not overlap.
Sep 10 '07 #98
Rainer Weikusat wrote:
Bart van Ingen Schenau <ba**@ingen.ddns.infowrites:
>Rainer Weikusat wrote:
>>Jonathan Leffler <jl******@earthlink.netwrites:
Read up on 'Nasal Demons' (Google - 4th entry when I looked). In
comp.std.c land, undefined behaviour means exactly that.

Well, I wasn't about writing 'preferred phantasies of comp.std.c
regulars' but about C. And from the perpsective of the standard
text, claiming that

a = 3;
a = ++a;

results in any particular value for a is as wrong as claiming that
it may cause your next door neighbour to turn into a piano.

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?

I claim that this behaviour is highly illegal and would suggest that
you should try to get a different computer. Apart from that, since no
(standard) definition of 'correct behaviour' exists for this
particular case, its 'correctness' cannot be argued about without
refering to some definition of 'correct behaviour' which is not the
C-standard.
You seem to contradict yourself. If the correctness of the behaviour can
not be determined from the C standard, then you also can not claim that
any particular behaviour is incorrect for the DS9K.

Please not that the DS9K does not always obey the laws of physics, so
behaviour that ranges from physically implausible to impossible can
very well occur with a DS9K.
If you are not familiar with the DS9K, take a look here
http://en.wikipedia.org/wiki/DeathStation_9000, and at some of the
linked pages.

Bart v Ingen Schenau
--
a.c.l.l.c-c++ FAQ: http://www.comeaucomputing.com/learn/faq
c.l.c FAQ: http://www.eskimo.com/~scs/C-faq/top.html
c.l.c++ FAQ: http://www.parashift.com/c++-faq-lite/
Sep 10 '07 #99
Richard Heathfield wrote, On 10/09/07 17:58:
Charlie Gordon said:

<snip>
>is the Rationale available for download ?

Yes - if you search for C99 Rationale, it will probably be the top hit.
If you go to http://clc-wiki.net/wiki/c_standard there is definitely a
link to it.
--
Flash Gordon
Sep 10 '07 #100

This discussion thread is closed

Replies have been disabled for this discussion.

By using this site, you agree to our Privacy Policy and Terms of Use.