469,366 Members | 2,198 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
On Tue, 11 Sep 2007 16:50:20 -0400, "Wojtek Lerch" <Wo******@yahoo.cawrote:
"Keith Thompson" <ks***@mib.orgwrote in message
news:ln************@nuthaus.mib.org...
>The point, I think, is that the 'restrict' qualifiers allow the
compiler to assume that the char* and FILE* arguments point to
non-overlapping memory.

No they don't, except when they are in the function *definition*. In
a mere declaration, adding the restrict qualifier to parameters is as
meaningless as adding the const qualifier.
Hmmm... Doesn't that "break" the whole concept of 'restrict' as a
qualifier for separate translation units?
The following program is strictly conforming:

void fun( int *restrict p, int *restrict q );

int main( void ) {
int a = 0;
fun( &a, &a );
return a;
}

void fun( int *const x, int *const y ) {
*x = *y + 1;
*y = *x - 1;
}
What happens when the function definition of fun() is in an entirely
separate TU? Isn't than the 'restrict' qualifier useful in the header
file of that TU?

Sep 13 '07 #201
["Followup-To:" header set to comp.lang.c.]
On 2007-09-13 10:57, Rainer Weikusat <rw*******@mssgmbh.comwrote:
kuyper <ku****@wizard.netwrites:
>But it is NOT pointless to illustrute what "undefined behavior"
means by giving extreme examples.

It is not possible to illustrate 'nothing' by providing examples of
it.
But it is not "nothing", it is "everything".

hp

--
_ | Peter J. Holzer | I know I'd be respectful of a pirate
|_|_) | Sysadmin WSR | with an emu on his shoulder.
| | | hj*@hjp.at |
__/ | http://www.hjp.at/ | -- Sam in "Freefall"
Sep 13 '07 #202
kuyper <ku****@wizard.netwrites:
Rainer Weikusat wrote:
>kuyper <ku****@wizard.netwrites:
Rainer Weikusat wrote:
This text would fit into a newsgroup whose topic is production of
mildly creative absurd fiction or one discussing quirks of a
particular implementation of C BUT NOT into a discussion of C, because
it is only insofar related to it as it talks about something the
C-standard does not talk about. And 'C' is the set of things the
C-standard DOES talk about.

[...]
But it is NOT pointless to illustrute what "undefined behavior"
means by giving extreme examples.

It is not possible to illustrate 'nothing' by providing examples of
it.

True, but not very relevant. "nothing" is only one of the possible
forms that undefined behavior can take,
There is no such thing as a form of undefined behaviour because it
is undefined. If there was, it would be defined. In case of the midly
creative absurd fiction, it would be 'random nonsense defined by the
author'. And this random nonsense defined by whoever felt the desire
to write it is not part of the C-standard.

Sep 13 '07 #203
Rainer Weikusat wrote:
>
There is no such thing as a form of undefined behaviour because it
is undefined. If there was, it would be defined. In case of the midly
creative absurd fiction, it would be 'random nonsense defined by the
author'. And this random nonsense defined by whoever felt the desire
to write it is not part of the C-standard.
Your view does not appear to be having much support. This is an
unmoderated group and what is acceptable is largely up to the consensus
to determine.

If you have anything technical and on topic to contribute please do so.
--
Note that robinton.demon.co.uk addresses are no longer valid.
Sep 13 '07 #204
Rainer Weikusat wrote:
There is no such thing as a form of undefined behaviour
Yes, there is. /Every/ program behaviour is an example of undefined
behaviour (as it is defined by the C standard).

The standard puts constraints on the behaviour of a program: it
says certain things are not permitted (and consequently that
others are required). In the specific case of "undefined behaviour",
there are /no constraints applied/, so all behaviours are acceptable.
because it is undefined. If there was, it would be defined.
You're confusing "undefined behaviour" (behaviour which isn't defined by
anything anywhere) and "undefined behaviour" (behaviour on which the
standard places no requirements). The latter technical term is the
one typically used in this newsgroup.

(You're also making a philosophical error, in that you apparently
believe that every behaviour /must/ have a definition, which as
far as I can see at best wishful thinking; but we can deal with
your argument without worrying about that.)

--
Chris "Three." Dollin

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

Sep 13 '07 #205
Francis Glassborow <fr****************@btinternet.comwrites:
Rainer Weikusat wrote:
>>
There is no such thing as a form of undefined behaviour because it
is undefined. If there was, it would be defined. In case of the midly
creative absurd fiction, it would be 'random nonsense defined by the
author'. And this random nonsense defined by whoever felt the desire
to write it is not part of the C-standard.
Your view does not appear to be having much support.
Well, count me as in support then. I did not say anything before
because RW was arguing perfectly adequately without my muddying the
waters but I, too, dislike any operation description of UB.

Because I have a liking for denotational semantics, given a C program
X which has some UB elements in it, I think E[X] = _|_ [1]. It is
worrying that, for some beginners, this fact (that their program has
no meaning) is not distressing enough, but attaching fanciful stories
to _|_ (especially ones to which experience will soon attribute low
probabilities) makes it seem *less* serious in my book.

It think RW's position is encapsulated in the last words of
Wittgenstein's Tractatus: "Whereof one cannot speak, thereof one must
be silent".

[1] The E in E[X] is the curly E used to refer to the "meaning" of
the program. _|_ is "bottom" (⊥ if you have a modern new reader and
some good fonts).

--
Ben.
Sep 13 '07 #206
Rainer Weikusat wrote:
>
kuyper <ku****@wizard.netwrites:
Rainer Weikusat wrote:
This text would fit into a newsgroup whose topic is production of
mildly creative absurd fiction or one discussing quirks of a
particular implementation of C BUT NOT into a discussion of C, because
it is only insofar related to it as it talks about something the
C-standard does not talk about. And 'C' is the set of things the
C-standard DOES talk about.

[...]
But it is NOT pointless to illustrute what "undefined behavior"
means by giving extreme examples.

It is not possible to illustrate 'nothing' by providing examples of
it.
But UB is not "nothing".

Perhaps you don't realize that the term "undefined behavior" is,
in fact, defined. And it doesn't mean that "nothing" can happen.
In fact, just the opposite -- if a "nothing" part, which you appear
to be fixated on, even exists, it applies to _limits_ on what can
happen. There are _no_ limits to what can happen, which means,
literally, that _anything_ can happen.

So, it _is_ possible in this case to illustrate "nothing" by
providing examples of things which fall into the "no limits"
category.

--
+-------------------------+--------------------+-----------------------+
| 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 13 '07 #207
Rainer Weikusat wrote:
>
kuyper <ku****@wizard.netwrites:
Rainer Weikusat wrote:
kuyper <ku****@wizard.netwrites:
[...]
>
As you've misinterpreted this definition, the standard imposes
requirements so stringent that they cannot even be met:
"There is no such thing ...".

