Topic: psychic compilers (was 2 questions about Visual C++ vs. standard)
Author: Bennett McElwee <bmcelwee@my-deja.com>
Date: 1999/12/21 Raw View
David R Tribble <david@tribble.com> wrote:
> Christian Bau wrote:
> > > volatile int x;
> > > int* p = NULL;
> > >
> > > void myfunction (void)
> > > {
> > > printf ("I am going to invoke undefined behavior!!!\n");
> > > x = 0; x = 1; x = 2;
> > > p = NULL; *p = 0; /* undefined behavior!!! */
> > > }
> > >
> > > the compiler can safely assume that myfunction () is never called,
> > > and since it is never called, it might as well remove all the code
> > > inside its body. So when you call it, it will not print, and it
> > > will not store to a volatile variable.
>
> It can do this only if myfunction() is static. GCC, in fact, does
> this sort of optimization (uncalled leaf functions) if you ask for
> it.
No, it can do it in any case. There are two possibilities for
any program using this function:
(1) The program does not attempt to call the function.
- In this case, the compiler can remove the function's body.
(2) The program attempts to call the function at some point.
- In this case the program's behaviour is undefined. Since it
is undefined, the compiler can produce any code it likes; in
particular, it can remove the function's body.
Note that the function is removed by the compiler, not the linker.
Also note that the compiler can remove the function regardless of
whether it is able to determine if the function is called. (As you
point out, it can't in this case because it is not static).
Finally, I suppose that most compilers would in fact generate code
for the function. Many real programs contains bugs that would cause
undefined behaviour; a decent compiler would at least try to do
something reasonable (like cause a page fault in the above function).
> One particular optimization that drives us nuts is the AIX C++
> compiler which eliminates unreferenced static const variables,
> which is conforming behavior, but which makes it difficult to
> embed SCCS "what" / RCS "ident" strings within our object code:
>
> static const char id[] = "@(#)$Header$";
> // removed by some compilers!
Would declaring it volatile help?
Cheerio,
Bennett.
--
-- Bennett.McElwee rbs.co.uk I reserve the right --
-- @ to be wrong. --
Sent via Deja.com http://www.deja.com/
Before you buy.
[ comp.std.c++ is moderated. To submit articles, try just posting with ]
[ your news-reader. If that fails, use mailto:std-c++@ncar.ucar.edu ]
[ --- Please see the FAQ before posting. --- ]
[ FAQ: http://reality.sgi.com/austern_mti/std-c++/faq.html ]
Author: James Kuyper <kuyper@wizard.net>
Date: 1999/12/22 Raw View
Harvey Taylor wrote:
>
> James Kuyper wrote:
> > Harvey Taylor wrote:
> > > James Kuyper wrote:
....
> Whoa now, wait a minute. In fact the compiler treated the Page
> Fault generating "out of MMU mapped" address precisely the same as
> it would a valid address. I could modify the MMU map and the
> code would execute without a Page Fault.
You could? Using strictly conforming C code? Whatever you do to modify
the MMU map is outside the domain of the C standard; it necessarily
can't define what will happen as a result. That's what "undefined
behavior" means.
---
[ comp.std.c++ is moderated. To submit articles, try just posting with ]
[ your news-reader. If that fails, use mailto:std-c++@ncar.ucar.edu ]
[ --- Please see the FAQ before posting. --- ]
[ FAQ: http://reality.sgi.com/austern_mti/std-c++/faq.html ]
Author: James Kuyper <kuyper@wizard.net>
Date: 1999/12/22 Raw View
David R Tribble wrote:
>
> Christian Bau wrote:
> > > volatile int x;
> > > int* p = NULL;
> > >
> > > void myfunction (void)
> > > {
> > > printf ("I am going to invoke undefined behavior!!!\n");
> > > x = 0; x = 1; x = 2;
> > > p = NULL; *p = 0; /* undefined behavior!!! */
> > > }
> > >
> > > the compiler can safely assume that myfunction () is never called,
> > > and since it is never called, it might as well remove all the code
> > > inside its body. So when you call it, it will not print, and it
> > > will not store to a volatile variable.
>
> It can do this only if myfunction() is static. ...
Why? Executing the function is guaranteed to allow undefined behavior -
the compiler can do anything it wants.
---
[ comp.std.c++ is moderated. To submit articles, try just posting with ]
[ your news-reader. If that fails, use mailto:std-c++@ncar.ucar.edu ]
[ --- Please see the FAQ before posting. --- ]
[ FAQ: http://reality.sgi.com/austern_mti/std-c++/faq.html ]
Author: "Anders J. Munch" <andersjm@dancontrol.dk>
Date: 1999/12/22 Raw View
Michiel Salters wrote in message <3858E1D1.EE97BEB9@lucent.com>...
>"Anders J. Munch" wrote:
>> int x; volatile int y; int z;
>> x *= 2; ++y; z = 10/x;
>
>> A compiler might decide for efficiency to execute ++y last [...]
>What is a volatile variable?
>
>It is a message to the compiler that reads and writes are observable, and
>that it cannot and should not reorder code that changes reads/writes to
>them. The compiler is only allowed to change the order of code if it is
>covered by the as-if rule, and certainly, this doesn't apply to the
>example you suggested.
If executing ++y last changed the order of observable side-effects, you
would be right. But it doesn't: assuming no undefined behaviour, ++y is
the *only* observable side-effect in this snippet. If either x or z were
volatile it would be a different matter.
- Anders
---
[ comp.std.c++ is moderated. To submit articles, try just posting with ]
[ your news-reader. If that fails, use mailto:std-c++@ncar.ucar.edu ]
[ --- Please see the FAQ before posting. --- ]
[ FAQ: http://reality.sgi.com/austern_mti/std-c++/faq.html ]
Author: Michiel Salters <salters@lucent.com>
Date: 1999/12/22 Raw View
David R Tribble wrote:
> Christian Bau wrote:
> > > volatile int x;
> > > int* p = NULL;
> > > void myfunction (void)
> > > {
> > > printf ("I am going to invoke undefined behavior!!!\n");
> > > x = 0; x = 1; x = 2;
> > > p = NULL; *p = 0; /* undefined behavior!!! */
> > > }
> > > the compiler can safely assume that myfunction () is never called,
> > > and since it is never called, it might as well remove all the code
> > > inside its body. So when you call it, it will not print, and it
> > > will not store to a volatile variable.
> It can do this only if myfunction() is static. GCC, in fact, does
> this sort of optimization (uncalled leaf functions) if you ask for
> it.
No, it can do it always. Calling the function results in undefined
behavior, so any program that calls this function is illegal.
There is no requirement placed on the compiler with regard to
the production of illegal programs, so removing it is allowed.
No legal program can detect it it missing, after all (since they
can't call it.)
I doubt if gcc can determine if all paths through a function will
lead to undefined behavior. I even doubt it can do so in the
case there is only one path, given some comments in this
group recently (about compiling int a[1/0];)
> Harvey Taylor wrote:
> > If anything like this were to become part of the standard, there
> > would need to be a way to turn it (the compiler behaviour) off.
> > In general, software that doesn't do what you tell it, can be
> > a _real_ pain.
> Yep. The good compilers allow you to enable/disable specific
> optimizations.
> One particular optimization that drives us nuts is the AIX C++
> compiler which eliminates unreferenced static const variables,
> which is conforming behavior, but which makes it difficult to
> embed SCCS "what" / RCS "ident" strings within our object code:
> // foo.cpp
> static const char id[] = "@(#)$Header$";
> // removed by some compilers!
This is a bit standard, but I have no idea in which FAQ this should
be:
if (argc==1 && strcmp(argv[1],"-version") std::cout << id;
No way any compiler will drop id. (Ok, so your GUI defines
argc=0. Add a messagebox using `id'.)
Michiel Salters
---
[ comp.std.c++ is moderated. To submit articles, try just posting with ]
[ your news-reader. If that fails, use mailto:std-c++@ncar.ucar.edu ]
[ --- Please see the FAQ before posting. --- ]
[ FAQ: http://reality.sgi.com/austern_mti/std-c++/faq.html ]
Author: "Kelsey Bjarnason" <kelseyb@no.spam.telus.net>
Date: 1999/12/22 Raw View
[snips]
"David R Tribble" <david@tribble.com> wrote in message
news:38592F0B.CFD3D4CB@tribble.com...
> One particular optimization that drives us nuts is the AIX C++
> compiler which eliminates unreferenced static const variables,
> which is conforming behavior, but which makes it difficult to
> embed SCCS "what" / RCS "ident" strings within our object code:
>
> // foo.cpp
>
> static const char id[] = "@(#)$Header$";
> // removed by some compilers!
> ...
Okay, maybe I'm missing something, but... who cares? It wouldn't be removed
if your code were accessing it, you're presumably checking in/out your
source, not the objects, so of the two places it might matter, it is
relevant to neither.
---
[ comp.std.c++ is moderated. To submit articles, try just posting with ]
[ your news-reader. If that fails, use mailto:std-c++@ncar.ucar.edu ]
[ --- Please see the FAQ before posting. --- ]
[ FAQ: http://reality.sgi.com/austern_mti/std-c++/faq.html ]
Author: James Kuyper <kuyper@wizard.net>
Date: 1999/12/22 Raw View
Kelsey Bjarnason wrote:
>
> [snips]
>
> "David R Tribble" <david@tribble.com> wrote in message
> news:38592F0B.CFD3D4CB@tribble.com...
>
> > One particular optimization that drives us nuts is the AIX C++
> > compiler which eliminates unreferenced static const variables,
> > which is conforming behavior, but which makes it difficult to
> > embed SCCS "what" / RCS "ident" strings within our object code:
> >
> > // foo.cpp
> >
> > static const char id[] = "@(#)$Header$";
> > // removed by some compilers!
> > ...
>
> Okay, maybe I'm missing something, but... who cares? It wouldn't be removed
> if your code were accessing it, you're presumably checking in/out your
> source, not the objects, so of the two places it might matter, it is
> relevant to neither.
The purpose is to allow examination of object files, to determine which
version of the source was used to create them. If the version string is
dropped, that doesn't work.
[ comp.std.c++ is moderated. To submit articles, try just posting with ]
[ your news-reader. If that fails, use mailto:std-c++@ncar.ucar.edu ]
[ --- Please see the FAQ before posting. --- ]
[ FAQ: http://reality.sgi.com/austern_mti/std-c++/faq.html ]
Author: Hyman Rosen <hymie@prolifics.com>
Date: 1999/12/22 Raw View
"Kelsey Bjarnason" <kelseyb@no.spam.telus.net> writes:
> Okay, maybe I'm missing something, but... who cares? It wouldn't be removed
> if your code were accessing it, you're presumably checking in/out your
> source, not the objects, so of the two places it might matter, it is
> relevant to neither.
The purpose of this construct is to embed an identifiable string within the
object code. Then utilities can scan an executable for copies of this string
and determine what version of each source file is used.
Many compilers provide some local way of doing such embedding, generally
placing the string into a special section of the executable which doesn't
get loaded at all at runtime.
In our source code, we do the equivalent of the following:
#define SCCS_ID "%W% %E% %U%"
#include "sccs_id.h"
The included file uses #ifdef to pick out what system it's running on,
and then issues the appropriate utterance within that section. It looks
something like this:
#ifndef SCCS_ID_H
#define SCCS_ID_H
#ifdef SCCS_ID
#if defined(COMPILER_A)
#pragma comment(SCCS_ID)
#endif
#if defined(COMPILER_B)
static char sccs_id[] = SCCS_ID;
#endif
#if defined(COMPILER_C)
static char sccs_id[] = SCCS_ID "\n";
#endif
#endif /* SCCS_ID */
#endif /* SCCS_ID_H */
[ comp.std.c++ is moderated. To submit articles, try just posting with ]
[ your news-reader. If that fails, use mailto:std-c++@ncar.ucar.edu ]
[ --- Please see the FAQ before posting. --- ]
[ FAQ: http://reality.sgi.com/austern_mti/std-c++/faq.html ]
Author: James Kuyper <kuyper@wizard.net>
Date: 1999/12/23 Raw View
Harvey Taylor wrote:
>
> James Kuyper wrote:
> > Harvey Taylor wrote:
> > > James Kuyper wrote:
> > ...
> > > [...]
> > > I'm glad the compiler writers did not opt for the legalistic
> > > solution.
> >
> > But they did. "Undefined behavior" includes generation of a Page Fault;
> > if it weren't for the legalese that allows for undefined behavior in
> > this case, the compiler would be required to prevent the Page Fault you
> > were trying to generate.
> >
>
> Whoa now, wait a minute. In fact the compiler treated the Page
> Fault generating "out of MMU mapped" address precisely the same as
> it would a valid address. I could modify the MMU map and the
> code would execute without a Page Fault.
>
> This would indicate to me that the 1.9 text is more of a CYA
> [cover thine posterior] clause than anything else.
My apologies - I didn't read your message correctly. I saw the words
"Page Fault", but read them as "memory violation", which is what would
happen on writing through a null pointer on any machine I've ever used
that had any kind of decent memory protection. I've never used one where
the effect would be as mild as causing a page fault. I actually do know
what a page fault is; I just read what I was expecting, instead of
what's actually there :-{.
The section 1.9 text is needed to cover the segment violation I would
get; you're correct in stating that it's not needed to cover the Page
Fault that you were deliberately triggering, since that causes no
behavior that matters from the point of view of the standard.
---
[ comp.std.c++ is moderated. To submit articles, try just posting with ]
[ your news-reader. If that fails, use mailto:std-c++@ncar.ucar.edu ]
[ --- Please see the FAQ before posting. --- ]
[ FAQ: http://reality.sgi.com/austern_mti/std-c++/faq.html ]
Author: Jim Hyslop <jim.hyslop@leitch.com>
Date: 1999/12/23 Raw View
In article <Y3O54.195$486.381@news.get2net.dk>,
"Anders J. Munch" <andersjm@dancontrol.dk> wrote:
>
> Hyman Rosen wrote in message ...
> >Nevertheless, since program execution follows the abstract machine
> >model, the standard *could* have specified that all effects before
> >the undefined operation occurs must happen properly.
The Standard requires side effects to be resolved at each sequence
point. So it boils down to whether or not there is a sequence point
between the undefined operation and the "all effects" you refer to.
> It could have, but it wouldn't be a good idea. Example:
>
> int x;
> volatile int y;
> int z;
> ....
> x *= 2;
> ++y;
> z = 10/x;
>
> A compiler might decide for efficiency to execute ++y last (say
> because x
> is already in register, no sense in throwing it out just to reload
> later),
No, it cannot do that. Incrementing y is a side effect. As I said
above, the standard requires all side effects to be complete at sequence
points (1.9/7). 1.9/11 states "At sequence points, volatile objects
are stable in the sense that previous evaluations are complete and
subsequent evaluations have not yet occurred." There is a sequence
point at the end of a full expression (i.e. a semi-colon)(1.9/16).
Therefore, the compiler *MUST* evaluate ++y, including its side effects,
after the statement 'x*=2;' and before the statement 'z = 10/x;' The
compiler could, of course, tuck the results of 'x*=2;' into a register,
and for the last statement use the register value instead of
re-fetching the value of x from memory. But it still must execute '++y'
before evaluating z.
> and should be allowed to do so. If the standard had a requirement as
> you
> suggest, this reordering would not be allowed,
[snip]
As I have shown, the Standard does in fact have such a requirement.
--
Jim
I ignore all email from recruitment agencies.
Please do not send me email with questions - post
here.
Sent via Deja.com http://www.deja.com/
Before you buy.
---
[ comp.std.c++ is moderated. To submit articles, try just posting with ]
[ your news-reader. If that fails, use mailto:std-c++@ncar.ucar.edu ]
[ --- Please see the FAQ before posting. --- ]
[ FAQ: http://reality.sgi.com/austern_mti/std-c++/faq.html ]
Author: "Anders J. Munch" <andersjm@post.tele.dk>
Date: 1999/12/23 Raw View
Jim Hyslop wrote in message <83r9a7$35f$1@nnrp1.deja.com>...
>In article <Y3O54.195$486.381@news.get2net.dk>,
> "Anders J. Munch" <andersjm@dancontrol.dk> wrote:
>> int x; volatile int y; int z;
>> ....
>> x *= 2; ++y; z = 10/x;
>>
>> A compiler might decide for efficiency to execute ++y last [...]
>No, it cannot do that. Incrementing y is a side effect. As I said
>above, the standard requires all side effects to be complete at sequence
>points (1.9/7). 1.9/11 states "At sequence points, volatile objects
>are stable in the sense that previous evaluations are complete and
>subsequent evaluations have not yet occurred." There is a sequence
>point at the end of a full expression (i.e. a semi-colon)(1.9/16).
++y is an _observable_ side effect. The assignments to x and z are _not_
observable side effects. They are side effects of the abstract machine,
but no implementation is required to mimic the abstract machine when it
comes to anything but _observable_ behaviour (see 1.9/1 and 1.9/5). The
paragraphs you refer to describe the abstract machine. Not the
requirements on an implementation.
- Anders
---
[ comp.std.c++ is moderated. To submit articles, try just posting with ]
[ your news-reader. If that fails, use mailto:std-c++@ncar.ucar.edu ]
[ --- Please see the FAQ before posting. --- ]
[ FAQ: http://reality.sgi.com/austern_mti/std-c++/faq.html ]
Author: Harvey Taylor <het@despam.pangea.ca>
Date: 1999/12/17 Raw View
James Kuyper wrote:
> Harvey Taylor wrote:
>> Christian Bau wrote:
>>> volatile int x;
>>> int* p =3D NULL;
>>>
>>> void myfunction (void)
>>> {
>>> printf ("I am going to invoke undefined behavior!!!\n");
>>> x =3D 0; x =3D 1; x =3D 2;
>>> p =3D NULL; *p =3D 0; /* undefined behavior!!! */
>>> }
>>>
>>> the compiler can safely assume that myfunction () is never called, and
>>> since it is never called, it might as well remove all the code inside its
>>> body. So when you call it, it will not print, and it will not store to a
>>> volatile variable.
>>>
>> If anything like this were to become part of the standard, there
>> would need to be a way to turn it (the compiler behaviour) off.
>
> It's already part of the standard. It has been for as long as there's
> been a standard. It was there in the original C standard which is
> referenced by the C++ standard. Examine the description of undefined
> behavior.
>
Well, well. That is interesting.
I just had occasion to write a function to deliberately write
through a NULL pointer and a function to deliberately trigger
a Page Fault as part of a system monitor testing package.
The code worked to generate run time faults as I intended
(which the system monitor then caught).
However looking at the FDIS 1.9, I see what you mean.
I'm glad the compiler writers did not opt for the legalistic
solution.
>> In general, software that doesn't do what you tell it, can be
>> a _real_ pain.
> But it did do what you told it to do. When you write code that allows
> undefined behavior, you are, in effect, telling the compiler to "do
> whatever you want, including not compiling this, so long as you issue at
> least one diagnostic if you don't compile it". Now, if that's not what
> you wanted to tell it, you should remove the code which allows undefined
> behavior.
>
While this is within the letter of the standard it seems to me
essentially sterile. If myfunction() from Christian's were
elided from the object file, I would be looking for compiler
switches or writing it in inline assembly.
<cordially>
-het
--
"The road to wisdom?
Well it's plain and simple to express:
Err and err and err again,
but less and less and less." -Piet Hein
Harvey Taylor Internet: het@despam.portal.ca
[ comp.std.c++ is moderated. To submit articles, try just posting with ]
[ your news-reader. If that fails, use mailto:std-c++@ncar.ucar.edu ]
[ --- Please see the FAQ before posting. --- ]
[ FAQ: http://reality.sgi.com/austern_mti/std-c++/faq.html ]
Author: James Kuyper <kuyper@wizard.net>
Date: 1999/12/17 Raw View
Harvey Taylor wrote:
> James Kuyper wrote:
...
> Well, well. That is interesting.
> I just had occasion to write a function to deliberately write
> through a NULL pointer and a function to deliberately trigger
> a Page Fault as part of a system monitor testing package.
>
> The code worked to generate run time faults as I intended
> (which the system monitor then caught).
> However looking at the FDIS 1.9, I see what you mean.
> I'm glad the compiler writers did not opt for the legalistic
> solution.
But they did. "Undefined behavior" includes generation of a Page Fault;
if it weren't for the legalese that allows for undefined behavior in
this case, the compiler would be required to prevent the Page Fault you
were trying to generate. One way to do that would be for the compiler to
insert code before every use of a pointer, to validate the address
stored in the pointer, and not use it if doing so would produce a Page
Fault.
...
> > But it did do what you told it to do. When you write code that allows
> > undefined behavior, you are, in effect, telling the compiler to "do
> > whatever you want, including not compiling this, so long as you issue at
> > least one diagnostic if you don't compile it". Now, if that's not what
> > you wanted to tell it, you should remove the code which allows undefined
> > behavior.
> >
> While this is within the letter of the standard it seems to me
> essentially sterile. If myfunction() from Christian's were
> elided from the object file, I would be looking for compiler
> switches or writing it in inline assembly.
That's exactly as it should be - attempting to write through a null
pointer!? A null pointer is guaranteed to not be a pointer to any real
C++ object. There's no way within C++ to have any idea what it does
point at, if anything. There's quite a few implementations where that
would fail radically - either because null pointers don't point at any
real memory, or because the memory they would otherwise be pointing at
is protected against access. Whatever the reason is that you want to
write through a null pointer, is extremely system-specific, and it's
entirely appropriate to have to rely on implementation-specific compiler
features to achieve it.
[ comp.std.c++ is moderated. To submit articles, try just posting with ]
[ your news-reader. If that fails, use mailto:std-c++@ncar.ucar.edu ]
[ --- Please see the FAQ before posting. --- ]
[ FAQ: http://reality.sgi.com/austern_mti/std-c++/faq.html ]
Author: Michiel Salters <salters@lucent.com>
Date: 1999/12/20 Raw View
"Anders J. Munch" wrote:
> Hyman Rosen wrote in message ...
> >Nevertheless, since program execution follows the abstract machine
> >model, the standard *could* have specified that all effects before
> >the undefined operation occurs must happen properly.
> It could have, but it wouldn't be a good idea. Example:
> int x;
> volatile int y;
> int z;
> ....
> x *= 2;
> ++y;
> z = 10/x;
> A compiler might decide for efficiency to execute ++y last (say because x
> is already in register, no sense in throwing it out just to reload later),
> and should be allowed to do so. If the standard had a requirement as you
> suggest, this reordering would not be allowed, because a divide by zero
> might hinder the increment of y. The performance penalty for this kind of
> situations might not be so bad in itself, but to have to avoid this kind
> of problems would make it somewhat harder to write an optimizing compiler.
What is a volatile variable?
It is a message to the compiler that reads and writes are observable, and
that it cannot and should not reorder code that changes reads/writes to
them. The compiler is only allowed to change the order of code if it is
covered by the as-if rule, and certainly, this doesn't apply to the
example you suggested.
Volatiles are made to improve the possibilities of an optimizing compiler;
it can safely assume that all other variables can be aggressively
optimized.
Michiel Salters
---
[ comp.std.c++ is moderated. To submit articles, try just posting with ]
[ your news-reader. If that fails, use mailto:std-c++@ncar.ucar.edu ]
[ --- Please see the FAQ before posting. --- ]
[ FAQ: http://reality.sgi.com/austern_mti/std-c++/faq.html ]
Author: David R Tribble <david@tribble.com>
Date: 1999/12/20 Raw View
Christian Bau wrote:
> > volatile int x;
> > int* p = NULL;
> >
> > void myfunction (void)
> > {
> > printf ("I am going to invoke undefined behavior!!!\n");
> > x = 0; x = 1; x = 2;
> > p = NULL; *p = 0; /* undefined behavior!!! */
> > }
> >
> > the compiler can safely assume that myfunction () is never called,
> > and since it is never called, it might as well remove all the code
> > inside its body. So when you call it, it will not print, and it
> > will not store to a volatile variable.
It can do this only if myfunction() is static. GCC, in fact, does
this sort of optimization (uncalled leaf functions) if you ask for
it.
Harvey Taylor wrote:
> If anything like this were to become part of the standard, there
> would need to be a way to turn it (the compiler behaviour) off.
> In general, software that doesn't do what you tell it, can be
> a _real_ pain.
Yep. The good compilers allow you to enable/disable specific
optimizations.
One particular optimization that drives us nuts is the AIX C++
compiler which eliminates unreferenced static const variables,
which is conforming behavior, but which makes it difficult to
embed SCCS "what" / RCS "ident" strings within our object code:
// foo.cpp
static const char id[] = "@(#)$Header$";
// removed by some compilers!
...
-- David R. Tribble, david@tribble.com, http://david.tribble.com --
---
[ comp.std.c++ is moderated. To submit articles, try just posting with ]
[ your news-reader. If that fails, use mailto:std-c++@ncar.ucar.edu ]
[ --- Please see the FAQ before posting. --- ]
[ FAQ: http://reality.sgi.com/austern_mti/std-c++/faq.html ]
Author: Harvey Taylor <het@despam.pangea.ca>
Date: 1999/12/20 Raw View
James Kuyper wrote:
> Harvey Taylor wrote:
> > James Kuyper wrote:
> ...
> > [...]
> > I'm glad the compiler writers did not opt for the legalistic
> > solution.
>
> But they did. "Undefined behavior" includes generation of a Page Fault;
> if it weren't for the legalese that allows for undefined behavior in
> this case, the compiler would be required to prevent the Page Fault you
> were trying to generate.
>
Whoa now, wait a minute. In fact the compiler treated the Page
Fault generating "out of MMU mapped" address precisely the same as
it would a valid address. I could modify the MMU map and the
code would execute without a Page Fault.
This would indicate to me that the 1.9 text is more of a CYA
[cover thine posterior] clause than anything else.
> [...] There's quite a few implementations where that
> would fail radically - either because null pointers don't point at any
> real memory, or because the memory they would otherwise be pointing at
> is protected against access. Whatever the reason is that you want to
> write through a null pointer, is extremely system-specific, and it's
> entirely appropriate to have to rely on implementation-specific compiler
> features to achieve it.
> Yes, I would be happy to have a run time exception on the NULL
pointer write, rather than an unexplained crash some time later.
I was a bit surprised when I discovered VxWorks allowed such
access without a peep.
<cordially>
-het
--
"Long after we are gone, our voices will linger in these nets."
- paraphrasing G'Kar
Harvey Taylor Internet: het@despam.portal.ca
---
[ comp.std.c++ is moderated. To submit articles, try just posting with ]
[ your news-reader. If that fails, use mailto:std-c++@ncar.ucar.edu ]
[ --- Please see the FAQ before posting. --- ]
[ FAQ: http://reality.sgi.com/austern_mti/std-c++/faq.html ]
Author: christian.bau@isltd.insignia.com (Christian Bau)
Date: 1999/12/20 Raw View
In article <3859BE12.7772@despam.pangea.ca>, Harvey Taylor
<het@despam.pangea.ca> wrote:
> James Kuyper wrote:
> >>> volatile int x;
> >>> int* p =3D NULL;
> >>>
> >>> void myfunction (void)
> >>> {
> >>> printf ("I am going to invoke undefined behavior!!!\n");
> >>> x =3D 0; x =3D 1; x =3D 2;
> >>> p =3D NULL; *p =3D 0; /* undefined behavior!!! */
> >>> }
> >>>
> >>> the compiler can safely assume that myfunction () is never called, and
> >>> since it is never called, it might as well remove all the code inside its
> >>> body. So when you call it, it will not print, and it will not store to a
> >>> volatile variable.
>
> Well, well. That is interesting.
> I just had occasion to write a function to deliberately write
> through a NULL pointer and a function to deliberately trigger
> a Page Fault as part of a system monitor testing package.
>
> The code worked to generate run time faults as I intended
> (which the system monitor then caught).
> However looking at the FDIS 1.9, I see what you mean.
> I'm glad the compiler writers did not opt for the legalistic
> solution.
Doesn't work with a Borland 16 bit compiler. I could imagine that very
interesting things will happen on a highly optimising compiler for Merced.
And since technology is making progress, and there is now a programming
language where writing through a null pointer is required to throw an
exception, I could make a guess that ten years from now you won't get a
page fault on many systems. Looks to me like you should write code like
this in assembler.
And how much shipping code is compiled with all compiler optimisations
switched off because it contains some undefined behavior that only shows
up when optimisations are switched on?
---
[ comp.std.c++ is moderated. To submit articles, try just posting with ]
[ your news-reader. If that fails, use mailto:std-c++@ncar.ucar.edu ]
[ --- Please see the FAQ before posting. --- ]
[ FAQ: http://reality.sgi.com/austern_mti/std-c++/faq.html ]
Author: Francis Glassborow <francis@robinton.demon.co.uk>
Date: 1999/12/20 Raw View
In article <christian.bau-2012991019400001@christian-
mac.isltd.insignia.com>, Christian Bau <christian.bau@isltd.insignia.com
> writes
>And how much shipping code is compiled with all compiler optimisations
>switched off because it contains some undefined behavior that only shows
>up when optimisations are switched on?
Hm... I always thought the problem was that optimisers got it wrong (I
can remember a C compiler that used to issue 'Unsafe optimisation'
warnings:)
Francis Glassborow Journal Editor, Association of C & C++ Users
64 Southfield Rd
Oxford OX4 1PA +44(0)1865 246490
All opinions are mine and do not represent those of any organisation
[ comp.std.c++ is moderated. To submit articles, try just posting with ]
[ your news-reader. If that fails, use mailto:std-c++@ncar.ucar.edu ]
[ --- Please see the FAQ before posting. --- ]
[ FAQ: http://reality.sgi.com/austern_mti/std-c++/faq.html ]
Author: Hyman Rosen <hymie@prolifics.com>
Date: 1999/12/13 Raw View
jbarfurth@vossnet.de (Joerg Barfurth) writes:
> Which program ? The compiler need not even translate this program into
> an executable.
Well, I finally went and read the Standard myself. It says in 1.9,
However, if any such execution sequence contains an undefined
operation, this International Standard places no requirement
on the implementation executing that program with that input
(not even with regard to operations preceding the first
undefined operation).
This answers my question completely.
[ comp.std.c++ is moderated. To submit articles, try just posting with ]
[ your news-reader. If that fails, use mailto:std-c++@ncar.ucar.edu ]
[ --- Please see the FAQ before posting. --- ]
[ FAQ: http://reality.sgi.com/austern_mti/std-c++/faq.html ]
Author: Hyman Rosen <hymie@prolifics.com>
Date: 1999/12/14 Raw View
kanze@gabi-soft.de writes:
> Independantly of the problem of going back in time, there is (generally)
> nothing that a program can do that cannot be undone. If your output is
> to a screen, the undefined behavior could backspace over it and rewrite
> it. If your output is to a file, the undefined behavior can delete the
> file, and replace it with something else.
>
> About the only place I see an eventual question is if the program
> outputs, then flushes, a value, and then sleeps or delays enough for the
> value to be really observed before the undefined behavior occurs.
Well the standard says that if a program will execute an undefined
operation upon being presented a certain input sequence, there are
no requirements at all for that execution, even for actions before
the undefined operation is executed.
Nevertheless, since program execution follows the abstract machine
model, the standard *could* have specified that all effects before
the undefined operation occurs must happen properly.
---
[ comp.std.c++ is moderated. To submit articles, try just posting with ]
[ your news-reader. If that fails, use mailto:std-c++@ncar.ucar.edu ]
[ --- Please see the FAQ before posting. --- ]
[ FAQ: http://reality.sgi.com/austern_mti/std-c++/faq.html ]
Author: kanze@gabi-soft.de
Date: 1999/12/14 Raw View
Hyman Rosen <hymie@prolifics.com> writes:
|> kanze@gabi-soft.de writes:
|> > Independantly of the problem of going back in time, there is (generally)
|> > nothing that a program can do that cannot be undone. If your output is
|> > to a screen, the undefined behavior could backspace over it and rewrite
|> > it. If your output is to a file, the undefined behavior can delete the
|> > file, and replace it with something else.
|> > About the only place I see an eventual question is if the program
|> > outputs, then flushes, a value, and then sleeps or delays enough for the
|> > value to be really observed before the undefined behavior occurs.
|> Well the standard says that if a program will execute an undefined
|> operation upon being presented a certain input sequence, there are
|> no requirements at all for that execution, even for actions before
|> the undefined operation is executed.
|> Nevertheless, since program execution follows the abstract machine
|> model, the standard *could* have specified that all effects before
|> the undefined operation occurs must happen properly.
It could have, but could a conforming program tell?
--
James Kanze mailto:James.Kanze@gabi-soft.de
Conseils en informatique orient e objet/
Beratung in objekt orientierter Datenverarbeitung
Ziegelh ttenweg 17a, 60598 Frankfurt, Germany Tel. +49(069)63198627
[ comp.std.c++ is moderated. To submit articles, try just posting with ]
[ your news-reader. If that fails, use mailto:std-c++@ncar.ucar.edu ]
[ --- Please see the FAQ before posting. --- ]
[ FAQ: http://reality.sgi.com/austern_mti/std-c++/faq.html ]
Author: "Anders J. Munch" <andersjm@dancontrol.dk>
Date: 1999/12/15 Raw View
Hyman Rosen wrote in message ...
>Nevertheless, since program execution follows the abstract machine
>model, the standard *could* have specified that all effects before
>the undefined operation occurs must happen properly.
It could have, but it wouldn't be a good idea. Example:
int x;
volatile int y;
int z;
....
x *= 2;
++y;
z = 10/x;
A compiler might decide for efficiency to execute ++y last (say because x
is already in register, no sense in throwing it out just to reload later),
and should be allowed to do so. If the standard had a requirement as you
suggest, this reordering would not be allowed, because a divide by zero
might hinder the increment of y. The performance penalty for this kind of
situations might not be so bad in itself, but to have to avoid this kind
of problems would make it somewhat harder to write an optimizing compiler.
- Anders
[ comp.std.c++ is moderated. To submit articles, try just posting with ]
[ your news-reader. If that fails, use mailto:std-c++@ncar.ucar.edu ]
[ --- Please see the FAQ before posting. --- ]
[ FAQ: http://reality.sgi.com/austern_mti/std-c++/faq.html ]
Author: "Anders J. Munch" <andersjm@dancontrol.dk>
Date: 1999/12/15 Raw View
kanze@gabi-soft.de wrote in message <863dt51bzh.fsf@gabi-soft.de>...
>
>Hyman Rosen <hymie@prolifics.com> writes:
>|> Nevertheless, since program execution follows the abstract machine
>|> model, the standard *could* have specified that all effects before
>|> the undefined operation occurs must happen properly.
>
>It could have, but could a conforming program tell?
The user of a conforming implementation could tell!
- Anders
[ comp.std.c++ is moderated. To submit articles, try just posting with ]
[ your news-reader. If that fails, use mailto:std-c++@ncar.ucar.edu ]
[ --- Please see the FAQ before posting. --- ]
[ FAQ: http://reality.sgi.com/austern_mti/std-c++/faq.html ]
Author: Harvey Taylor <het@despam.pangea.ca>
Date: 1999/12/15 Raw View
Christian Bau wrote:
> volatile int x;
> int* p = NULL;
>
> void myfunction (void)
> {
> printf ("I am going to invoke undefined behavior!!!\n");
> x = 0; x = 1; x = 2;
> p = NULL; *p = 0; /* undefined behavior!!! */
> }
>
> the compiler can safely assume that myfunction () is never called, and
> since it is never called, it might as well remove all the code inside its
> body. So when you call it, it will not print, and it will not store to a
> volatile variable.
>
If anything like this were to become part of the standard, there
would need to be a way to turn it (the compiler behaviour) off.
In general, software that doesn't do what you tell it, can be
a _real_ pain.
<l8r>
-het
--
"The road to wisdom?
Well it s plain and simple to express:
Err and err and err again,
but less and less and less." -Piet Hein
Harvey Taylor Internet: het@despam.portal.ca
[ comp.std.c++ is moderated. To submit articles, try just posting with ]
[ your news-reader. If that fails, use mailto:std-c++@ncar.ucar.edu ]
[ --- Please see the FAQ before posting. --- ]
[ FAQ: http://reality.sgi.com/austern_mti/std-c++/faq.html ]
Author: James Kuyper <kuyper@wizard.net>
Date: 1999/12/16 Raw View
Harvey Taylor wrote:
>
> Christian Bau wrote:
> > volatile int x;
> > int* p = NULL;
> >
> > void myfunction (void)
> > {
> > printf ("I am going to invoke undefined behavior!!!\n");
> > x = 0; x = 1; x = 2;
> > p = NULL; *p = 0; /* undefined behavior!!! */
> > }
> >
> > the compiler can safely assume that myfunction () is never called, and
> > since it is never called, it might as well remove all the code inside its
> > body. So when you call it, it will not print, and it will not store to a
> > volatile variable.
> >
>
> If anything like this were to become part of the standard, there
> would need to be a way to turn it (the compiler behaviour) off.
It's already part of the standard. It has been for as long as there's
been a standard. It was there in the original C standard which is
referenced by the C++ standard. Examine the description of undefined
behavior.
> In general, software that doesn't do what you tell it, can be
> a _real_ pain.
But it did do what you told it to do. When you write code that allows
undefined behavior, you are, in effect, telling the compiler to "do
whatever you want, including not compiling this, so long as you issue at
least one diagnostic if you don't compile it". Now, if that's not what
you wanted to tell it, you should remove the code which allows undefined
behavior.
[ comp.std.c++ is moderated. To submit articles, try just posting with ]
[ your news-reader. If that fails, use mailto:std-c++@ncar.ucar.edu ]
[ --- Please see the FAQ before posting. --- ]
[ FAQ: http://reality.sgi.com/austern_mti/std-c++/faq.html ]
Author: jcoffin@taeus.com (Jerry Coffin)
Date: 1999/12/11 Raw View
In article <38510FD7.7138AEA3@lucent.com>, salters@lucent.com says...
[ ... ]
> I'm wondering about this. All modifications to volatiles and all flushed
> ouput must be observable at a sequence point. If we then read an integer
> and divide 1 by the read integer, we could invoke undefined behavior,
> but I don't think this can alter our observations.
It does seem difficult to conceive of a way to make this happen,
doesn't it? I should probably take a look back through the stuff from
the C committee to see how it was worded (and if, indeed, my memory is
correct at all). Unfortunately, I've just received a phone call
saying that my boss just got taken to the hospital with a possible
heart attack, so quickly finishing this message may be the last I get
to think on the subject for a bit...
> (Spiking the coffee machine with LSD is one form of undefined behavior
> which might alter our observations, however :-)
Your observations maybe, but not mine (he types, after putting down
his mug of hot chocolate...)
--
Later,
Jerry.
The universe is a figment of its own imagination.
---
[ comp.std.c++ is moderated. To submit articles, try just posting with ]
[ your news-reader. If that fails, use mailto:std-c++@ncar.ucar.edu ]
[ --- Please see the FAQ before posting. --- ]
[ FAQ: http://reality.sgi.com/austern_mti/std-c++/faq.html ]
Author: Hyman Rosen <hymie@prolifics.com>
Date: 1999/12/11 Raw View
Barry Margolin <barmar@bbnplanet.com> writes:
> Fundamental laws of the universe, such as causality, take precedence over
> anything in the standard.
That's not what I asked about. If the compiler can prove that a
program will at some point execute undefined behavior, must the
program it generates nevertheless cause all side effects that
occur ahead of the undefined behavior to actually happen, or is
the behavior of the program as a whole completely undefined.
Here's an example -
#include <iostream>
int main()
{
int i = 6;
do { cout << 120 / i << endl; } while (i-- > 0);
}
It is easy to see that division by zero must occur whenever this
program runs. Must the program print "20\n24\n30\n40\n60\n120\n"
or not?
---
[ comp.std.c++ is moderated. To submit articles, try just posting with ]
[ your news-reader. If that fails, use mailto:std-c++@ncar.ucar.edu ]
[ --- Please see the FAQ before posting. --- ]
[ FAQ: http://reality.sgi.com/austern_mti/std-c++/faq.html ]
Author: jbarfurth@vossnet.de (Joerg Barfurth)
Date: 1999/12/12 Raw View
Hyman Rosen <hymie@prolifics.com> wrote:
> That's not what I asked about. If the compiler can prove that a
> program will at some point execute undefined behavior, must the
> program it generates nevertheless cause all side effects that
> occur ahead of the undefined behavior to actually happen, or is
> the behavior of the program as a whole completely undefined.
>
> Here's an example -
>
> #include <iostream>
> int main()
> {
> int i = 6;
> do { cout << 120 / i << endl; } while (i-- > 0);
> }
>
> It is easy to see that division by zero must occur whenever this
> program runs. Must the program print "20\n24\n30\n40\n60\n120\n"
> or not?
> ---
Which program ? The compiler need not even translate this program into
an executable.
E.g. there might be an optimizing compiler that unrolls the loop,
statically evaluating the divisions. It might then issue a diagnostic
("Zero-divide in expression") and terminate translation.
If instead of int main() the same body was used for an ordinary function
the compiler might replace calls to that function with a call to
lauch_nuclear_missiles().
If the compiler cannot determine whether this piece of code will be
executed, it might still emit a warning.
I'd expect any real compiler to either reject the program with a
diagnostic as shown, provide a warning stating what will happen (e.g.
that the entire loop will not be executed) or produce an executable that
in fact prints the expected output before the error occurs.
But strictly speaking that is a QOI issue.
-- J rg Barfurth
[ comp.std.c++ is moderated. To submit articles, try just posting with ]
[ your news-reader. If that fails, use mailto:std-c++@ncar.ucar.edu ]
[ --- Please see the FAQ before posting. --- ]
[ FAQ: http://reality.sgi.com/austern_mti/std-c++/faq.html ]
Author: christian.bau@isltd.insignia.com (Christian Bau)
Date: 1999/12/13 Raw View
In article <kRb44.47$c72.3599@burlma1-snr2>, Barry Margolin
<barmar@bbnplanet.com> wrote:
> In article <38510FD7.7138AEA3@lucent.com>,
> Michiel Salters <salters@lucent.com> wrote:
> >
> >Jerry Coffin wrote:
> >> I'm not sure this has ever been addressed specifically WRT C++, but
> >> IIRC, there was an official clarification (or perhaps a DR) from the C
> >> committee that said, in essence, that if the program executed any code
> >> with undefined behavior, then the behavior of the program as a whole
> >> was undefined.
> >
> >I'm wondering about this. All modifications to volatiles and all flushed
> >ouput must be observable at a sequence point. If we then read an integer
> >and divide 1 by the read integer, we could invoke undefined behavior,
> >but I don't think this can alter our observations.
>
> Fundamental laws of the universe, such as causality, take precedence over
> anything in the standard.
However, a compiler can always make the assumption that your code does not
invoke undefined behavior. For example, it may assume you don't write to a
null pointer. So if you write
volatile int x;
int* p = NULL;
void myfunction (void)
{
printf ("I am going to invoke undefined behavior!!!\n");
x = 0; x = 1; x = 2;
p = NULL; *p = 0; /* undefined behavior!!! */
}
the compiler can safely assume that myfunction () is never called, and
since it is never called, it might as well remove all the code inside its
body. So when you call it, it will not print, and it will not store to a
volatile variable.
[ comp.std.c++ is moderated. To submit articles, try just posting with ]
[ your news-reader. If that fails, use mailto:std-c++@ncar.ucar.edu ]
[ --- Please see the FAQ before posting. --- ]
[ FAQ: http://reality.sgi.com/austern_mti/std-c++/faq.html ]
Author: kanze@gabi-soft.de
Date: 1999/12/13 Raw View
Hyman Rosen <hymie@prolifics.com> writes:
|> Barry Margolin <barmar@bbnplanet.com> writes:
|> > Fundamental laws of the universe, such as causality, take precedence over
|> > anything in the standard.
|> That's not what I asked about. If the compiler can prove that a
|> program will at some point execute undefined behavior, must the
|> program it generates nevertheless cause all side effects that
|> occur ahead of the undefined behavior to actually happen, or is
|> the behavior of the program as a whole completely undefined.
|> Here's an example -
|> #include <iostream>
|> int main()
|> {
|> int i = 6;
|> do { cout << 120 / i << endl; } while (i-- > 0);
|> }
|> It is easy to see that division by zero must occur whenever this
|> program runs. Must the program print "20\n24\n30\n40\n60\n120\n"
|> or not?
No.
Independantly of the problem of going back in time, there is (generally)
nothing that a program can do that cannot be undone. If your output is
to a screen, the undefined behavior could backspace over it and rewrite
it. If your output is to a file, the undefined behavior can delete the
file, and replace it with something else.
About the only place I see an eventual question is if the program
outputs, then flushes, a value, and then sleeps or delays enough for the
value to be really observed before the undefined behavior occurs.
--
James Kanze mailto:James.Kanze@gabi-soft.de
Conseils en informatique orient e objet/
Beratung in objekt orientierter Datenverarbeitung
Ziegelh ttenweg 17a, 60598 Frankfurt, Germany Tel. +49(069)63198627
[ comp.std.c++ is moderated. To submit articles, try just posting with ]
[ your news-reader. If that fails, use mailto:std-c++@ncar.ucar.edu ]
[ --- Please see the FAQ before posting. --- ]
[ FAQ: http://reality.sgi.com/austern_mti/std-c++/faq.html ]
Author: Michiel Salters <salters@lucent.com>
Date: 1999/12/10 Raw View
Jerry Coffin wrote:
> In article <t71z8x6pbf.fsf@calumny.jyacc.com>, hymie@prolifics.com
> says...
> > That actually raises an interesting question. Can undefined behavior
> > reach backward in time? That is, suppose that I can prove that my
> > program will cause a sequence of legal side effects, but then always
> > execute some undefined behavior. Must the compiler ensure that the
> > legal side effects happen, or is the prospect of eventual undefinedness
> > enough to allow the program to do undefined things immediately?
> I'm not sure this has ever been addressed specifically WRT C++, but
> IIRC, there was an official clarification (or perhaps a DR) from the C
> committee that said, in essence, that if the program executed any code
> with undefined behavior, then the behavior of the program as a whole
> was undefined.
I'm wondering about this. All modifications to volatiles and all flushed
ouput must be observable at a sequence point. If we then read an integer
and divide 1 by the read integer, we could invoke undefined behavior,
but I don't think this can alter our observations.
(Spiking the coffee machine with LSD is one form of undefined behavior
which might alter our observations, however :-)
The OP mentioned "prospect of undefined behavior"; if a program reads
an integer from a file and divides 1 by it, is that a prospect?
Michiel Salters
[ comp.std.c++ is moderated. To submit articles, try just posting with ]
[ your news-reader. If that fails, use mailto:std-c++@ncar.ucar.edu ]
[ --- Please see the FAQ before posting. --- ]
[ FAQ: http://reality.sgi.com/austern_mti/std-c++/faq.html ]
Author: Barry Margolin <barmar@bbnplanet.com>
Date: 1999/12/10 Raw View
In article <38510FD7.7138AEA3@lucent.com>,
Michiel Salters <salters@lucent.com> wrote:
>
>Jerry Coffin wrote:
>> I'm not sure this has ever been addressed specifically WRT C++, but
>> IIRC, there was an official clarification (or perhaps a DR) from the C
>> committee that said, in essence, that if the program executed any code
>> with undefined behavior, then the behavior of the program as a whole
>> was undefined.
>
>I'm wondering about this. All modifications to volatiles and all flushed
>ouput must be observable at a sequence point. If we then read an integer
>and divide 1 by the read integer, we could invoke undefined behavior,
>but I don't think this can alter our observations.
Fundamental laws of the universe, such as causality, take precedence over
anything in the standard.
--
Barry Margolin, barmar@bbnplanet.com
GTE Internetworking, Powered by BBN, Burlington, MA
*** DON'T SEND TECHNICAL QUESTIONS DIRECTLY TO ME, post them to newsgroups.
Please DON'T copy followups to me -- I'll assume it wasn't posted to the group.
[ comp.std.c++ is moderated. To submit articles, try just posting with ]
[ your news-reader. If that fails, use mailto:std-c++@ncar.ucar.edu ]
[ --- Please see the FAQ before posting. --- ]
[ FAQ: http://reality.sgi.com/austern_mti/std-c++/faq.html ]