Velocity Reviews - Computer Hardware Reviews

Velocity Reviews > Newsgroups > Programming > C++ > Knowing the implementation, are all undefined behaviours become implementation-defined behaviours?

Reply
Thread Tools

Knowing the implementation, are all undefined behaviours become implementation-defined behaviours?

 
 
Michael Tsang
Guest
Posts: n/a
 
      02-14-2010
-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA1

Deferencing a NULL pointer is undefined behaviour, but, on Linux, the
program crashes with SIGSEGV. So, the behaviour of derefencing a NULL
pointer is defined to "crash the program with SIGSEGV".

Signed integer overflow is undefined behaviour, but, on x86 CPUs, the number
simply wrap around so we can say that the behaviour is defined to round on
x86 CPUs.
-----BEGIN PGP SIGNATURE-----
Version: GnuPG v1.4.9 (GNU/Linux)

iEYEARECAAYFAkt3kjsACgkQm4klUUKw07D7QwCfQH0jkVFEDA QMi9+t31JiQ449
4QMAn2M+QxWW3yf4WShHgmWjBCluBvun
=e8V1
-----END PGP SIGNATURE-----

 
Reply With Quote
 
 
 
 
Alf P. Steinbach
Guest
Posts: n/a
 
      02-14-2010
* Michael Tsang:
> -----BEGIN PGP SIGNED MESSAGE-----
> Hash: SHA1
>
> Deferencing a NULL pointer is undefined behaviour, but, on Linux, the
> program crashes with SIGSEGV. So, the behaviour of derefencing a NULL
> pointer is defined to "crash the program with SIGSEGV".
>
> Signed integer overflow is undefined behaviour, but, on x86 CPUs, the number
> simply wrap around so we can say that the behaviour is defined to round on
> x86 CPUs.
> -----BEGIN PGP SIGNATURE-----
> Version: GnuPG v1.4.9 (GNU/Linux)
>
> iEYEARECAAYFAkt3kjsACgkQm4klUUKw07D7QwCfQH0jkVFEDA QMi9+t31JiQ449
> 4QMAn2M+QxWW3yf4WShHgmWjBCluBvun
> =e8V1
> -----END PGP SIGNATURE-----
>


Your question, from the subject line, is

"Knowing the implementation, are all undefined behaviours become
implementation-defined behaviours?"

And it's cross-posted to [comp.lang.c] and [comp.lang.c++].

At least for C++ the answer is a definite maybe: theoretically it depends on the
implementation.

In practice the answer is a more clear "no", because it's practically impossible
for an implementation to clearly define all behaviors, in particular pointer
operations and use of external libraries.



Cheers & hth.,

- Alf
 
Reply With Quote
 
 
 
 
Seebs
Guest
Posts: n/a
 
      02-14-2010
On 2010-02-14, Michael Tsang <> wrote:
> Deferencing a NULL pointer is undefined behaviour, but, on Linux, the
> program crashes with SIGSEGV. So, the behaviour of derefencing a NULL
> pointer is defined to "crash the program with SIGSEGV".


Not necessarily.

> Signed integer overflow is undefined behaviour, but, on x86 CPUs, the number
> simply wrap around so we can say that the behaviour is defined to round on
> x86 CPUs.


That's not rounding, that's wrapping.

But no, it's not the case. These are not necessarily *defined* -- they may
merely be typical side-effects that are not guaranteed or supported.

Modern gcc can do some VERY strange things if you write code which might
dereference a null pointer. (For instance, loops which check whether a
pointer is null may have the test removed because, if it were null, it
would have invoked undefined behavior to dereference it...)

-s
--
Copyright 2010, all wrongs reversed. Peter Seebach / usenet-
http://www.seebs.net/log/ <-- lawsuits, religion, and funny pictures
http://en.wikipedia.org/wiki/Fair_Game_(Scientology) <-- get educated!
 
Reply With Quote
 