The text was "There is no such thing as a form of undefined behaviour
because it is undefined." And it was written in response to your claim
that the standard would specify 'forms of the undefined', in other
words impose, requirements on it.
The Standard specifies no such thing as "forms of the undefined",
and no one here is specifying such things, either. Rather, they
are giving examples of behavior which do not contradict UB in the
Standard.

No one is saying "i = i++;" _will_ do such-and-such. Rather, they
are saying that "i = i++;" _may_ do such-and-such, and it would
still be conforming.

[...]
One option available to you would be to file a Defect Report with
the C committee asking for clarification of this issue.

The issue is perfectly clear.

That

i = 3;
i = ++i;

means 'the value of i is now 3' is wrong,
No, it's not. Or, rather, it might not. It is certainly possible
that a given implementation results in i having a value of 3, and
such an implementation would be conforming.

Now, to say that "the value of i shall be 3" would be wrong, as it
contradicts the Standard. (Unless you are an implementor, and you
have chosen to define your particular implementation's behavior in
this case. Defining what your implementation does with UB is
allowed.)
because the meaning of this statement is undefined.
I assume that "this statement" refers to "i = ++i;" and not "the
value of i is now 3".
'i has now the value of 4' is wrong for the
same reason.
Again, the value of i may be 4 in a conforming implementation.
Stating that it means that 'the front door should open'
is still wrong.
No one here is making such a statement. There is a world of
difference between "the front door should open" and "the front
door could open".

And, again, if you are making your own implementation, you are
certainly free to say "the front door should open" as it
pertains to your implementation.
Same reason again. And this can be continued for every
possible statement about anything: There is no statement which is
supposed to be true, provided the reference for determining what
exactly is true or false is the C-standard, which, for this particular
instance, does not define that.
Every statement made here by the regulars is true in this
regard, as they are always qualified with "may do this", or "does
this on my particular platform".
This is completely orthogonal to the question what conceivable
behaviour of C-implementations when processing this piece of non-C
could be. And C is again very simple in this respect: Whatever the
behaviour may be, it does not matter. No reason to discuss it.
There are plenty of reasons to discuss this when the subject comes
up with someone posting either a question ("why does X do Y?") or,
even more importantly, when someone answers "why" with a definitive
statement ("because 'i++' returns the old value").

The reason for discussing it is to make it clear to the reader that
UB has been invoked, and the result of UB can be, literally, anything.

