C the complete nonsense

S

Seebs

I see it now, thanks. I also note that the old page now has a disclaimer
section, as spinoza1111 demanded. In my first skimming of the new page,
I didn't see any credit for my supportive work, and was prepared to
deliver a scathing attack. Now I'm glad I resisted until a slightly
deeper skim, as it's clearly there. I'd hate to look the fool, making
unfounded accusations.

If you wish to be credited as something other than "some random guy on
Usenet", let me know. :)

-s
 
A

Alexander Bartolich

Seebs said:
[...]
The key is that, in an expression, a function yields a value of its
return type.

I would like to contribute to this game of finding the smallest nit.
*Calling* a function yields a value of its return type. The function
name itself (without the function call operator) yields a pointer to
the function.

--
 
B

blmblm

spinoza1111 said:
On 2010-04-06, Richard Heathfield <[email protected]> wrote:

[ snip ]


Flipped around a bit, found a new example. 4th edition, page 264:
#define MAX_SIZE 100
/* ... */
float balance[MAX_SIZE];
/* ... */
for(i=0; i<MAX_SIZE; i++) printf("%f", balance);
/* ... */
for(i=0; i<MAX_SIZE; i++) x =+ balance;

The reader is encouraged to try to spot errors. I only found two; can
you do better?
(1) You added some special invisible non graphic characters to make
the example not compile with several errors, or those characters were
added by the browser in a way that I have not seen occur before.

Strange. The copy of Seeb's post delivered to me by the news server
I use contained no such characters,


Given that the example was apparently as shown in a book I doubt there
were nonprintable characters.


What does that have to do with whether there were nonprintable
characters in Seebs's post? I can't think of a mechanism for copying
text from a paper book to a Usenet post that doesn't have at least
the potential for introducing changes.
My guess is that Edward Nilges was
making a joke or that he was guessing.

The former seems unlikely. He does say things that he apparently
intends to be amusing, but this one doesn't seem like his style,
to me anyway. I could be wrong. I think my proposed explanation --
Google doing something strange with the part of the post meant
to represent code -- is more likely.

[ snip ]
 
B

blmblm

[ snip ]
The "language definition" as found in the standards cannot be used to
write compilers

So the existence of compilers that claim to be standard-compliant ....

Eh, why bother.
or even understand how to use C (Seebach's code is
exhibit A). They fail to define significant semantics, because by the
time they were drafted, there existed several incompatible
implementations, and the standards writers appear to have no mandate
to make these compilers incompatible with a standard.

The only way to square this circle was to create a non-deterministic
semantics, in which (to take only one simple example) the programmer
cannot code a(b=0, b) and expect in all cases that the values of the
formal parameters will both be zero.

In this code

#include "stdio.h"
#define MAX_SIZE 100
void b(int c, int d)
{
printf("%d %d",c,d);
}
int main()
{

int e = 4;
b(e = 0, e);
return 0;

}

my Microsoft C++ express compiler in C mode prints 0 0, but I'm not
"supposed" to expect this because in "standard" C the order of
evaluation has been "defined" as nondeterministic.

But if the order of evaluation is nondeterministic, this means that a
truly conformant compiler would have to use a random number generator
to generate code for matching formal and actual parameters.

I don't think that's what nondeterminism means in context; I think
that instead it means that any choice is valid. I could be wrong,
and would welcome correction *by someone else*.

[ snip ]
You have never made this case, because you can only criticise his lack
of conformance to Linux and his "failure" to tell his readers about
nondeterministic operations...information which is useless on a
specific compiler and platform which works deterministically.

But extremely useful if one wants to write portable code.

[ snip ]
 
J

James Harris

[ snip ]
Flipped around a bit, found a new example.  4th edition, page 264:
        #define MAX_SIZE 100
        /* ... */
        float balance[MAX_SIZE];
        /* ... */
        for(i=0; i<MAX_SIZE; i++) printf("%f", balance);
        /* ... */
        for(i=0; i<MAX_SIZE; i++) x =+ balance;
The reader is encouraged to try to spot errors.  I only found two; can
you do better?
(1) You added some special invisible non graphic characters to make
the example not compile with several errors, or those characters were
added by the browser in a way that I have not seen occur before.
Strange.  The copy of Seeb's post delivered to me by the news server
I use contained no such characters,

Given that the example was apparently as shown in a book I doubt there
were nonprintable characters.

