• Re: Constants and undefined behavior

    From Tim Rentsch@3:633/10 to All on Sunday, June 21, 2026 14:26:08
    antispam@fricas.org (Waldek Hebisch) writes:

    Dan Cross <cross@spitfire.i.gajendra.net> wrote:

    In article <1100g0e$1lt8i$1@kst.eternal-september.org>,
    Keith Thompson <Keith.S.Thompson+u@gmail.com> wrote:

    and in fact
    it *won't* occur during execution because foo() isn't called.
    A compiler can't generate code with arbitrary behavior just
    because it can't prove that there will be no UB. If it could,
    every signed or floating-point arithmetic operation with unknown
    operand values would grant the same permission.

    But that's not the situation here. The situation is that the
    compiler can prove that something _is_ UB.

    In the program quoted at the top of this post, the UB occurs in
    a function foo() that's never called. A compiler can replace the
    body of foo() with a trap, and it can certainly warn about the UB,
    but I don't believe it can reject the entire program. A clever
    compiler could prove that the UB never occurs.

    So there are two things that are at play here.

    First, this notion that UB is _only_ a runtime matter. The text
    of the standard contradicting that aside, if a translator can
    detect that the behavior of a construct is provably undefined if
    executed, then it seems axiomatic that UB is clearly something
    that plays a role at translation time, as well.

    I think that this paragraph (and several other it this post and
    other posts) represent fundamental misanderstanding. This may
    be due to the way C standard is written. AFAIK Extended Pascal
    standard (once you translate terminalogy) states the same things as
    C about UB, but in clearer way. Some relevant parts below:

    : 3.1 Dynamic-violation
    : A violation by a program of the requirements of this International
    : Standard that a processor is permitted to leave undetected up to,
    : but not beyond, execution of the declaration, definition, or
    : statement that exhibits (see clause 6) the dynamic-violation.

    : 3.2 Error
    : A violation by a program of the requirements of this International
    : Standard that a processor is permitted to leave undetected.
    ...
    : 5.1 Processors
    ...
    : e) be able to determine whether or not the program violates any
    : requirements of this International Standard, where such a
    violation is : not designated an error or dynamic-violation,
    ...

    : 5.2 Programs
    ...
    : b) if it conforms at level 1, use only those features of the
    language : specified in clause 6;

    UB in C standard corresponds with 'error' in Pascal standard. [...]

    Does it? In C a syntax error is undefined behavior, but it
    requires a diagnostic. (I don't mean to single out just syntax
    errors; there are other examples.)

    --- PyGate Linux v1.5.17
    * Origin: Dragon's Lair, PyGate NNTP<>Fido Gate (3:633/10)
  • From Tim Rentsch@3:633/10 to All on Sunday, June 21, 2026 15:26:35
    antispam@fricas.org (Waldek Hebisch) writes:

    [...]

    I think that lawyerish style of current C standard is mostly
    inertia,

    I wouldn't use a term like lawyerish to describe the text in the
    ISO C standard. Can you explain what quality you mean to ascribe
    to "lawyerish" writing in the C standard without using any term
    related to lawyering or legal documents?

    and making standard more mathematical would improve it.

    Could you elaborate on that statement? In what ways would giving
    a more mathematical treatment of C semantics improve the quality
    of the ISO C document? How would doing that advance the stated
    purposes or goals of the C standard?

    But giving formal semantic in the standard would mean
    significantly bigger change.

    Due to the nature of C, I believe it is effectively impossible to
    give a formal mathematical definition of the semantics of C. Do
    you think such a thing is feasible or practicable? If so can you
    explain the reasoning behind your thinking?

    --- PyGate Linux v1.5.17
    * Origin: Dragon's Lair, PyGate NNTP<>Fido Gate (3:633/10)
  • From Janis Papanagnou@3:633/10 to All on Wednesday, June 24, 2026 16:58:36
    I'm entering this sub-thread late and yet I haven't finished reading
    all posts. - While I lately noticed some convergence of opinions and
    facts this post appears to me to mostly fall back again; but I won't
    re-open the discussion. I just want to comment on a single exposition.

    On 2026-06-15 10:09, David Brown wrote:
    On 15/06/2026 00:55, Keith Thompson wrote:
    [...]
    [...]

    Throwing some kind of exception or trap can definitely be helpful at
    times.ÿ And I agree that it would make it obvious that there has been a problem detected.ÿ But throwing exceptions or traps can cause more
    problems (the Ariane 5 failure was caused by the exception handler, not
    the overflow fault).ÿ That does not mean it is better to ignore
    overflows - it means there is no appropriate action that is suitable in every situation.ÿ I am far from convinced that there is even a
    reasonable choice of default action that could be usefully made.
    (I don't expect the complete investigation report on the Ariane 5
    incident being represented or explained, but picking a few facts is
    not only an oversimplification here, it lead to a misrepresentation
    of the case and inappropriate reasoning and conclusions.)

    Throwing an exception in a system that should have a well-defined and
    safe behavior is of course stupid. Exceptions are there to catch them
    and handle them with appropriate actions to mitigate or fix any issue.

    Not UB, but well defined software and well defined system behavior is
    the key! That should be not only in aviation and life-critical systems
    but (ideally) also in "ordinary" software development with used tools.

    The problem with the Ariane 5 was a sequence and combination of events.

    But the _primary cause_ had not been the [technical] interrupt. It was
    the fact that the *requirements* (the flight trajectories) changed from
    Ariane 4 to Ariane 5 and that they didn't adjust the system accordingly
    but just re-used formerly designed system components unchanged.

    (This actually reminds (or resembles?) more the case that Dan narrated;
    of using old software systems with new tools, that "unexpectedly" fails
    in a new compiler-environment, because of a component in another place
    that was just "invisible" at the place where the problem got triggered.)

    In retrospect it is clear that all the software components with their
    contracts should have been double-checked against the (new) Ariane 5 requirements - that hadn't been done and that was the problem source!

    (There's a reason why they use Ada and not "C" in such areas; the
    rocket might otherwise have exploded on the launching-ramp already. ;-)

    Janis

    [...]


    --- PyGate Linux v1.5.18
    * Origin: Dragon's Lair, PyGate NNTP<>Fido Gate (3:633/10)
  • From Janis Papanagnou@3:633/10 to All on Wednesday, June 24, 2026 17:45:22
    On 2026-06-16 10:10, David Brown wrote:
    On 15/06/2026 19:57, Waldek Hebisch wrote:
    [...]

    No, ignoring problems is never a good thing.ÿ Writing code that doesn't
    run the risk of problems is a good thing.

    Sure.


    And I can agree that sometimes leaving traps enabled in released code
    can be helpful - there are situations where you can't practically remove
    the risk of overflows, and it is better to crash out reliably than risk running on with faulty data.ÿ It is, however, also the case that
    sometimes traps will cause far more problems than incorrect data would. (Noting that UB does not guarantee "incorrect data" - it can do
    anything.ÿ Wrapping semantics, or unspecified value semantics, would do that.)

    Hmm.. - not sure what you mean (and imply with) "crash out reliably".

    Having been engaged in server systems software development a crash
    had never been an accepted option. And that's certainly also true
    with life-critical applications and costly operations (upthread you
    had mentioned Ariane 5). You should always avoid crashes and catch
    exceptions. The point is what you can then do with that information,
    and that depends on the actual application case; report it, retry it,
    retry with alternative methods or adapted conditions, emulate the
    result, estimate it, ask supervisor process, switch devices, etc.

    I'm well aware that wrong data may also be bad, be it from a wrong
    algorithms, a technical overflow situation, unreliable data sources,
    or an unreliable processing (not-excluding effects of UB).

    I'm really not sure whether to consider "not handling an exception"
    better or worse than "not handling data errors"; usually you don't
    want either. So both should prevented (if possible) or acted upon
    (if getting a notice about it).

    Janis

    [...]


    --- PyGate Linux v1.5.18
    * Origin: Dragon's Lair, PyGate NNTP<>Fido Gate (3:633/10)
  • From Chris M. Thomasson@3:633/10 to All on Wednesday, June 24, 2026 12:27:47
    On 6/24/2026 8:45 AM, Janis Papanagnou wrote:
    On 2026-06-16 10:10, David Brown wrote:
    On 15/06/2026 19:57, Waldek Hebisch wrote:
    [...]

    No, ignoring problems is never a good thing.ÿ Writing code that
    doesn't run the risk of problems is a good thing.

    Sure.


    And I can agree that sometimes leaving traps enabled in released code
    can be helpful - there are situations where you can't practically
    remove the risk of overflows, and it is better to crash out reliably
    than risk running on with faulty data.ÿ It is, however, also the case
    that sometimes traps will cause far more problems than incorrect data
    would. (Noting that UB does not guarantee "incorrect data" - it can do
    anything.ÿ Wrapping semantics, or unspecified value semantics, would
    do that.)

    Hmm.. - not sure what you mean (and imply with) "crash out reliably".

    Having been engaged in server systems software development a crash
    had never been an accepted option. And that's certainly also true
    with life-critical applications and costly operations (upthread you
    had mentioned Ariane 5). You should always avoid crashes and catch exceptions.

    Right. Also, fwiw, I had a calibration system for my server framework
    that would artificially crash a system while keep logs. On reboot, it
    read the results and self calibrated itself.



    The point is what you can then do with that information,
    and that depends on the actual application case; report it, retry it,
    retry with alternative methods or adapted conditions, emulate the
    result, estimate it, ask supervisor process, switch devices, etc.

    I'm well aware that wrong data may also be bad, be it from a wrong algorithms, a technical overflow situation, unreliable data sources,
    or an unreliable processing (not-excluding effects of UB).

    I'm really not sure whether to consider "not handling an exception"
    better or worse than "not handling data errors"; usually you don't
    want either. So both should prevented (if possible) or acted upon
    (if getting a notice about it).

    Janis

    [...]



    --- PyGate Linux v1.5.18
    * Origin: Dragon's Lair, PyGate NNTP<>Fido Gate (3:633/10)
  • From Tim Rentsch@3:633/10 to All on Monday, June 29, 2026 05:41:10
    cross@spitfire.i.gajendra.net (Dan Cross) writes:

    [...]

    "Undefined Behavior", in C, in the manner usually discussed in
    this newsgroup, was introduced with the first standard.

    The term but not the concept, which was there since the
    early days of C -- at least since K&R in 1978, and very
    likely earlier (I haven't reviewed any of the earlier
    descriptions of the language).

    --- PyGate Linux v1.5.18
    * Origin: Dragon's Lair, PyGate NNTP<>Fido Gate (3:633/10)
  • From Tim Rentsch@3:633/10 to All on Monday, June 29, 2026 06:27:13
    antispam@fricas.org (Waldek Hebisch) writes:

    Tim Rentsch <tr.17687@z991.linuxsc.com> wrote:

    antispam@fricas.org (Waldek Hebisch) writes:
    [...]
    UB in C standard corresponds with 'error' in Pascal standard. [...]

    Does it? In C a syntax error is undefined behavior, but it
    requires a diagnostic. (I don't mean to single out just syntax
    errors; there are other examples.)

    I mean typical UB, especialy cases that people complain about.
    [...]

    Then you should say what you mean, rather than leaving it
    for other people to guess.

    --- PyGate Linux v1.5.18
    * Origin: Dragon's Lair, PyGate NNTP<>Fido Gate (3:633/10)
  • From Dan Cross@3:633/10 to All on Monday, June 29, 2026 15:23:31
    In article <86mrwd7c49.fsf@linuxsc.com>,
    Tim Rentsch <tr.17687@z991.linuxsc.com> wrote:
    cross@spitfire.i.gajendra.net (Dan Cross) writes:

    [...]

    "Undefined Behavior", in C, in the manner usually discussed in
    this newsgroup, was introduced with the first standard.

    The term but not the concept, which was there since the
    early days of C -- at least since K&R in 1978, and very
    likely earlier (I haven't reviewed any of the earlier
    descriptions of the language).

    How much time elapsed before your response?

    If you cannot respond in a timely manner (read: within a week),
    then please do not respond at all.

    That said, not really. I've read K&R, both editions, and the
    first really doesn't define a concept that gives such supreme
    latitude to the compiler. They merely acknowledged that there
    existed things for which they could not give a good behavioral
    definition. The way that UB is defined and used in 2026 was
    absent in K&R in 1978.

    - Dan C.


    --- PyGate Linux v1.5.18
    * Origin: Dragon's Lair, PyGate NNTP<>Fido Gate (3:633/10)