--
+-------------------------+--------------------+-----------------------+
| 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 13 '07 #208
Rainer Weikusat wrote:
kuyper <ku****@wizard.netwrites:
The standard DEFINES what the phrase "undefined behavior" means in the
context of the C standard: "behavior upon which this international
standard imposes no requirements".
Correct. But that is not a definition of 'undefined behaviour' (even
trying to do so would quite obviously contradict the term) but what
the phrase 'undefined behaviour' is supposed to mean: Behaviour which
is not defined by the standard. Specifically, it is neither defined as
random nor as arbitrary but NOT defined.
Wrong; it is the operative definition for the term "undefined
behavior" in the context of the C standard. There is no
contradiction in defining that term, any more than there would
be to *write* about the properties of *sound*. You're mixing
"levels" (to borrow Hofstadter's phrase).
Sep 13 '07 #209
Bart van Ingen Schenau <ba**@ingen.ddns.infowrites:
Rainer Weikusat wrote:
>kuyper <ku****@wizard.netwrites:
>>The standard DEFINES what the phrase "undefined behavior" means in
the context of the C standard: "behavior upon which this
international standard imposes no requirements".

Correct. But that is not a definition of 'undefined behaviour' (even
trying to do so would quite obviously contradict the term) but what
the phrase 'undefined behaviour' is supposed to mean: Behaviour which
is not defined by the standard. Specifically, it is neither defined as
random nor as arbitrary but NOT defined.

Wrong. In this group the convention is that if a term or phrase is
defined by the C standard, then that definition is how the term
should/will be interpreted when used in a post to this group.
The term 'undefined behaviour' has such a definition in the standard, so
you can't just interpret it the way you do.

You seem to imply that, if a program invokes UB, then whatever behaviour
results is wrong, because showing behaviour means that it must be
defined, which contradicts your interpretation of 'undefined
behaviour'. This leads to the logical conclusion that 'undefined
behaviour' can not exist.
I think you've misinterpreted (this part of) what Rainer is saying.

Obviously the phrase "undefined behavior" is defined by the standard
(C99 3.4.3). Given that definition, the behavior of any code whose
behavior is undefined is not defined.

The phrase is defined. The behavior is not. I *think* that's all
Rainer is saying here.

I disagree with some of Rainer's other arguments, but I think he's
correctly summarized what the standard says about UB.

[snip]

--
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 13 '07 #210
Rainer Weikusat <rw*******@mssgmbh.comwrites:
[...]
There is no such thing as a form of undefined behaviour because it
is undefined. If there was, it would be defined.
Behavior can occur without being defined. Stuff happens.

You've managed to make a claim to which there are infinitely many
counterexamples.

--
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 13 '07 #211
Keith Thompson wrote:
Rainer Weikusat <rw*******@mssgmbh.comwrites:
[...]
>There is no such thing as a form of undefined behaviour because it
is undefined. If there was, it would be defined.

Behavior can occur without being defined. Stuff happens.

You've managed to make a claim to which there are infinitely many
counterexamples.
I don't know that it's /infinitely/ many. The universe may be
finite. Even if it isn't, we don't have access to more than
a finite amount of it.

Certainly there are a /great many/ counterexamples.

--
All But A Finite Hedgehog
"Based on their behaviour so far -- I have no idea" /Sahara/

Sep 13 '07 #212
Ben Bacarisse wrote, On 13/09/07 17:57:
Francis Glassborow <fr****************@btinternet.comwrites:
>Rainer Weikusat wrote:
>>There is no such thing as a form of undefined behaviour because it
is undefined. If there was, it would be defined. In case of the midly
creative absurd fiction, it would be 'random nonsense defined by the
author'. And this random nonsense defined by whoever felt the desire
to write it is not part of the C-standard.
Your view does not appear to be having much support.

Well, count me as in support then.
I'm explicitly NOT saying how is correct and who isn't, because I've not
followed who thinks what carefully enough. Instead I'm going to express
my opinions on some of the points Ben is raising.
I did not say anything before
because RW was arguing perfectly adequately without my muddying the
waters but I, too, dislike any operation description of UB.

Because I have a liking for denotational semantics, given a C program
X which has some UB elements in it, I think E[X] = _|_ [1]. It is
worrying that, for some beginners, this fact (that their program has
no meaning) is not distressing enough, but attaching fanciful stories
to _|_ (especially ones to which experience will soon attribute low
probabilities) makes it seem *less* serious in my book.
<snip>

Personally I *like* the non-serious examples of "possible" results of
undefined behaviour which are obviously things that will not happen on
real-world implementations (the reasons being outside the C standard).
The reasons I like them are as follows:

If it is obviously something that will not happen in the real world
people will not mistake it for a statement of what is actually
guaranteed to happen on some implementation. It also illustrates that,
as far as the definition[1] of C is concerned it is perfectly acceptable
for things to happen that the questioner would not think of. It can be
fun (at least for me) thinking up new and (possibly) amusing
illustrations. Some of the suggestions that others come up with can be
amusing to me.

[1] The questioner might not know about the C standard but they will
know that the language is defined in some manner, even if they think
that their implementation defines it. Most people here obviously know
that the C standard defines the current language, and has at least since
C89 was pretty much universally implemented.

Please note that I've cut the cross-post since I'm talking about what
goes on in comp.lang.c and I am pretty sure the person I'm replying to
reads comp.lang.c.
--
Flash Gordon
Sep 13 '07 #213
Keith Thompson wrote:
Any 'restrict' qualifiers in the definition of memcpy() are meaningful
(*if* memcpy() is implemented in C), but are not necessarily available
to the user.
Right. By including them in the "Synopsis" in the man page,
or equivalent, that information is also made avaialble to the
programmer, although it is not enforced. It's one of many
matters for which C relies on the programmer to use things
properly.
Allowing 'const' qualifiers on pointer parameters to be inconsistent
between a function declaration and its definition makes some sense, I
suppose, since they affect only the implementation of the function;
they say something about the parameter object, which is local to the
body of the function, and there's no reason for the caller to care
about it.
I'm not sure anybody uses "const" at the outer level for
function parameters in prototypes. It wouldn't convey
anything useful for the programmer to know.

"const" is however very useful at the next level, and has
special meaning -- it does *not* mean that the type of the
argument has to be const-qualified at that level, but rather
that no data shall be modified by dereferncing any pointer
value that is based on that argument.
Allowing 'restrict' qualifiers to be inconsistent seems problematic,
since they're saying something about the pointed-to objects, not just
about the pointers, and that's information that could be useful to the
caller.
It is somewhat analogous to "const" at the next-to-outer
level: no modifications shall be made to any object using
a pointer value based on a different (restrict-qualified)
pointer argument.

The "const" restriction is imposed on the function, while
the "restrict" restriction is imposed on the caller.

One could imagine all sorts of other ways to embed such
restrictions into C source code, but those are the onees
we came up with back when decisions had to be made.
Sep 13 '07 #214
"Douglas A. Gwyn" <DA****@null.netwrites:
Keith Thompson wrote:
>Any 'restrict' qualifiers in the definition of memcpy() are meaningful
(*if* memcpy() is implemented in C), but are not necessarily available
to the user.

Right. By including them in the "Synopsis" in the man page,
or equivalent, that information is also made avaialble to the
programmer, although it is not enforced. It's one of many
matters for which C relies on the programmer to use things
properly.
[...]

Ok, but I find this particular instance of that (having a keyword in a
delaration that really has no more meaning than a comment, even though
there *could* be an obvious meaning for it) to be a bit too subtle.
If something is meaningless, it doesn't belong in the language. Just
my opinion. Allowing

void func(int array[42]);

is equally misleading.

Suppressing my natural humility for just a moment (yeah, I know), if
*I* was confused by this, I suspect others are as well.

The "obvious meaning" I'm referring to is that

void *memcpy(void * restrict s1,
const void * restrict s2,
size_t n);

could tell the compiler that this call:

memcpy(buf, buf+1, 42);

invokes undefined behavior, and possibly elicit a warning or even
cause the translation unit to be rejected. Or it could *assume*, in
more subtle cases, that the actual parameters point to non-overlapping
memory and perhaps perform some optimization based on that. (The
compiler is allowed to use its knowledge of standard functions, but
consider a similar user-written function.)

I think I would have preferred it if the qualifiers in a function
declaration and in the corresponding function definition were required
to be identical. With such a rule, the compiler would know from
seeing the qualifiers on the declaration that the parameters are
'restrict'ed, and might be able to act on that knowledge. I don't see
the benefit of allowing the qualifiers to differ.

Another alternative, which would keep the current semantics, would be
to forbid top-level qualifiers on parameter declarations that are not
part of a function definition. They're meaningless anyway, so why
allow them? You can always insert comments.

I'm not suggesting that either change should be made; it would break
existing code.

--
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 13 '07 #215
On Mon, 10 Sep 2007 12:22:31 +0100, Ben Bacarisse wrote:
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."
Expected, but not required. As far as the wording is concerned, fgets
could read n-1 characters, tack on a \0, then fill any remaining space in
the buffer with random values - it is not actually reading additional
characters, and it wrote a null after the last one read, so it is, by this
text, conforming.
Sep 13 '07 #216
Chris Dollin wrote:
>
Keith Thompson wrote:
Rainer Weikusat <rw*******@mssgmbh.comwrites:
[...]
There is no such thing as a form of undefined behaviour because it
is undefined. If there was, it would be defined.
Behavior can occur without being defined. Stuff happens.

You've managed to make a claim to which there are infinitely many
counterexamples.

I don't know that it's /infinitely/ many. The universe may be
finite. Even if it isn't, we don't have access to more than
a finite amount of it.

Certainly there are a /great many/ counterexamples.
So you're saying that there is a /finite/ number of counterexamples?
Are you saying that it is, in theory, possible to enumerate them all?
I doubt that such a "complete" list would be "complete", and that
given such a list, someone somewhere could give an additional example.
And, once that was added to the "well, now it's complete" list, yet
another counterexample could be added.

For proof, I will simply point out that, regardless of the size of
the list, one can always add "both A and B occur", or "you end up at
the midpoint of A and B", where A and B are two items from the
current list.

--
+-------------------------+--------------------+-----------------------+
| 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 13 '07 #217
Kenneth Brody said:
Chris Dollin wrote:
>>
Keith Thompson wrote:
<snip>
>
You've managed to make a claim to which there are infinitely many
counterexamples.

I don't know that it's /infinitely/ many. The universe may be
finite. Even if it isn't, we don't have access to more than
a finite amount of it.

Certainly there are a /great many/ counterexamples.

So you're saying that there is a /finite/ number of counterexamples?
Are you saying that it is, in theory, possible to enumerate them all?
The two statements are not equivalent. There could be finitely many
counterexamples even though it is not possible even in theory to
enumerate them all. If the number of counterexamples exceeds the volume
of the universe (measured in multiples of the smallest volume in which
one such counterexample can be enumerated) multiplied by the duration
of the universe (measured in multiples of the smallest time it takes to
enumerate one counterexample), then it is indeed not possible even in
theory to enumerate them all, any more than one can in theory squeeze a
quart of water into a pint pot.
I doubt that such a "complete" list would be "complete", and that
given such a list, someone somewhere could give an additional example.
And, once that was added to the "well, now it's complete" list, yet
another counterexample could be added.
Oh, for sure. On the one hand, it could, for example, print 1. On the
other hand, it could print 2. On the other other hand, it could print
3. Or 4, perhaps. Or maybe 5? Etc.

--
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 14 '07 #218
On Thu, 13 Sep 2007 15:11:39 -0700, Keith Thompson <ks***@mib.orgwrote:
>"Douglas A. Gwyn" <DA****@null.netwrites:
>Keith Thompson wrote:
>>Any 'restrict' qualifiers in the definition of memcpy() are meaningful
(*if* memcpy() is implemented in C), but are not necessarily available
to the user.

Right. By including them in the "Synopsis" in the man page,
or equivalent, that information is also made avaialble to the
programmer, although it is not enforced. It's one of many
matters for which C relies on the programmer to use things
properly.
[...]

Ok, but I find this particular instance of that (having a keyword in a
delaration that really has no more meaning than a comment, even though
there *could* be an obvious meaning for it) to be a bit too subtle.
Indeed.
Suppressing my natural humility for just a moment (yeah, I know), if
*I* was confused by this, I suspect others are as well.
I was confused right about until the time I read Douglas' explanation.

I guess it's back to the reading room for me :-)
I think I would have preferred it if the qualifiers in a function
declaration and in the corresponding function definition were required
to be identical. With such a rule, the compiler would know from
seeing the qualifiers on the declaration that the parameters are
'restrict'ed, and might be able to act on that knowledge. I don't see
the benefit of allowing the qualifiers to differ.
[...]
I'm not suggesting that either change should be made; it would break
existing code.
I think I agree with that pattern of thought. At least it could make
qualifiers more useful to the compiler; but that's not going to change
easily and I'm not suggesting such a change either.

Sep 14 '07 #219
Kelsey Bjarnason <kb********@gmail.comwrites:
On Mon, 10 Sep 2007 12:22:31 +0100, Ben Bacarisse wrote:
>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."

Expected, but not required. As far as the wording is concerned, fgets
could read n-1 characters, tack on a \0, then fill any remaining space in
the buffer with random values - it is not actually reading additional
characters, and it wrote a null after the last one read, so it is, by this
text, conforming.
I said "I think not, though there is wriggle room". I should have
said "There is wriggle room so I think yes". It is silly, but wriggle
room is wriggle room.

The same argument means the following are UB:

char buf[] = "hello";
strncpy(buf, "j", 5);
buf[1] = 'e';
puts(buf);

char buf[2];
strncpy(buf, "x", 20);

I am not too bothered about that (though I admit I had not thought
about it until now!) but I'd advocate a change to fgets to state that
it modifies no more than the bytes it reads (plus the null) so that
one can easily do such tests.

--
Ben.
Sep 14 '07 #220
"Keith Thompson" <ks***@mib.orgwrote in message
news:ln************@nuthaus.mib.org...
....
The "obvious meaning" I'm referring to is that

void *memcpy(void * restrict s1,
const void * restrict s2,
size_t n);

could tell the compiler that this call:

memcpy(buf, buf+1, 42);

invokes undefined behavior [...] (The
compiler is allowed to use its knowledge of standard functions, but
consider a similar user-written function.)
Well, exactly: consider this user-written function:

void *notquitememcpy(void * restrict s1,
const void * restrict s2,
size_t n) {
return NULL;
}

and this call:

notquitememcpy(buf, buf+1, 42);

Just because you're passing the same pointer to two restrict-qualified
parameters of a function doesn't necessarily cause undefined behaviour -- it
depends on what the function does with them.
I think I would have preferred it if the qualifiers in a function
declaration and in the corresponding function definition were required
to be identical. With such a rule, the compiler would know from
seeing the qualifiers on the declaration that the parameters are
'restrict'ed, and might be able to act on that knowledge. I don't see
the benefit of allowing the qualifiers to differ.
The benefit is that it lets you define a function with const-qualified
parameters without having to commit to their constness in the public
prototype in the header.
Another alternative, which would keep the current semantics, would be
to forbid top-level qualifiers on parameter declarations that are not
part of a function definition. They're meaningless anyway, so why
allow them? You can always insert comments.
I imagine that might complicate programs that parse C code and extract
function prototypes from it.

Sep 14 '07 #221
Rainer Weikusat wrote:
kuyper <ku****@wizard.netwrites:
>Rainer Weikusat wrote:
>>This text would fit into a newsgroup whose topic is production of
mildly creative absurd fiction or one discussing quirks of a
particular implementation of C BUT NOT into a discussion of C, because
it is only insofar related to it as it talks about something the
C-standard does not talk about. And 'C' is the set of things the
C-standard DOES talk about.

[...]
>But it is NOT pointless to illustrute what "undefined behavior"
means by giving extreme examples.

It is not possible to illustrate 'nothing' by providing examples of
it.
NOP

Sep 14 '07 #222
Kenneth Brody wrote:
Chris Dollin wrote:
>>
Keith Thompson wrote:
Rainer Weikusat <rw*******@mssgmbh.comwrites:
[...]
There is no such thing as a form of undefined behaviour because it
is undefined. If there was, it would be defined.

Behavior can occur without being defined. Stuff happens.

You've managed to make a claim to which there are infinitely many
counterexamples.

I don't know that it's /infinitely/ many. The universe may be
finite. Even if it isn't, we don't have access to more than
a finite amount of it.

Certainly there are a /great many/ counterexamples.

So you're saying that there is a /finite/ number of counterexamples?
If the accessible universe is finite, yes.
Are you saying that it is, in theory, possible to enumerate them all?
Yes. Enumerate all possible universe states. The number of counterexamples
is no bigger than this.

Oops: I've an implicit assumption that states are discrete.

I /think/ I could weasel that into the finiteness, but I won't.
I doubt that such a "complete" list would be "complete", and that
given such a list, someone somewhere could give an additional example.
And, once that was added to the "well, now it's complete" list, yet
another counterexample could be added.

For proof, I will simply point out that, regardless of the size of
the list, one can always add "both A and B occur", or "you end up at
the midpoint of A and B", where A and B are two items from the
current list.
Discreteness kills that, I think.

--
Chris "indiscrete" Dollin

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

Sep 14 '07 #223
Chris Dollin said:

<snip>
>
Enumerate all possible universe states.
Where?

--
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 14 '07 #224
"Ben Bacarisse" <be********@bsb.me.uka écrit dans le message de news:
87************@bsb.me.uk...
The same argument means the following are UB:

char buf[] = "hello";
strncpy(buf, "j", 5);
buf[1] = 'e';
puts(buf);
Why do you think the above code should invoke UB ?
It should just output j e and a new-line on stdout
char buf[2];
strncpy(buf, "x", 20);
This one is definitely UB
I am not too bothered about that (though I admit I had not thought
about it until now!)
You do not seem to know the broken semantics of strncpy.
I wouldn't be surprised, very few programmers do.
That's why strncpy should NEVER be used, even in the unlikely cases where it
does exactly what is needed because using it propagates dangerous
misunderstandings on the overwhelming majority on programmers.
but I'd advocate a change to fgets to state that
it modifies no more than the bytes it reads (plus the null) so that
one can easily do such tests.
I agree with you, I doubt many C libraries behave differently, except in
case of a read error, which is explicitly addressed by the Standard already.

--
Chqrlie.
Sep 14 '07 #225
Richard Heathfield wrote:
Chris Dollin said:

<snip>
>>
Enumerate all possible universe states.

Where?
Theory.

--
Chris "that's just a /practical/ problem" Dollin

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

Sep 14 '07 #226
"Charlie Gordon" <ne**@chqrlie.orgwrites:
>That's why strncpy should NEVER be used, even in the unlikely cases where it
does exactly what is needed because using it propagates dangerous
misunderstandings on the overwhelming majority on programmers.
I beg to differ; while strncpy() is weird it was designed for a
single purpose: putting a possibly non-NUL terminated sequence of
characters in a limited size char[] struct field such as those
used in UNIX utmp/wtmp files. For that purpose it is perfect and
it feels wrong to re-implement strncpy() under a different name.

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 14 '07 #227
"Charlie Gordon" <ne**@chqrlie.orgwrites:
"Ben Bacarisse" <be********@bsb.me.uka écrit dans le message de news:
87************@bsb.me.uk...
>The same argument means the following are UB:

char buf[] = "hello";
strncpy(buf, "j", 5);
buf[1] = 'e';
puts(buf);

Why do you think the above code should invoke UB ?
It should just output j e and a new-line on stdout
> char buf[2];
strncpy(buf, "x", 20);

This one is definitely UB
>I am not too bothered about that (though I admit I had not thought
about it until now!)

You do not seem to know the broken semantics of strncpy.
I wouldn't be surprised, very few programmers do.
That's why strncpy should NEVER be used, even in the unlikely cases where it
does exactly what is needed because using it propagates dangerous
misunderstandings on the overwhelming majority on programmers.
You need to run this past me again. Why shouldn't people who don't know
what they are doing not use it?

It seems easy enough to use correctly to me.
>
>but I'd advocate a change to fgets to state that
it modifies no more than the bytes it reads (plus the null) so that
one can easily do such tests.

I agree with you, I doubt many C libraries behave differently, except in
case of a read error, which is explicitly addressed by the Standard already.
Sep 14 '07 #228
Ben Bacarisse wrote:
>
You can phrased it "your program has no defined meaning" or "the C
standard does not say what this program means/does" or just "this is
UB" and these answers come up all the time in c.l.c.
The meaning of the program is unimportant in this context, its behaviour
is. IOWs what it does matters. The point of UB is that executing a
program with UB can result in anything. The Abstract machine is
irrelevant because the program is no longer C and so is outside the
requirements of the Abstract Machine.

Yes we do tend to be a bit jokey when giving examples of 'anything' but
UB behaviour can be pretty drastic (three examples I know of: 1) setting
a monitor on fire -- seriously though this would not happen to modern
monitors there once was one that would overheat and eventually ignite if
its scan rate was set to zero. 2) reprogramming a graphics card
randomly, took me many hours to restore the graphics card. 3) Randomly
reprogramming a programmable keyboard -- that one was really nasty as
the keyboard had condenser backed storage of its settings that ensured
that the current state was secure for almost a year :-(
--
Note that robinton.demon.co.uk addresses are no longer valid.
Sep 14 '07 #229
Francis Glassborow wrote:
Ben Bacarisse wrote:
>>
You can phrased it "your program has no defined meaning" or "the C
standard does not say what this program means/does" or just "this is
UB" and these answers come up all the time in c.l.c.

The meaning of the program is unimportant in this context, its behaviour
is.
The meaning of a[n imperative] program /is/ it's behaviour -- the
changes to the state it produces.
IOWs what it does matters. The point of UB is that executing a
program with UB can result in anything.
Executing a program /without/ UB can result in anything, too. The
standard is only talking about the behaviour of the C abstract
machine. The bits of an implementation that aren't about the C
abstract machine are /already/ unconstrained by the standard.

This isn't what I used to think, but absent a good counter-argument,
it's what I'm thinking now.
The Abstract machine is irrelevant because the program is no longer
C and so is outside the requirements of the Abstract Machine.
I don't think the standard is in a position to say that.
Yes we do tend to be a bit jokey when giving examples of 'anything' but
UB behaviour can be pretty drastic (three examples I know of: 1) setting
a monitor on fire -- seriously though this would not happen to modern
monitors there once was one that would overheat and eventually ignite if
its scan rate was set to zero. 2) reprogramming a graphics card
randomly, took me many hours to restore the graphics card. 3) Randomly
reprogramming a programmable keyboard -- that one was really nasty as
the keyboard had condenser backed storage of its settings that ensured
that the current state was secure for almost a year :-(
What part of the Standard prevents those things from happening when
a conforming program executes -- better, which stop an implementation
that does these things from being a conformant implementation?

--
Chris "willing to argue the corner for a while" Dollin

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

Sep 14 '07 #230
[snips]

On Fri, 14 Sep 2007 13:12:44 +0200, Richard wrote:
You need to run this past me again. Why shouldn't people who don't know
what they are doing not use it?
You mean why _should_ they not use it? Because people who don't know what
they're doing write bad and often dangerous code. Give 'em a spoon
instead. :)