What does that have to do with whether there were nonprintable
characters in Seebs's post?  I can't think of a mechanism for copying
text from a paper book to a Usenet post that doesn't have at least
the potential for introducing changes.


I suppose it depends on what we are looking for. I took it that Seebs
was asking us to say what was wrong with the code that he found in the
book. Nilges possibly thought we were supposed to copy and paste it
but that's surprising since being only an outline of code it was a
long way from being compilable.
The former seems unlikely.  He does say things that he apparently
intends to be amusing, but this one doesn't seem like his style,
to me anyway.  I could be wrong.  I think my proposed explanation --
Google doing something strange with the part of the post meant
to represent code -- is more likely.

I'd assumed Nilges knew more about C than that but you may be right.

James
 
B

Ben Bacarisse

spinoza1111 <[email protected]> wrote:

I don't think that's what nondeterminism means in context; I think
that instead it means that any choice is valid.

I don't think it matters. spinoza1111 is wrong to say that the standard
defines the order to be non-deterministic. If it did, you would be
right that we would have to find out how the standard defines
non-deterministic (since are at least a couple of common meanings in
CS). But it does not. It says the order is unspecified and it even
says what that means.
I could be wrong,
and would welcome correction *by someone else*.

You are only wrong in that non-determinism is irrelevant. The meaning
of what the standard actually says is as you describe it -- any choice
of order is valid (within the limits imposed elsewhere by the standard,
of course).

<snip>
 
T

Tim Rentsch

Right, "any choice", with the understanding that "any choice"
means any choice not otherwise disallowed by the Standard.
For example, the assignment 'e = 0' could not be done after
the function call but must be done before. The term used
in the Standard is 'unspecified behavior'.

(Incidentally, the example function call above is actually
undefined behavior because the assignment to 'e' and the
read access of 'e' are unsequenced relative to each other,
but that doesn't change what the rules are about evaluation
order.)

AFAIK the standards do not use the term "nondeterministic" - the
correct phrase is "implementation defined" which is something
quite different. [snip elaboration]

Actually it's unspecifed behavior, not implementation-defined
behavior. The difference is, with implmentation-defined
behavior, each implmentation must document which choice(s)
it makes; with unspecified behavior, the same set of choices
is available, but implementations need not document which
choice(s) they make in these cases.

In short, the C standards are incomplete; they do not completely
specify the interpretation of code.

It is complete in this area. The Standard says specifically
that order of evaluation is "unspecified", meaning any ordering
that doesn't violate any other stated requirements is allowed.
One way to look at it is that
the standards specify C as a family of languages, differing by
implementation defined rules.

Certainly that is one way to look at it. A better way (IMO) to
look at it, at least as regards evaluation order, is that C
is a single language with a non-deterministic semantics. One
reason for this is that an implementation need not make the
same choice about evaluation order from one expression to the
next, or even the same on the next compilation as this one.
And for evaluation order in particular, implementations are
under no obligation to describe or document what rules they
use to determine ordering in any particular circumstance.
 
S

Seebs

Seebs said:
[...]
The key is that, in an expression, a function yields a value of its
return type.
I would like to contribute to this game of finding the smallest nit.
*Calling* a function yields a value of its return type. The function
name itself (without the function call operator) yields a pointer to
the function.

Right you are. My sentence, as written, was indeed incorrect. Good
catch!

(This kind of thing, by the way, is why people writing about C usually
*need* technical reviews and errata.)

-s
 
S

Seebs

I don't think that's what nondeterminism means in context; I think
that instead it means that any choice is valid. I could be wrong,
and would welcome correction *by someone else*.

No, Nilges is wrong. The behavior is descriptively nondeterministic,
not prescriptively nondeterministic.

You aren't required to behave surprisingly, merely allowed to, in such
cases. When the standard says that behavior on overflow is "undefined",
it doesn't mean that you are *required* to do something abnormal; you're
quite welcome to just wrap around on signed integers, if that's what you
want.

All they've said is that they have not defined an outcome -- meaning anything
is permissible, not that nothing is permissible.

Actually, I should qualify my statement. "Nilges has said something untrue."
I have at this time no reason to believe he actually believes it, so it
may be that he is right but lying.

-s
 
S

Seebs

AFAIK the standards do not use the term "nondeterministic" - the
correct phrase is "implementation defined" which is something
quite different.