Malcolm McLean
Guest
Posts: n/a
 
      02-14-2010
On Feb 14, 8:03*am, Michael Tsang <mikl...@gmail.com> wrote:
>

"Undefined behaviour" doesn't mean "exists in some metaphysical state
of indefiniteness" but "the C standard imposes no requirements on the
program's behaviour (and therefore the program is incorrect)". There
was a huge thread about this a few years back on gets.

So typically derefencing null will have the same effect each time any
particular program is run, probably the same effect on any particular
platform. Derefencing a wild pointer may have different effects,
particularly on a multi-taskign machine where exact pointer vlaues
vary from runto run.

 
Reply With Quote
 
Robert Fendt
Guest
Posts: n/a
 
      02-14-2010
And thus spake Seebs <usenet->
14 Feb 2010 07:03:57 GMT:

> dereference a null pointer. (For instance, loops which check whether a
> pointer is null may have the test removed because, if it were null, it
> would have invoked undefined behavior to dereference it...)


Sorry to interrupt, but since when is checking a pointer value
for 0 the same as deferencing it? Checking a pointer treats the
pointer itself as a value, and comparison against 0 is one of
the few things that are _guaranteed_ to work with a pointer
value. So if GCC really would remove a check of the form

if(!pointer)
do_something(*pointer);

or even

if(pointer == 0)
throw NullPointerException;

then GCC would be very much in violation of the standard. And
produce absolutely useless code, as well. What's the point of
having pointers in a language if you wouldn't even be able to
perform basic operations on them?

Regards,
Robert

 
Reply With Quote
 
Alf P. Steinbach
Guest
Posts: n/a
 
      02-14-2010
* Richard Heathfield:
> Michael Tsang wrote:
>> Deferencing a NULL pointer is undefined behaviour, but, on Linux, the
>> program crashes with SIGSEGV. So, the behaviour of derefencing a NULL
>> pointer is defined to "crash the program with SIGSEGV".

>
> Thread's subject line: Knowing the implementation, are all undefined
> behaviours become implementation-defined behaviours?
>
> No. For example, consider a stack exploit on gets(). There are systems
> on which the behaviour could be absolutely anything at all, depending on
> user input!6\b$10be5c39no carrier





Cheers,

- Alf
 
Reply With Quote
 
Bo Persson
Guest
Posts: n/a
 
      02-14-2010
Robert Fendt wrote:
> And thus spake Seebs <usenet->
> 14 Feb 2010 07:03:57 GMT:
>
>> dereference a null pointer. (For instance, loops which check
>> whether a pointer is null may have the test removed because, if it
>> were null, it would have invoked undefined behavior to dereference
>> it...)

>
> Sorry to interrupt, but since when is checking a pointer value
> for 0 the same as deferencing it? Checking a pointer treats the
> pointer itself as a value, and comparison against 0 is one of
> the few things that are _guaranteed_ to work with a pointer
> value. So if GCC really would remove a check of the form
>
> if(!pointer)
> do_something(*pointer);
>
> or even
>
> if(pointer == 0)
> throw NullPointerException;
>
> then GCC would be very much in violation of the standard. And
> produce absolutely useless code, as well. What's the point of
> having pointers in a language if you wouldn't even be able to
> perform basic operations on them?
>


Yes, but there are cases where the compiler can determine that the
pointer is ALWAYS null or not-null, and remove code that would execute
otherwise. For example:

*pointer = 42;
if(pointer == 0)
throw NullPointerException;

is known never to throw the exception!


Bo Persson




 
Reply With Quote
 
Richard Tobin
Guest
Posts: n/a
 
      02-14-2010
In article <853c9a09-8911-48c5-ba74->,
Malcolm McLean <> wrote:

>Derefencing a wild pointer may have different effects,
>particularly on a multi-taskign machine where exact pointer vlaues
>vary from runto run.


