Re: removing a loop cause it to go at half the speed?



Robin Haigh wrote:
"Chris Dollin" <kers@xxxxxxxxxx> wrote in message
news:dvlt72$hpa$1@xxxxxxxxxxxxxxxxxxxxxxx
Robin Haigh wrote:

Behaviour is only undefined if it's not defined, and defined includes
implementation-defined.
Not as the term is used here, to the best of my knowledge. "Defined"
means "defined by the [relevant] C standard" - defined in such a way
that you can rely on it portably.

I'll agree it's a useful shorthand, but it does tend to lead to people
bandying these terms around without understanding their significance, or
lack of it. People develop concepts that don't apply across the whole set
of possible C programs, but only to the type of thing they're thinking of.

The concepts are also useful because they are well defined by the same standard that defined the C language. If someone doesn't understand them then they should be explained to them.

Lack of undefined behaviour doesn't make a program portable. It's
impossible to avoid implementation dependencies, and once you allow in
literally one bit of implementation dependency, the effect on a program's
behaviour is potentially unbounded. You can only know that code is portable
by looking at all the dependencies and figuring out that they don't make any
difference across the set of platforms that matter.

#include <stdlib.h>
#include <stdio.h>
int main(void)
{
if (puts("Hello world!") >= 0)
return EXIT_SUCCESS;
else
return EXIT_FAILURE;
}

On any hosted implementation it will either output "Hello world!/n" successfully and return a success code to the environment or it will fail and return a failure code. Hardly unbounded.

In that process, if the standard says "undefined" and the relevant platforms
say "defined", you're as well off as if the standard said
"implementation-defined". And conversely, if the standard says
"implementation-defined" but you don't know how some relevant platform might
do that, you're as badly off as if the standard said "undefined".

No, with implementation defined behaviour you know that it *will* be documented on *all* conforming implementations, because part of the definition of "implementation defined" is that the implementation is *required* to document it. If the standard says it is undefined behaviour then even if your implementation defines it you know that you will have to check whether it is documented for *every* system you want to use it on in the future, and you may well come across a system which leaves it completely undefined and possibly even causes random behaviour.

And then there's the question of inputs. Most implementations of the
standard library contain code that produces undefined behaviour, for invalid
arguments.

If you give the functions valid inputs they are *required* to behave in the documented manner. Therefore, to avoid invoking undefined behaviour with the library you just have to write your program properly so that it only passes valid arguments (and avoid things like gets).

> Link with the library and your program has undefined behaviour
in it, from a purely static viewpoint.

I would disagree with that. See my program above which links to the library and clearly does *not* invoke undefined behaviour (subjust to typos and thinkos).

> To know you're ok, you have to know
that the undefined behaviour is guarded, because your running program won't
actually pass invalid arguments in any circumstances.

Or write your program such that it cannot generate invalid arguments in the first place.

> The argument may be
non-trivial and will usually have to involve implementation dependencies
and program inputs. If the logic of your validation of inputs isn't totally
bombproof, for instance, you may think your source is clean code, and
portable,
but you've got unguarded undefined unpredictable behaviour in your
executable
anyway, or you will have on some other platform.

If you accidentally put your car in to reverse when doing 30mph on the road you will wreck your gearbox, does that mean it is not useful to define the behaviour of your car when you don't do that but not define it when you do?

Behaviour only really makes sense in the context of a running executable.
The notion that source code has behaviour, though it seems to be appealing,
just isn't sustainable.

It is perfectly sustainable. Something is either guaranteed to behave in a certain way, or in one of a finite set of ways (sometimes with the choice having to be documented) or it is not. It is *extremely* useful to know whether the behaviour is something where you have a guarantee of the behaviour or not.

In fact one of the sources of bugs is that programmers don't focus on what
platforms they're writing for and just think they'll write portable source,
but then it turns out not to be as portable as they thought.

In those cases the problem is the programmer not understanding what *is* portable, and that IMHO is a very strong argument for letting people know whether things are guaranteed by the standard (defined behaviour), whether the standard guarantees that the behaviour will be documented by the implementation (implementation defined), one of a number of specified options but not documented which one (unspecified behaviour) or one where the C standard places no requirements (undefined behaviour).

You know at one extreme if you stick to defined behaviour you will always get a well defined result and if you invoke undefined behaviour that unless you can find some other documentation for *every* platform of interest that specifies it then all bets are off.

> Portability doesn't come that easy.

Portability is not always easy or possible, but the starting point is knowing what the C standard guarantees and what it doesn't. If you start by making as much of the code as possible defined by the C standard then you are minimising how much work you have to do when porting to a new implementation, and remember that a new version of Windows or Linux or your compiler (or even a service pack) might (and in the past has) changed the behaviour of things not defined by the C standard.
--
Flash Gordon, living in interesting times.
Web site - http://home.flash-gordon.me.uk/
comp.lang.c posting guidelines and intro:
http://clc-wiki.net/wiki/Intro_to_clc
.



Relevant Pages

  • Re: <ctype.h> toLower()
    ... See the C Standard. ... >> tolower() is implemented. ... >> platform, without even having to know which character set is used on that ... is, however, an error in portability for me to *call* that macro. ...
    (alt.comp.lang.learn.c-cpp)
  • Re: interesting use of NEXT SENTENCE vs. CONTINUE
    ... > implementations that purport to conform to a COBOL standard is to write ... I DID think any old compiler would be able to ... compile it WITH MINOR MODIFICATIONS for a specific platform. ... >> Portability depends on where you plan to port (or more likely where ...
    (comp.lang.cobol)
  • Re: C portability is a myth
    ... Of course it was the C standard itself which was ... I did not even think about portability. ... platform, all compliant with the exact same version of the ANSI C ... its a limiting factor on availability. ...
    (comp.lang.c)
  • Re: C portability is a myth
    ... Of course it was the C standard itself which was ... I did not even think about portability. ... >> other C compilers that follow the standard. ... > to the portability is going to be the capabilities of that platform. ...
    (comp.lang.c)
  • Re: removing a loop cause it to go at half the speed?
    ... Lack of undefined behaviour doesn't make a program portable. ... if the standard says "undefined" and the relevant platforms ... Portability ...
    (comp.lang.c)