Path: csiph.com!weretis.net!feeder6.news.weretis.net!news.misty.com!news.iecc.com!.POSTED.news.iecc.com!nerds-end From: Kaz Kylheku <480-992-1380@kylheku.com> Newsgroups: comp.compilers Subject: Re: what is defined, was for or against equality Date: Tue, 11 Jan 2022 19:19:31 -0000 (UTC) Organization: A noiseless patient Spider Lines: 136 Sender: news@iecc.com Approved: comp.compilers@iecc.com Message-ID: <22-01-045@comp.compilers> References: <17d70d74-1cf1-cc41-6b38-c0b307aeb35a@gkc.org.uk> <22-01-016@comp.compilers> <22-01-018@comp.compilers> <22-01-020@comp.compilers> <22-01-027@comp.compilers> <22-01-032@comp.compilers> <22-01-038@comp.compilers> <22-01-041@comp.compilers> <22-01-044@comp.compilers> Injection-Info: gal.iecc.com; posting-host="news.iecc.com:2001:470:1f07:1126:0:676f:7373:6970"; logging-data="34163"; mail-complaints-to="abuse@iecc.com" Keywords: standards, optimize Posted-Date: 11 Jan 2022 14:47:23 EST X-submission-address: compilers@iecc.com X-moderator-address: compilers-request@iecc.com X-FAQ-and-archives: http://compilers.iecc.com Xref: csiph.com comp.compilers:2821 On 2022-01-11, David Brown wrote: > On 10/01/2022 13:04, Thomas Koenig wrote: >> David Brown schrieb: >> >>> The big question here, is why do you think Fortran is any different? In >>> theory, there isn't a difference - nothing you have said here convinces >>> me that there is any fundamental difference between Fortran and C in >>> regards to undefined behaviour. >> >> I am not sure how to better explain it. I will try a bit, but >> this will be my last reply to you in this thread. We seem to have >> a fundamental difference in our understanding, and seem to be >> unable to resolve it. > > Fair enough. Maybe in a future discussion, one of us will have an > "Aha!" moment and understand the other's viewpoint, and progress will be > made - until then, there's no point in going around in circles. I'll > snip bits of your post here, and try to minimise new points (unless I > get that "Aha!") - but be sure I am reading and appreciating your entire > post. > >>> (And there's no difference in the >>> implementations - the most commonly used Fortran compilers also handle >>> C, C++, and perhaps other languages.) >> >> Sort of. >> >> At the risk of boring most readers of this group, a very short, but >> (hopefully) pertinent introduction of how modern compilers work: >> >> >> There is no compiler (if you mean a single binary) that handles both >> C and Fortran. They are separate front ends to common middle >> and back ends. > > Yes. But it is the middle end that handles most of the optimisations, > including those based on undefined behaviour. The front end determines > whether code can have undefined behaviour and in what circumstances. More precisely, optimizations are based on the absence of undefined behavior: the assumption that contracts are being upheld. More precisely, that contracts are being upheld in the face of the inability to determine and diagnose statically whether they are violated; i.e. there is a "blind trust". (Though there do exist situations in which, in principle, undefined behavior is easily deducible at translation time, without a requirement to do so.) Front-ends for different languages are written to the respective requirements of those languages. Their first aim is to handle well-defined constructs and situations. They target the intermediate language of the compiler middle. That language has its own contracts. The front end for each respective language has to ensure that every situation in which behavior is defined (contract is upheld) is translated to reliable intermediate code whose contract is upheld. Care has to be taken that the intermediate code is expressed in the right way so that it will not change behavior in invalid ways due to optimizations. This leaves a lot of room for Fortran and C to have entirely different defined/undefined behaviors. Even the front end for one single language can have a lot of switches affecting what is defined or not. Thre could be a switch which says that overflowing integer addition has two's complement wrapping behavior. In that case, the compiler then selects the intermediate instructions which provide that behavior reliably (possibly simulating signed arithmetic with unsigned), and also disables any inferences in the front end that might be based on the assumption that overflow has not occurred. >>> C does not have a "write" function in the standard library. So the >>> behaviour of "write" is not defined by the C standards - but that does >>> not mean the behaviour is undefined. >> >> When interpreting at a language standard, you _must_ follow the >> definitions in the standards if they exist, you cannot use everyday >> interpretations. >> >> Subclause 3.4.3 (N2596) defines >> >> # undefined behavior >> >> # behavior, upon use of a nonportable or erroneous program >> # construct or of erroneous data, for which this document imposes >> # no requirements >> >> write() is nonportable and the C standard imposes no requirements >> on it. Therefore, the program above invokes undefined behavior. > > No. (As always, this is based on my interpretation of the standards - Yes; using any function that is not in the C program, or in the standard, is ISO C undefined behavior. A program which includes is not required to compile according to ISO C; it can fail with an error message about the header not being defined. Or, #include is allowed, in a conforming implementation, to bring in tokens which have nothing to do with POSIX. Furthermore, a program which calls write, and does not provide such a function itself, is not required to successfully link. If it does link, there is no requirement that this symbol is a function described by POSIX. POSIX implementations have to go out of their way to allow C programs to use write as an external name, which ISO C allows. For instance, the GNU C Library defines write as a weak symbol for some identifier which resembles __libc_write: the "strong" symbol. The C library internally uses only that __libc_write: it never calls write, because user code could replace it: int write(char *x) { ... } double write = 42.0; When the application defines the external name write, the weak symbol coming from glibc yields; it is suppressed in favor of the program's definition. > consider everything to have "IMHO" attached.) The implementation of > "write" is outside the scope of the standards, and is therefore > undefined as far as the standards are concerned. That does not make it > undefined behaviour in the program - it just means the standards don't > say what "write" should do. Right; it's "ISO C formal undefined behavior", not "behavior that is not defined by any party whatsoever" ... though it could well be. -- TXR Programming Language: http://nongnu.org/txr Cygnal: Cygwin Native Application Library: http://kylheku.com/cygnal