As to why he's suggesting not using it, if I had to guess I'd say
something along the lines of unlike pretty much every other string
function, this one has a nasty tendency to produce non-null-terminated
character arrays; if coders aren't aware of this or fail to pay attention
to it, bad things can happen.
Sep 14 '07 #231
Kelsey Bjarnason <kb********@gmail.comwrites:
[snips]

On Fri, 14 Sep 2007 13:12:44 +0200, Richard wrote:
>You need to run this past me again. Why shouldn't people who don't know
what they are doing not use it?

You mean why _should_ they not use it? Because people who don't know
what
I was making a joke and I think,yes, there is one too many
negatives.. You see, if people dont know how to use an API then they,
well, shouldn't. It is obvious. But they can learn by doing and with
judicous test cases, and debug cycles they will learn to use it
properly.

they're doing write bad and often dangerous code. Give 'em a spoon
instead. :)
or, tell them to read the API.
>
As to why he's suggesting not using it, if I had to guess I'd say
something along the lines of unlike pretty much every other string
function, this one has a nasty tendency to produce non-null-terminated
character arrays; if coders aren't aware of this or fail to pay attention
to it, bad things can happen.
As can i++ if you dont keep an eye on the index limit for an array.

It is bogus advice.

There is *nothing* wrong with strncpy and it is used in millions of
lines of code. In many ways you could say its safer to use since it wont
overwrite memory if the source string is bad.