It's not a general characteristic of multi-tasking systems that
pointer values vary from run to run. Virtual memory has traditionally
been used to give all instances of a program indistinguishable address
spaces, and addresses will usually be the same.

Recently for security reasons some operating systems have started to
deliberately randomise the locations of, for example, shared
libraries, so pointers are now more likely to vary. (Fortunately this
can usually be disabled for debugging.)

-- Richard
--
Please remember to mention me / in tapes you leave behind.
 
Reply With Quote
 
Robert Fendt
Guest
Posts: n/a
 
      02-14-2010
And thus spake "Bo Persson" <>
Sun, 14 Feb 2010 11:24:48 +0100:

> Yes, but there are cases where the compiler can determine that the
> pointer is ALWAYS null or not-null, and remove code that would execute
> otherwise. For example:
>
> *pointer = 42;
> if(pointer == 0)
> throw NullPointerException;
>
> is known never to throw the exception!


Yes, that's static optimisation. Nothing wrong with that.
However, the posting I was commenting explicitely described
something different:

>> dereference a null pointer. (For instance, loops which check
>> whether a pointer is null may have the test removed because, if it
>> were null, it would have invoked undefined behavior to dereference
>> it...)


This would mean nothing else than the compiler removing
nullpointer checks solely on the grounds that a nullpointer
cannot be de-referenced legally. So the compiler would see a
pointer dereference, and decide "then it can't be null anyway,
since it's used later". And that's just bull, sorry.

Yes, if there's an unconditional pointer dereference and
_afterwards_ a check for null, the compiler could take this as a
hint that said pointer has been checked for null before the first
dereference and thus remove the superfluous check. So if you had
something like this:

MyType& obj = *pointer;
if (!pointer)
threw NullPointerException;

Since the dereference happens _before_ the check, the program
has already entered the domain of undefined behaviour, and the
check is moot (even if one has not 'used' the object reference
in any other way). If the author of the previous posting meant
that, then I agree (though I have doubts whether GCC really
optimises this agressively). But in that case his comment was at
least not very clear.

Regards,
Robert

 
Reply With Quote
 
Ben Bacarisse
Guest
Posts: n/a
 
      02-14-2010
Robert Fendt <> writes:
<snip>
> Yes, if there's an unconditional pointer dereference and
> _afterwards_ a check for null, the compiler could take this as a
> hint that said pointer has been checked for null before the first
> dereference and thus remove the superfluous check. So if you had
> something like this:
>
> MyType& obj = *pointer;
> if (!pointer)
> threw NullPointerException;
>
> Since the dereference happens _before_ the check, the program
> has already entered the domain of undefined behaviour, and the
> check is moot (even if one has not 'used' the object reference
> in any other way). If the author of the previous posting meant
> that, then I agree (though I have doubts whether GCC really
> optimises this agressively).


gcc does exactly that (with certain options). I think this is the
nature a recent Linux kernel bug: http://lkml.org/lkml/2009/7/6/19

The pointer use was ever so slightly less obvious but it led gcc to
conclude that the following test could be removed.

Given the cross-post, I should say that I have no idea if gcc does
this for the exact case you cite (which is C++) but I wanted to point
out that similar things are done.

<snip>
--
Ben.
 
Reply With Quote
 
 
 
Reply

Thread Tools

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

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


Similar Threads
Thread Thread Starter Forum Replies Last Post
Become The master in computer hardware to become successfull shilla Computer Security 1 01-22-2011 06:19 PM
Become The master in computer hardware to become successfull shilla VHDL 0 01-22-2011 04:45 AM
Knowing the implementation, are all undefined behaviours become implementation-defined behaviours? Michael Tsang C Programming 54 03-30-2010 07:46 AM
same code, different providers => different behaviours?? Bart ASP .Net 2 03-22-2007 10:25 AM
"Interesting" C behaviours Rennie deGraaf C Programming 6 11-28-2004 09:27 AM



Advertisments