It's "unspecified", in general, but in the case Nilges showed, it's
actually "undefined".

You can easily create an example which is merely unspecified and does
not invoke undefined behavior, in which case, any outcome is indeed
permitted -- that doesn't mean that you are required to do surprising
stuff.
In short, the C standards are incomplete; they do not completely
specify the interpretation of code. One way to look at it is that
the standards specify C as a family of languages, differing by
implementation defined rules.

As well as by regions that are simply not defined at all.

-s
 
M

Malcolm McLean

All they've said is that they have not defined an outcome -- meaning
anything is permissible, not that nothing is permissible.
Usually when the program is permitted to exit with an error message,
it is said that the behaviour is "undefined". This is to keep the
distinction that programs with implementation-defined behaviour are
(or can be) correct, programs with undefined behaviour are incorrect.
 
S

Seebs

Usually when the program is permitted to exit with an error message,
it is said that the behaviour is "undefined". This is to keep the
distinction that programs with implementation-defined behaviour are
(or can be) correct, programs with undefined behaviour are incorrect.

The obvious exception would be abort(). :)

But yes, I think that's a pretty good summary. Undefined behavior
means you no longer have a reasonable expectation of *any behavior
at all*, let alone expected behavior. By contrast, unspecified
behavior means you are guaranteed to get some result, but no one
will tell you what. Implementation defined behavior means that,
if you look in the compiler documentation, you can find out exactly
what behavior you will get.

-s
 
K

Keith Thompson

Seebs said:
Seebs said:
[...]
The key is that, in an expression, a function yields a value of its
return type.
I would like to contribute to this game of finding the smallest nit.
*Calling* a function yields a value of its return type. The function
name itself (without the function call operator) yields a pointer to
the function.

Right you are. My sentence, as written, was indeed incorrect. Good
catch!

(This kind of thing, by the way, is why people writing about C usually
*need* technical reviews and errata.)

The most correct and precise way to say that is that a *function call*
(which is a kind of expression) yields a value of the function's
return type.
 
K

Keith Thompson

Malcolm McLean said:
I just happened to skim through your recent blog post, spinoza1111,
and noticed the following:
[Is the "type" of a fucntion void or void(int)?]

Generally we use the terms "signature" and "return type" to avoid this
ambiguity.

What ambiguity?

