On 23/08/2025 00:11, Keith Thompson wrote:
comp.lang.c would probably be a better place for this discussion,
but cross-posting between moderated and unmoderated newsgroups is
likely to cause problems.
Yes - but some comments have also wandered slightly from being just applicable to C. Still, it is not really a compiler discussion.
[FYI, cross-posting to comp.compilers and other groups works because
your moderator's scripts know how to handle it. -John]
David Brown <david.brown@hesbynett.no> writes:
On 21/08/2025 21:53, Keith Thompson wrote:[...]
If you declare and call a function "foo" that is written in fully
portable C code, but not part of the current translation unit being
compiled (perhaps it has been separately compiled or included in a
library), then it would be UB by the section 4 definition (since the C
standards don't say anything about what "foo" does, nor does your code).
If the translation unit that defined "foo" is part of your program, then
your code *does* define its behavior. Linking multiple translation
units into a program is specified by the C standard; it's translation
phase 8.
No.
The C standard does not define how this linking or combing is done - it
only covers certain specific aspects of the linking that relate directly
to C. The behaviour of the function "foo" here is not defined in the C standards, and if the source code is not available when translating a different translation unit, the behaviour of "foo" is undefined.
The C code being translated has code to call the function - the call is defined (assuming declarations and definitions are consistent), but the effect of the call is not defined - it is therefore UB.
Add to that, the C standard has a specific term for features that areThat's not what "implementation-defined behavior" means in C.
non-portable but not undefined behaviour - "implementation-defined
behaviour". Code that relies on "int" being 32-bit is not portable, but >>> it is not UB when compiled on implementations for which "int" /is/ 32-bit. >>
Cases of implementation-defined behavior are explicitly called out in
the standard, and an implementation must document how it treats each
instance of implementation-defined behavior. Each implementation
must document the range of int. There is no such requirement for
the behavior of "foo" defined in some non-standard header.
Yes, exactly - implementation-defined behaviours are things that are not portable, but are not undefined behaviour, because they must be defined
by the implementation. (The C standard usually also gives some specific options or minimum requirements for those definitions.)
Section 4 says precisely that behaviour that is not defined by the C standard, is "undefined behaviour" in exactly the same way as things
that are explicitly labelled "undefined behaviour" in the standard.
And that, I think, is the root of the problem - the C standard is on the
one hand trying to classify, define and describe things as "undefined behaviour" as a technical term in the C standard, while on the other
hand it is also trying to say these are things that have no definition
or descriptions of their behaviours.
[...]It is behavior that
is not defined *by the C standard*. If I write printf("goodbye\n")
when I meant to write printf("hello\n"), that's incorrect behavior,
but it's not undefined behavior.
I agree that it is not C undefined behaviour, yes.
Sysop: | Tetrazocine |
---|---|
Location: | Melbourne, VIC, Australia |
Users: | 11 |
Nodes: | 8 (0 / 8) |
Uptime: | 50:52:35 |
Calls: | 166 |
Files: | 21,502 |
Messages: | 77,738 |