strtok, on the other hand .....
Sep 14 '07 #232
"Casper H.S. Dik" <Ca********@Sun.COMa écrit dans le message de news:
46*********************@news.xs4all.nl...
"Charlie Gordon" <ne**@chqrlie.orgwrites:
>>That's why strncpy should NEVER be used, even in the unlikely cases where
it
does exactly what is needed because using it propagates dangerous
misunderstandings on the overwhelming majority on programmers.

I beg to differ; while strncpy() is weird it was designed for a
single purpose: putting a possibly non-NUL terminated sequence of
characters in a limited size char[] struct field such as those
used in UNIX utmp/wtmp files. For that purpose it is perfect and
it feels wrong to re-implement strncpy() under a different name.
I gave the rationale for this: if the savvy 1% programmers who know well
keep using it even just for this purpose, the 99% remaining will continue
thinking they know what it does and use it improperly all the time and
produce flawed code everywhere, including life support equipment and
aircraft navigation systems.

The argument is very much the same against gets and sprintf.

Even when dealing with Unix utmp and wtmp structures, it would be better to
write explicit code to deal with these error prone structures, such code is
quite easy to re-write anyway.

How can we defend the need for a function with so little value in the C
library when we do not even have strdup?
Having strncpy causes thousands of bugs.
Not having strdup has the same effect (people will call malloc(strlen(str)))

