Velocity Reviews - Computer Hardware Reviews

Velocity Reviews > Newsgroups > Programming > C Programming > Re: Linux X demo

Reply
Thread Tools

Re: Linux X demo

 
 
Keith Thompson
Guest
Posts: n/a
 
      07-22-2007
Herbert Kleebauer <(E-Mail Removed)> writes:
> Keith Thompson wrote:
>> >> >>>case 0x05: {la[--j] = la[j] / la[j+1]; break;}

>
>> The original code exhibits undefined behavior as far as the standard
>> is concerned because it violates the requirement in 6.5p2:
>>
>> Between the previous and next sequence point an object shall have
>> its stored value modified at most once by the evaluation of an
>> expression. Furthermore, the prior value shall be read only to
>> determine the value to be stored.
>>
>> The original expression modifies j and reads the prior value of j for
>> a purpose other than determining the value to be stored.

>
> I know, but the question was, why doesn't the compiler emit an
> error message, when the source code obviously violates a required
> rule: the prior value __SHALL__ be read only to
> determine the value to be stored.


First off, who says it doesn't emit an error message? gcc, with no
options specified, doesn't produce any diagnostics, but with the right
options it prints:

c.c:6: warning: operation on `j' may be undefined

Probably other compilers behave similarly.

Yes, it's a warning, not an error message, but the standard makes no
distinction between different kinds of diagnostics, and as a
programmer you should usually treat both the same way, as an
indication that you need to fix the code.

The rule I quoted does use the word "shall", but it's not part of a
constraint. Any violation of a "shall" requirement outside a
constraint invokes undefined behavior; the standard says so
explicitly. Diagnostics are required for syntax errors and constraint
violations. The code we're discussing is neither.

>> I'm not aware of any C compiler that bothers defines the behavior of
>> this kind of construct.

>
> By generating code for such a construct it DEFINES the behavior of
> the construct.


No, it really doesn't. As pete pointed out, by generating code it
makes absolutely no guarantee that it will generate the same code
again the next time you compile it.

An implementation can define the behavior of some construct (that's
not already defined by the standard) *only* by documenting it. If the
implementation behaves in a certain way but hasn't documented that
behavior, you can't rely on it; the authors can freely change the
behavior in the next release, and quietly break your code. If the
implementation's documentation makes a promise that the compiler fails
to keep, that's a genuine bug, and you should report it.

You *can't* learn the language, or even the charactistics of a
particular implementation, entirely by trial and error.

>> warn about it, though they're not required to. But this:
>>
>> int *p0, *p1;
>> /* ... */
>> *p0 = (*p1)++;
>>
>> invokes behavior *only* if p0==p1 when it's evaluated. There's


Sorry, I meant "invokes undefined behavior".

>> typically no way to determine that kind of thing at compile time (if
>> there were, we wouldn't need to run the program).

>
> That doesn't make any sense. You say, if the compiler processes
> a statement like "i=n/m;" it doesn't know whether the variable m=0 or
> not at run time and therefore has to compile it without an error
> message (which is pretty obvious).


Right.

> But then you make the conclusion
> that it also shouldn't generate an error message for "i=n/0" because
> this is only a special case of the general form "i=n/m" which is
> processed without an error message.


I didn't say that it *shouldn't* generate an error message; I said
that it isn't *required* to do so.

For any case of undefined behavior (n/m, where m might be zero, is a
good example), there will be cases where the compiler potentially can
*know* that it invokes UB:

int n = 1;
const int m = 0;
n/m;

cases where the compiler potentially can know that it doesn't:

int n = /* whatever */;
int m = /* whatever */;
if (m != 0) [
n/m;
}

(Note that since m != 0, n/m can't divide by zero -- but it *can*
overflow if n == INT_MIN, m == -1, and INT_MIN < -INT_MAX.)

and cases where it just can't tell:

int n = atoi(argv[1]);
int m = atoi(argv[2]);
n/m;

If you want to require diagnostics for the "obvious" cases, the
authors of the C standard would have to have defined unambiguously
which cases are "obvious" and which are not. They would have had to
decide how much dataflow analysis to require, among other things. The
amount of such analysis that's practical has varied considerably over
time (the C language, in various forms, is over 30 years old, and
compiler technology has advanced considerably in that time).

So the authors of the standard did the simplest thing they could do:
they didn't require *any* compile-time analysis behond what's required
to process correct programs and issue diagnostics for syntax errors
and constraint violations, and they defined all the actual constraints
so that violations can be detected straightforwardly at compilation
time. Requiring more than that would have (a) placed an additional
burden on compiler writers, (b) made the language definition more
complex and more error-prone (there are already known errors in the
standard; making it more complex would inevitably have caused more
errors, making the standard less reliable and less useful), and (c)
wouldn't completely solve any problem anyway, because there will
*always* be cases that can't be determined during compilation.

*And* they permitted compilers to issue any additional diagnostics
they like, so that a sufficiently clever compiler *can* do whatever
additional analysis is necessary to detect and diagnose more instances
of undefined behavior.

>> You learn about such things by learning the language, which, as it
>> turns out, is not as simple as you seem to think it is.

>
> Especially when the error reporting system of the C compiler
> is buggy and doesn't report code which violates the specification.


The code invokes undefined behavior. It doesn't violate the
specification, it just isn't covered by it. And the authors of the
standard were kind enough to *define* the areas of undefined behavior.

If you want to see what the standard itself actually says, you might
consider downloading
<http://www.open-std.org/jtc1/sc22/wg14/www/docs/n1124.pdf>. It's a
post-C99 version of the standard, incorporating two Technical
Corrigenda. You'll need to be aware that most compilers these days
fully support the C90 standard, but very few fully support C99.

I don't believe that any useful language can entirely avoid these
issues. There are languages that have fewer instances of "undefined
behavior" (or whatever the equivalent term is) than C does. This can
be done by nailing down the behavior of constructs that C leaves
undefined, or by not providing problematic features such as pointer
arithmetic.

--
Keith Thompson (The_Other_Keith) http://www.velocityreviews.com/forums/(E-Mail Removed) <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"
 
Reply With Quote
 
 
 
 
Chris Dollin
Guest
Posts: n/a
 
      07-23-2007
Herbert Kleebauer wrote:

> "J. J. Farrell" wrote:
>> On Jul 21, 5:19 pm, Herbert Kleebauer <(E-Mail Removed)> wrote:

>
>> What's bizarre about it? "proper" in this context means something
>> along the lines of "doing what it's supposed to do". The specification
>> of the C language says that when a compiler comes across invalid code
>> like this it can do whatever it chooses, so whatever the compiler
>> chooses to do is "proper".

>
> Does the specification really say that the compiler can do what ever it
> likes when it is feed with invalid code?


No, it says that the result of executing a construct for which the
behaviour is undefined is completely at the whim of the implementation
(not just the compiler, the entire implementation).

Code that's invalid because of syntax errors or constraint violations
is required to generate a diagnostic. (The compiler is free to abandon
or continue processing; the resulting code can do anything it likes.)

Having the compiler detect all cases of undefined behaviour is
impossible [1], so it would be unreasonable for the standard to require it.
Having the run-time detect all such cases would demand significant
overheads; given the goals of C, it would be unreasonable for the
standard to require it.

Implementations are free to compete on the quality of their non-mandated
diagnostics.

[1] Does `*pointerToInt = someInteger++;` fall prey to undefined behaviour?

--
Chris "actual, not definitional" Dollin

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

 
Reply With Quote
 
 
 
 
Richard Bos
Guest
Posts: n/a
 
      07-23-2007
Herbert Kleebauer <(E-Mail Removed)> wrote:

> "J. J. Farrell" wrote:
> > On Jul 21, 5:19 pm, Herbert Kleebauer <(E-Mail Removed)> wrote:

>
> > What's bizarre about it? "proper" in this context means something
> > along the lines of "doing what it's supposed to do". The specification
> > of the C language says that when a compiler comes across invalid code
> > like this it can do whatever it chooses, so whatever the compiler
> > chooses to do is "proper".

>
> Does the specification really say that the compiler can do what ever it
> likes when it is feed with invalid code? If so, then I would call this
> a bug in the specification. If a compiler is feed with invalid code,
> it has to generate an error message instead of compiling it to some
> freely chosen code.


Please draw up a specification of "invalid code" which does not require
the compiler to solve the Halting Problem.

Richard
 
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
Re: Linux X demo santosh C Programming 8 07-20-2007 09:47 PM
wxPython demo /Process does not open new demo Andy Leszczynski Python 1 02-18-2005 06:03 PM
wxpython demo under linux C GIllespie Python 2 05-12-2004 02:34 PM
PyOpenGL demo in wxPython demo crashes F. GEIGER Python 9 05-03-2004 04:43 PM
UT2004 Demo for Linux, Win and Mac is out... steve NZ Computing 9 02-18-2004 06:16 AM



Advertisments