The "type of a function" is always a function type, which is distinct
from the function's return type. You can talk about a function's
"signature" if you like (the standard never uses the term but I'll
concede that it's clear enough). But the "type of a function"
means one and only one thing.

I'll concede that some people refer to a function's return type
as the type of the function, and this can be fairly harmless in
informal discussions. But such usage is strictly incorrect, and
either using it in a C reference book or attempting to "correct"
someone who has used the terms correctly is just wrong.
In some contexts ypu want to talk about the return type of a function,
for instance in the expression
printf("%f", foo() );

foo() can be replaced by any function of "type" float or double.

No, the call to foo can be replaced by a call to any function
whose return type is float or double (i.e., whose type is "function
taking whatever and returning float or double") -- or by any other
expression of type float or double.
On
the other hand qsort takes a pointer to a comparison function of
"type" int(const void *, const void *).

Yes -- except that you can drop the scare quotes; that really is
the type of the comparison function.
 
K

Keith Thompson

Tim Rentsch said:
(e-mail address removed) (Richard Harter) writes: [...]
In short, the C standards are incomplete; they do not completely
specify the interpretation of code.

It is complete in this area. The Standard says specifically
that order of evaluation is "unspecified", meaning any ordering
that doesn't violate any other stated requirements is allowed.
One way to look at it is that
the standards specify C as a family of languages, differing by
implementation defined rules.

Certainly that is one way to look at it. A better way (IMO) to
look at it, at least as regards evaluation order, is that C
is a single language with a non-deterministic semantics. One
reason for this is that an implementation need not make the
same choice about evaluation order from one expression to the
next, or even the same on the next compilation as this one.
And for evaluation order in particular, implementations are
under no obligation to describe or document what rules they
use to determine ordering in any particular circumstance.

Did you really mean to use the word "non-deterministic"?

I'd prefer to say that C is a single language whose semantics
are not entirely specified in all cases. Saying that it has
"non-deterministic semantics" could imply that each implementation
is required to behave in a non-deterministic manner, which of course
it isn't.
 
M

Malcolm McLean

I'll concede that some people refer to a function's return type
as the type of the function, and this can be fairly harmless in
informal discussions.  But such usage is strictly incorrect, and
either using it in a C reference book or attempting to "correct"
someone who has used the terms correctly is just wrong.
"type" is a C technical term. The problem is that we can't restrict
the word to this usage, even when discussing the C standard, because
it is too common an English word.
 
T

Tim Rentsch

Keith Thompson said:
Tim Rentsch said:
(e-mail address removed) (Richard Harter) writes: [...]
In short, the C standards are incomplete; they do not completely
specify the interpretation of code.

It is complete in this area. The Standard says specifically
that order of evaluation is "unspecified", meaning any ordering
that doesn't violate any other stated requirements is allowed.
One way to look at it is that
the standards specify C as a family of languages, differing by
implementation defined rules.

Certainly that is one way to look at it. A better way (IMO) to
look at it, at least as regards evaluation order, is that C
is a single language with a non-deterministic semantics. One
reason for this is that an implementation need not make the
same choice about evaluation order from one expression to the
next, or even the same on the next compilation as this one.
And for evaluation order in particular, implementations are
under no obligation to describe or document what rules they
use to determine ordering in any particular circumstance.

Did you really mean to use the word "non-deterministic"?

Yes I did, and in retrospect I may have been guilty of confusing
the issue, so let me explain further.

IME the word "non-deterministic" is used to mean one of three
different things, even though these different meanings are
related they're definitely not the same:

1. Certain algorithms or automata are described as being
"non-deterministic" to mean that, when confronted with
a choice, they make "the right" choice, or in another
way of explaining the behavior they make all possible
choices. A non-deterministic Turing machine doesn't
make a choice at random, it makes the "right" choice
or equivalently it computes in parallel all possible
alternative choices.

2. Sometimes "non-deterministic" is used to mean that
when confronted with a choice some particular choice
is made, but which choice that is is made "at random".

3. In the area of formal semantics in particular, the
term "non-deterministic" is used as an adjective
(often modifying the word semantics) to mean that
when a choice is confronted, some particular choice
is made but the semantics doesn't prescribe how
the choice is to be made. Implementing a formal
semantics that is non-deterministic could be done
by, eg, always choosing the first alternative,
always choosing the last alternative, choosing the
n%k'th choice of k alternatives on the n'th choice,
waiting for a cosmic ray and making a choice based
on the energy of the cosmic ray, etc. In some sense
meaning (3) is a generalization of meaning (2).

Since I have some background in formal semantics, I meant the
phrase "non-deterministic semantics" in the sense of meaning 3.
This meaning is pretty close to what the C standard calls
'unspecified behavior' (in fact probably identical, but I don't
want to equate a formal term and an informal term without a lot
more thought than I've put in just now).

I'd prefer to say that C is a single language whose semantics
are not entirely specified in all cases. Saying that it has
"non-deterministic semantics" could imply that each implementation
is required to behave in a non-deterministic manner, which of course
it isn't.

It does behave in a non-deterministic manner in the literal sense
of non-deterministic, that is, it is not determined by the
definition. An implementation that bases its choices on random
events that by chance always happens to take the first choice is
still "non-deterministic"; so is an implementation that simply
decided always to take the first choice available. However you
are right that it is potentially confusing, so to be explicit
and also (hopefully) clear, I will say that by "non-deterministic
semantics" I mean that an implementation may elect any choice
resolution mechanism it wishes, including both mechanisms that
are completely regular and predictable and also mechanisms that
make totally unpredictable choices, or any combination of
predictable, unpredictable, and/or "random".
 
K

Keith Thompson

Malcolm McLean said:
"type" is a C technical term. The problem is that we can't restrict
the word to this usage, even when discussing the C standard, because
it is too common an English word.

I disagree. When we're discussing the C standard we most certainly
*can* (and should) use the word "type" with the meaning defined by the
C standard. What's the point of having the standard define meanings
for terms if we're unwilling or unable to use them that way?

And what exactly is the common English meaning of "type" for which a
function can have type int?
 
M

Malcolm McLean

And what exactly is the common English meaning of "type" for which a
function can have type int?
The "type" of a "function" in non-C terms would be "real" or
"integral", as well as other characteristics like "monotonic" or
"differentiable".
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,774
Messages
2,569,596
Members
45,143
Latest member
DewittMill
Top