From: David Schwartz on
On Feb 14, 4:24 pm, "Andreas H" <Andreas.H....(a)alumni.tu-berlin.de>
wrote:

> >> Thus, this code was broken because it relied on a *non-standard
> >> behaviour* that was not supported by the actual implementation.
> > That is another way to say the exact same thing I said.

> Well, I agree - even though this is of course not _formally_ equivalent to
> your original statement, that included an unconditional logical implication
> between "violating the C standard" and "being broken".

I don't think so. If I said "his house burned down because he fell
asleep while smoking" does that imply that *everyone* who falls asleep
while smoking will have their house burn down? To say "X caused Y" is
also to say that the facts were such that X *could* cause Y. It
doesn't imply in any way that X must always cause Y.

His code was broken because it violated a part of the C standard. This
is obviously only possible when the facts are such that a non-
conformance with the C standard can cause code to break. It doesn't
even imply that this must always happen.

Where it went off the deep end was when Rainer conflated doing things
the C standard specifies against those specifications (where it's
quite clear that you can do precisely the same thing but in compliance
with the specification) and doing things not specified by the C
standard at all (such as calling 'fork') but the way the standards
that do specify that behavior ask you to do it. That's when it
switched from a discussion to lunacy.

DS
From: Andreas H on
"David Schwartz" <dav...(a)webmaster.com> wrote:

>>>> Thus, this code was broken because it relied on a *non-standard
>>>> behaviour* that was not supported by the actual implementation.
>>> That is another way to say the exact same thing I said.

>> Well, I agree - even though this is of course not _formally_ equivalent
>> to your original statement, that included an unconditional logical
>> implication between "violating the C standard" and "being broken".

> I don't think so. If I said "his house burned down because he fell
> asleep while smoking" does that imply that *everyone* who falls asleep
> while smoking will have their house burn down? To say "X caused Y" is
> also to say that the facts were such that X *could* cause Y. It
> doesn't imply in any way that X must always cause Y.

It's exactly how you say: In everyday language, "caused" can also mean
"caused under the given circumstances". Keeping that in mind, your original
statement perfectly makes sense. And it was my fault to take your sentence
too formally.

For if you read "Y because of X" as a logical implication "X => Y", there
is no logical way, in which X is TRUE while Y is FALSE. To falsify an
implication "X => Y", it therefore is sufficient to provide _one_ single
example with X == TRUE AND Y == FALSE; e.g. somebody smoking in bed without
the house burning.

But again - now I know that by saying "because" you didn't mean a formal
logical implication!!

> His code was broken because it violated a part of the C standard. This
> is obviously only possible when the facts are such that a non-
> conformance with the C standard can cause code to break. It doesn't
> even imply that this must always happen.

Yes, that's right. And, by the way, following an applicable standard can
always be considered a good idea - unless you have good reason not to do so.

Greetings from Berlin
Andreas

[ http://en.wikipedia.org/wiki/Entailment ]

From: Rainer Weikusat on
"Andreas H" <Andreas.H....(a)alumni.tu-berlin.de> writes:
> "David Schwartz" <dav...(a)webmaster.com> wrote:
>>>>> Thus, this code was broken because it relied on a *non-standard
>>>>> behaviour* that was not supported by the actual implementation.
>>>> That is another way to say the exact same thing I said.
>
>>> Well, I agree - even though this is of course not _formally_ equivalent
>>> to your original statement, that included an unconditional logical
>>> implication between "violating the C standard" and "being broken".
>
>> I don't think so. If I said "his house burned down because he fell
>> asleep while smoking" does that imply that *everyone* who falls asleep
>> while smoking will have their house burn down? To say "X caused Y" is
>> also to say that the facts were such that X *could* cause Y. It
>> doesn't imply in any way that X must always cause Y.
>
> It's exactly how you say: In everyday language, "caused" can also mean
> "caused under the given circumstances". Keeping that in mind, your original
> statement perfectly makes sense. And it was my fault to take your sentence
> too formally.

The problem with this 'original statement' is still that it is flat
out in contradiction with the C-standard.

7.14.11|5 says

If the signal occurs other than as the result of calling the
abort or raise function, the behavior is undefined if the
signal handler refers to any object with static storage
duration other than by assigning a value to an object declared
as volatile sig_atomic_t,

'undefined behaviour' is defined as

undefined behavior

behavior, upon use of a nonportable or erroneous program
construct or of erroneous data, for which this International
Standard imposes no requirements
[3.4.3|1]

And this text simnply doesn't state that code use constructs the
C-standard doesn't define behaviour for is broken. No matter how hard
David wants that to be in there, it isn't.



From: Rainer Weikusat on
Rainer Weikusat <rweikusat(a)mssgmbh.com> writes:

[...]

> undefined behavior
>
> behavior, upon use of a nonportable or erroneous program
> construct or of erroneous data, for which this International
> Standard imposes no requirements
> [3.4.3|1]
>
> And this text simnply doesn't state that code use constructs the
> C-standard doesn't define behaviour for is broken. No matter how hard
> David wants that to be in there, it isn't.

A live demonstration for that: When translating the program included
below with gcc 4.3.2 with the optimizer disabled, a binary is produced
which exits when Ctrl-C is pressed (the same is true for 4.0.3 and
presumably, any other version).

------------------
#include <stdio.h>
#include <signal.h>

static int terminate;

void handle_sigint(int unused)
{
terminate = 1;
}

int main(void)
{
signal(SIGINT, handle_sigint);

puts("Off we go ...");
while (!terminate);
puts("... and here, we leave");

return 0;
}
-------------------

Translating the same program with 'optimization' turns the
while-statement into an endless loop which doesn't check the value of
terminate upon each iteration in the way I have shown in the context
of the original question. And this means "because the code isn't
strictly conforming C" it *may* have portabilitiy issues, that is,
might or might not 'work' when being used together with C
implementations which behave in different ways (such as gcc with and
without -O), depending on properties of these implementations
(invariant code motion). In this particular case, the problem is the
missing volatile, as per

Accessing a volatile object, modifying an object, modifying a
file, or calling a function that does any of those operations
are all side effects

[...]

In the abstract machine, all expressions are evaluated as
specified by the semantics. An actual implementation need not
evaluate part of an expression if it can deduce that its value
is not used and that no needed side effects are produced
(including any caused by calling a function or accessing a
volatile object).
[5.1.2.3, 2 + 3]

Related: The section on sig_atomic_t (7.14|2) states that

The type defined is

sig_atomic_t

which is the (possibly volatile-qualified) integer type of an
object that can be accessed as an atomic entity, even in the
presence of asynchronous interrupts.

Consequently, using sig_atomic_t means using an object with integer
type which is required to be atomically accessible in every conforming
C implementation ('maximially portable among conforming
implementation'). David usually refers to anyone who doesn't strive
for these 'maximal portability' as 'lunatic'. But at least for the
problems I have to solve, 'portable to everything which can run Linux'
is sufficient (especially since this also means 'portable to every even
remotely mainstream implementation of UNIX(*)').
From: David Schwartz on
On Feb 15, 12:44 pm, Rainer Weikusat <rweiku...(a)mssgmbh.com> wrote:

> And this text simnply doesn't state that code use constructs the
> C-standard doesn't define behaviour for is broken.

I agree.

> No matter how hard
> David wants that to be in there, it isn't.

You made this ridiculous claim up just to foist it on me and then show
how ridiculous it is.

DS