| Liste des Groupes | Revenir à cl c |
cross@spitfire.i.gajendra.net (Dan Cross) writes:In article <86ik81cfk5.fsf_-_@linuxsc.com>,>
Tim Rentsch <tr.17687@z991.linuxsc.com> wrote:Janis Papanagnou <janis_papanagnou+ng@hotmail.com> writes:On 2026-06-01 00:54, Keith Thompson wrote:>>[...]>
Yes, a compiler can reduce (a + b) * 0 to just 0. But it's not
required to do so, and (INT_MAX + 1) * 0 still has undefined
behavior. Undefined behavior is determined by the rules of the
abstract machine *without* any adjustments permitted by the as-if
rule.
This is something I really don't get in the actual C-logic...
>
Using constants that can be determined at compile time is UB here,
despite the '* 0' mathematically indicating an IMO clear semantics,
but using variables is only UB possibly at runtime? [...]
There's an important distinction to make here. Consider this
program:
>
#include <limits.h>
>
int
foo(){
int zero = (INT_MAX+1)*0;
return zero;
}
>
int
main(){
return 0;
}
>
This program does not transgress the bounds of undefined behavior.
To clarify, the comments in my posting were meant to be read as
saying the given text is the entire program, and that it is strictly
conforming with respect to conforming hosted implementations.
(Incidentally, given the rules for freestanding implementations, I'm
not sure that it is even possible for any program to be strictly
conforming with respect to conforming freestanding implementations.
In any case my statements were meant only in the context of hosted
implementations.)
[snip]>
Perhaps you mean that this is irrelevant because `foo` is not
invoked, but I see no reason why that need be the case in e.g.
a freestanding environment.
I explained the context of my previous statements above. Sorry for
not saying that in the original message.
>In a hosted environment, I don't>
think anything explicitly prevents `foo` from being called after
`main` returns (though I can't imagine that would happen in real
life; it would be weird if it did).
The semantics described in the ISO C standard don't admit that
possibility.
Whether foo() has external linkage or internal
linkage doesn't change that.
Only those actions initiated by
statements in main() are ever elaborated.
But I'm not sure what _you_ mean by "transgress the bounds of>
undefined behavior" here.
It's a grammatical fine point. I think for present purposes it's
okay to gloss over the distinction, and say this statement may be
read as saying "the program does not have undefined behavior".
>Even more than that, the program is strictly conforming, and must be>
accepted by a conforming implementation.
See above.
>Now let's change the program slightly:>
>
#include <limits.h>
>
int
foo(){
static int zero = (INT_MAX+1)*0;
return zero;
}
>
int
main(){
return 0;
}
>
This program does transgress the bounds of undefined behavior. The
reason for the difference is that in the first program the semantics
of foo() is to evaluate the expression to be stored in 'zero' only
at runtime, whereas in the second program the semantics of foo() is
to evaluate the expression to be stored in 'zero' before program
startup (informally, "at compile time"). What matters is not
whether the offending expression /might/ be evaluated "at compile
time", but whether the offending expression /must/ be evaluated "at
compile time". Only in the second case is undefined behavior
inevitable (and thus it does not occur in the first program).
>
Fine point: strictly speaking, I believe the C standard allows even
the second program to complete translation phase 8 successfully, and
for any offending behavior to occur only when we actually try to run
the program. To say that another way, there is no requirement that
possible nasal demons be made manifest at any point before an actual
attempted execution. On the other hand, because that possibility is
there lurking in the background, there is no requirement that the
program be accepted, and could be rejected by a conforming compiler.
Indeed. Further, I believe that the same is true for the first
program, as well.
It isn't. In the first program the offending expression is never
evaluated, because foo() is never called.
Les messages affichés proviennent d'usenet.