Fixing these 2 would make the language safer.

--
Chqrlie.
Sep 14 '07 #233
Chris Dollin wrote:
What part of the Standard prevents those things from happening when
a conforming program executes -- better, which stop an implementation
that does these things from being a conformant implementation?
"Conforming program" is a term of little value, and was defined
in the C standard for political reasons. A "strictly conforming
program", however, does not trigger undefined behavior.

"Conforming programs" on "conforming implementations" can do
all sorts of things beyond what the C standard specifies,
including operations that make monitors catch on fire, etc.

Francis's point was that such consequences actually do occur
sometimes when "undefined behavior" is triggered.
Sep 14 '07 #234
Keith Thompson wrote:
Ok, but I find this particular instance of that (having a keyword in a
delaration that really has no more meaning than a comment, even though
there *could* be an obvious meaning for it) to be a bit too subtle.
If something is meaningless, it doesn't belong in the language. ...
Well, it isn't meaningless, but it doesn't affect code generation.

There is a proposal before the C standards committee to adopt
somethings like Microsoft's __declspec facility for annotating
C source code with "attributes" that are outside the scope of
the current C standard. I suspect every experienced C
programmer has occasionally thought that there ought to be
somethings of the sort. Recall /*NOTREACHED*/ to avoid a
spurious warning from "lint"? There is a __declspec attribute
that has the same meaning.

GCC also has similar extensions.
I think I would have preferred it if the qualifiers in a function
declaration and in the corresponding function definition were required
to be identical.
Yes, that might have been better.
Sep 14 '07 #235
"Richard" <rg****@gmail.coma écrit dans le message de news:
eu************@desktop.thrasymachus...
Kelsey Bjarnason <kb********@gmail.comwrites:
>[snips]

On Fri, 14 Sep 2007 13:12:44 +0200, Richard wrote:
>>You need to run this past me again. Why shouldn't people who don't know
what they are doing not use it?

You mean why _should_ they not use it? Because people who don't know
what

I was making a joke and I think,yes, there is one too many
negatives.. You see, if people dont know how to use an API then they,
well, shouldn't. It is obvious. But they can learn by doing and with
judicous test cases, and debug cycles they will learn to use it
properly.
The situation is much worse than you make it sound: they don't know the
semantics, but they think they do. They write code that seems to work as
they expect but contains bugs waiting to bite... just like gets and sprintf.
>they're doing write bad and often dangerous code. Give 'em a spoon
instead. :)

or, tell them to read the API.
I agree: show them the API as an explanation for why they should not use
strncpy.
>>
As to why he's suggesting not using it, if I had to guess I'd say
something along the lines of unlike pretty much every other string
function, this one has a nasty tendency to produce non-null-terminated
character arrays; if coders aren't aware of this or fail to pay attention
to it, bad things can happen.

As can i++ if you dont keep an eye on the index limit for an array.

It is bogus advice.

There is *nothing* wrong with strncpy and it is used in millions of
lines of code. In many ways you could say its safer to use since it wont
overwrite memory if the source string is bad.
to reach millions, you need to count the binaries produced.

You cannot decently say that there be *nothing* wrong with it: its precise
semantics make it almost useless, are conter-intuitive and are vastly
misunderstood, and misused...
strtok, on the other hand .....
Why did C99 not include reentrant versions of strtok and friends baffles me.

--
Chqrlie.

Sep 14 '07 #236
Chris Dollin <ch**********@hp.comwrites:
Rainer Weikusat wrote:
>There is no such thing as a form of undefined behaviour

Yes, there is. /Every/ program behaviour is an example of undefined
behaviour (as it is defined by the C standard).
That's a claim which should be easy to prove: Assuming you are not
deliberatetly misunderstanding me, you appear to claim that 'undefined
behavious' is actually behaviour defined by the C-standard. Since 'no
requirements' isn't a definition of any specific behaviour, this
definition or set of definitions must be in some other location, so
please cite where the standard provides a definition of the allowed
semantics for undefined behaviour.

NB: A positive definition is required.
The standard puts constraints on the behaviour of a program: it
says certain things are not permitted (and consequently that
others are required). In the specific case of "undefined behaviour",
there are /no constraints applied/, so all behaviours are
acceptable.
More correctly (as I have written several times now): There is no such
thing as 'acceptable behaviour' for these case (provided you cannot
magically come up with a positive definition of this beahviour)
because no acceptable behaviour is defined. Presumably, a real-world
implementation of C will have 'some behaviour' in such situation and
whatever this might be is not relevant for determining the standard
conformance of this implementation.
>because it is undefined. If there was, it would be defined.

You're confusing "undefined behaviour" (behaviour which isn't defined by
anything anywhere) and "undefined behaviour" (behaviour on which the
standard places no requirements).
Assuming that the C-standard is relevant for defining the C language,
it is the only location where 'behaviour' can be defined and you are
basically presenting a false dichotomy: There is no such 'other
location'.
Sep 14 '07 #237
Douglas A. Gwyn wrote:
Chris Dollin wrote:
>What part of the Standard prevents those things from happening when
a conforming program executes -- better, which stop an implementation
that does these things from being a conformant implementation?

"Conforming program" is a term of little value, and was defined
in the C standard for political reasons. A "strictly conforming
program", however, does not trigger undefined behavior.

"Conforming programs" on "conforming implementations" can do
all sorts of things beyond what the C standard specifies,
including operations that make monitors catch on fire, etc.

Francis's point was that such consequences actually do occur
sometimes when "undefined behavior" is triggered.
Yes; but my esteemed twin is asking why we think those
consequences can't arise even when the program doesn't
exhibit UB. `i += 1;` may increment `i`, as it should,
/and/ set fire to the monitor.

I'd reject such an implementation on QoI grounds, not
on "not a C implementation" grounds.

--
Setting Fire To /His/ Monitor Is OK Hedgehog
"Based on their behaviour so far -- I have no idea" /Sahara/

Sep 14 '07 #238
Bart van Ingen Schenau <ba**@ingen.ddns.infowrites:
Rainer Weikusat wrote:
[...]
>The issue is perfectly clear.

That

i = 3;
i = ++i;

means 'the value of i is now 3' is wrong,
[...]
So, how many bug-reports have you filed with the compiler builders that
their behaviour for the code above is incorrect?
I wasn't talking about code but about the defined meaning of certain
statements. The statement above has no defined meaning. Ergo: Every
claim that its defined meaning would be ... must be wrong. It doesn't
matter if the claim is something technically sensible for certain C
implementation (like the example I gave above), or some absurd piece
of non-sense intended to be entertaining (like the 'nasal daemons'):
They are both wrong.

BTW, how did you manage to miss that:

| This is completely orthogonal to the question what conceivable
| behaviour of C-implementations when processing this piece of non-C
| could be. And C is again very simple in this respect: Whatever the
| behaviour may be, it does not matter.
Sep 14 '07 #239
Chris Dollin wrote:
Francis Glassborow wrote:
>[some examples of UB that actually happened]
What part of the Standard prevents those things from happening when
a conforming program executes -- better, which stop an implementation
that does these things from being a conformant implementation?
How about clause 5.1.2.3/5, which loosely translated states that, when
observing the side-effects of a program, the user may not be able to
tell the difference between execution on the abstract machine and
execution on the actual machine.

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 14 '07 #240
kuyper <ku****@wizard.netwrites:
Rainer Weikusat wrote:
[...]
>This is completely orthogonal to the question what conceivable
behaviour of C-implementations when processing this piece of non-C
could be. And C is again very simple in this respect: Whatever the
behaviour may be, it does not matter. No reason to discuss it.

There are two reasons to discuss it: to answer a question about
whether a given behavior is allowed (when the behavior is undefined,
the answer is always "yes"), and as a didactic tool for impressing
students with just how big a risk they take everytime they execute
code with undefined behavior. Giving humorous and extreme examples is
helpful for making the lesson more memorable, and is technically
correct,
That something weird and presumably dangerous happens if a source file
containing 'character sequences looking like C' which have no defined
behaviour is processed by a conforming C implementation is not
required by the C-standard. Insofar is a lesson trying to establish a
belief like that using sufficently weird make-ups designed to do so
at best useless (student is bright) and at worst bad (student is
stupid and just repeats what he has been told).

I have encountered people who believed exactly that.
Sep 14 '07 #241
Chris Dollin wrote:
>
Kenneth Brody wrote:
Chris Dollin wrote:
[...]
I don't know that it's /infinitely/ many. The universe may be
finite. Even if it isn't, we don't have access to more than
a finite amount of it.

Certainly there are a /great many/ counterexamples.
So you're saying that there is a /finite/ number of counterexamples?

If the accessible universe is finite, yes.
Are you saying that it is, in theory, possible to enumerate them all?

Yes. Enumerate all possible universe states. The number of counterexamples
is no bigger than this.

Oops: I've an implicit assumption that states are discrete.

I /think/ I could weasel that into the finiteness, but I won't.
What if the universe has an inifinite number of possible states?

Yes, there are a finite number of particles in the universe, and
each of them probably has a finite number of states. Unless,
that is, "state" includes "position and velocity". (Unless you
are to argue that there are two non-identical locations where a
particle can be for which there is no location between them.)

So... How does a clc discussion on fgets() turn into a quantum
physics discussion?

[...]

--
+-------------------------+--------------------+-----------------------+
| 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 14 '07 #242
Richard Heathfield wrote:
>
Chris Dollin said:

<snip>

Enumerate all possible universe states.

Where?
What? You don't keep a scratch universe handy?

--
+-------------------------+--------------------+-----------------------+
| 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 14 '07 #243
Francis Glassborow <fr****************@btinternet.comwrites:
Ben Bacarisse wrote:
>>
You can phrased it "your program has no defined meaning" or "the C
standard does not say what this program means/does" or just "this is
UB" and these answers come up all the time in c.l.c.

The meaning of the program is unimportant in this context, its
behaviour is.
Just to clarify. The meaning is the behaviour, but with the all
undetectable variations in behaviour collapsed down into one. The
subtle shift in emphasis when one moves from operational semantics
(describing behaviour) to denotational semantics (ascribing meaning to
program texts) is that one can avoid all the "how" questions.

In C (keep this on topic) the standard describes, in operational
terms, what happens as a program executes. But then, so as not to
constrain implementations has an "as if" rule to allow other behaviour
provided that the result is essentially the same -- i.e. (in
denotation terms) if the meaning is the same.

--
Ben.
Sep 14 '07 #244
"Charlie Gordon" <ne**@chqrlie.orgwrites:
"Ben Bacarisse" <be********@bsb.me.uka écrit dans le message de news:
87************@bsb.me.uk...
>The same argument means the following are UB:

char buf[] = "hello";
strncpy(buf, "j", 5);
buf[1] = 'e';
puts(buf);

Why do you think the above code should invoke UB ?
It should just output j e and a new-line on stdout
Yes of course! Duh!

I was looking for another function that took a "no more than n"
parameter and which does not specify (explicitly) that it does not
write any more location than the minimum required (like fgets in the
discussion). I stupidly switched from strncat to strncpy because I
thought I could make the string cuter! How daft is that? What I
should have given is something like:

char buf[4] = "\0\0c";
strncat(buf, "a", 3);
buf[1] = 'b';
puts(buf);

We all know what should happen, but I can't see how the wording rules
out the same memset(buf, 0, 3) suggested for fgets. Similarly, the
second example should have been:

char buf[2] = "";
strncat(buf, "x", 20);

Given the operational description, only two bytes are written, but the
same goes for fgets -- the standard only states what is read and
written but it does not preclude other modifications.

In my search for examples, I saw that the text for mbstowcs includes
the assurance: "No more than n elements will be modified in the array
pointed to by pwcs" so my hope that I might have missed some blanket
"no function writes to any object unless explicitly stated" seems
unfounded.

Sorry to have messed up this already messy thread with a duff example.

--
Ben.
Sep 14 '07 #245
Francis Glassborow wrote:
>
Ben Bacarisse wrote:

You can phrased it "your program has no defined meaning" or "the C
standard does not say what this program means/does" or just "this is
UB" and these answers come up all the time in c.l.c.

The meaning of the program is unimportant in this context,
its behaviour
is. IOWs what it does matters. The point of UB is that executing a
program with UB can result in anything. The Abstract machine is
irrelevant because the program is no longer C and so is outside the
requirements of the Abstract Machine.
Are you saying that a C program
that contains undefined behavior, is not a C program?
--
pete
Sep 15 '07 #246
Rainer Weikusat wrote, On 14/09/07 18:08:
kuyper <ku****@wizard.netwrites:
>Rainer Weikusat wrote:

[...]
>>This is completely orthogonal to the question what conceivable
behaviour of C-implementations when processing this piece of non-C
could be. And C is again very simple in this respect: Whatever the
behaviour may be, it does not matter. No reason to discuss it.
There are two reasons to discuss it: to answer a question about
whether a given behavior is allowed (when the behavior is undefined,
the answer is always "yes"), and as a didactic tool for impressing
students with just how big a risk they take everytime they execute
code with undefined behavior. Giving humorous and extreme examples is
helpful for making the lesson more memorable, and is technically
correct,

That something weird and presumably dangerous happens if a source file
containing 'character sequences looking like C' which have no defined
behaviour is processed by a conforming C implementation is not
required by the C-standard.
No one has claimed that it is. Only that such behaviour, and other
behaviour which is just plain weird, is *permitted* by the C standard.
Insofar is a lesson trying to establish a
belief like that using sufficently weird make-ups designed to do so
at best useless (student is bright)
A bright student should understand the point. There is even evidence
that bright students *do* understand the point, namely responses to such
messages from said students indicating they have understood it.
and at worst bad (student is
stupid and just repeats what he has been told).

I have encountered people who believed exactly that.
People who cannot understand the concept of undefined behaviour and the
anything, even things they would never imaging, is possible where there
is undefined behaviour should not be programming in C.
--
Flash Gordon
Sep 15 '07 #247
"Ben Bacarisse" <be********@bsb.me.uka écrit dans le message de news:
87************@bsb.me.uk...
"Charlie Gordon" <ne**@chqrlie.orgwrites:
>"Ben Bacarisse" <be********@bsb.me.uka écrit dans le message de news:
87************@bsb.me.uk...
>>The same argument means the following are UB:

char buf[] = "hello";
strncpy(buf, "j", 5);
buf[1] = 'e';
puts(buf);

Why do you think the above code should invoke UB ?
It should just output j e and a new-line on stdout

Yes of course! Duh!

I was looking for another function that took a "no more than n"
parameter and which does not specify (explicitly) that it does not
write any more location than the minimum required (like fgets in the
discussion). I stupidly switched from strncat to strncpy because I
thought I could make the string cuter! How daft is that? What I
should have given is something like:

char buf[4] = "\0\0c";
strncat(buf, "a", 3);
buf[1] = 'b';
puts(buf);

We all know what should happen, but I can't see how the wording rules
out the same memset(buf, 0, 3) suggested for fgets. Similarly, the
second example should have been:

char buf[2] = "";
strncat(buf, "x", 20);

Given the operational description, only two bytes are written, but the
same goes for fgets -- the standard only states what is read and
written but it does not preclude other modifications.
Actually, the wording for strncat is unambiguous about how many characters
can be changed in the destination buffer: .

C99 7.21.3.2p2
The strncat function appends not more than n characters (a null character
and
characters that follow it are not appended) from the array pointed to by s2
to the end of
the string pointed to by s1. The initial character of s2 overwrites the null
character at the
end of s1. A terminating null character is always appended to the
result.264) If copying
takes place between objects that overlap, the behavior is undefined.

264) Thus, the maximum number of characters that can end up in the array
pointed to by s1 is
strlen(s1)+n+1.

The wording is not cristal clear, but s1 is only changed by appending
characters from s2 and the null and following characters are not appended,
and then a (single) terminating null character is always appended.
In my search for examples, I saw that the text for mbstowcs includes
the assurance: "No more than n elements will be modified in the array
pointed to by pwcs" so my hope that I might have missed some blanket
"no function writes to any object unless explicitly stated" seems
unfounded.

Sorry to have messed up this already messy thread with a duff example.
What a great suggestion! Duff's examples would really mess this thread up
beyond repair ;-)

--
Chqrlie.
Sep 15 '07 #248
Rainer Weikusat wrote:
Bart van Ingen Schenau <ba**@ingen.ddns.infowrites:
....
I wasn't talking about code but about the defined meaning of certain
statements. The statement above has no defined meaning. Ergo: Every
claim that its defined meaning would be ... must be wrong.
It has no meaning that is defined by the C standard. The C standard's
statements about such code implicitly allow for the possibilty that
it's meaning might be defined by something other than the C standard,
such as the particular implementation that is used to translate and
execute the code. It could also have behavior that isn't defined by
anything, but just happens without having been defined. It is those
other things we've been talking about. We haven't been talking about
the code have a meaning defined by the C standard itself.

Sep 15 '07 #249
Rainer Weikusat wrote:
kuyper <ku****@wizard.netwrites:
Rainer Weikusat wrote:
....
There are two reasons to discuss it: to answer a question about
whether a given behavior is allowed (when the behavior is undefined,
the answer is always "yes"), and as a didactic tool for impressing
students with just how big a risk they take everytime they execute
code with undefined behavior. Giving humorous and extreme examples is
helpful for making the lesson more memorable, and is technically
correct,

That something weird and presumably dangerous happens if a source file
containing 'character sequences looking like C' which have no defined
behaviour is processed by a conforming C implementation is not
required by the C-standard. ...
That is most certainly true; one of the most frequent mistakes made
with respect to UB is the idea that it's necessarily wierd and
dangerous.
... Insofar is a lesson trying to establish a
belief like that using sufficently weird make-ups designed to do so
at best useless (student is bright) and at worst bad (student is
stupid and just repeats what he has been told).
The syntax of that last sentence is mixed up, so I'm not quite sure
what you're saying, but I think I've got the gist of it. I assume
you're not a native speaker of English, so I'm not criticizing you,
just pointing out the problem. My Spanish is much worse than your
English, and of the five foreign languages I know, Spanish is the one
I'm most fluent in.

Any good teacher should emphasize that UB can include all of the
following (and many other things as well):
1. Wierd and/or seriously dangerous behavior,
2. Behavior that is exactly what you incorrectly assumed the code was
required to have. This is also dangerous, because it hides a code
defect.
3. Useful behavior that could not be achieved by code with standard-
defined behavior. The only way such code could be useful is if
something other than the C standard defines the behavior, for example
the particular implementation that you are using to translate and
execute the code. This can also be dangerous, but is also perfectly
legitimate as long as it's well-understood that this code is not
intended to be portable. Such code should only be written by experts
who have enough experience to know when it's appropriate to write non-
portable code. Newbies should generally avoid writing such code, if
they can.

Sep 15 '07 #250

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.