Path: csiph.com!optima2.xanadu-bbs.net!xanadu-bbs.net!eternal-september.org!feeder.eternal-september.org!mx02.eternal-september.org!.POSTED!not-for-mail From: Keith Thompson Newsgroups: comp.lang.c Subject: Re: Unspecified Behaviors in C90 - part 3 Date: Fri, 17 Jul 2015 11:00:29 -0700 Organization: None to speak of Lines: 64 Message-ID: References: <55a42b8f.25228343@news.xs4all.nl> <435cc143-4ce0-4b10-a25b-92b0a638d9e6@googlegroups.com> <45ba9b21-0f12-4662-b89a-9f38c63a9486@googlegroups.com> <55A929D2.70908@verizon.net> Mime-Version: 1.0 Content-Type: text/plain; charset=us-ascii Injection-Info: mx02.eternal-september.org; posting-host="945944de09706c9b4e29b53c9d2efdc2"; logging-data="14927"; mail-complaints-to="abuse@eternal-september.org"; posting-account="U2FsdGVkX1/0v0wU5rRJUOBTmi6kdQxc" User-Agent: Gnus/5.13 (Gnus v5.13) Emacs/23.1 (gnu/linux) Cancel-Lock: sha1:aFg/yDoCalS58c8BL3sZYWyt0y4= sha1:m0keSD17SYiwhHAwIHElCjy5vWk= Xref: csiph.com comp.lang.c:65794 James Kuyper writes: [...] > When the C standard says that the behavior is unspecified, that's a very > different concept. It is permitted for the behavior of the program to be > detectably different, depending upon which choice the implementation > made. If one of the permitted options would produce behavior that you > don't want to happen, then you're supposed to re-write the code so that > it's no longer a permitted option. Such a re-write is always possible. A concrete example might help: #include int g(void) { putchar('g'); return 0; } int h(void) { putchar('h'); return 0; } void f(int x, int y) { /* nothing */ } int main(void) { f(g(), h()); putchar('\n'); return 0; } This program may print either "gh" or "hg", followed by a newline. It may not (assuming the putchar() calls succeed) do anything else. Which output is produced is *unspecified*. There is no implication in the standard that either order is the default or preferred order; either may occur, and implementations are not required to document whcih choice they make, or to make the same choice in all circumstances. The program could legally print "gh" one time and "hg" the next time (though that would be mildly surprising). This is entirely deliberate. There might be legitimate performance reasons a compiler might prefer one order over the other -- not in this particular case, since g() and h() are so similar, but in other cases where, for example, register allocation might be easier with one order than with the other. The current language rules give substantial flexibility both to compiler authors and to programmers. As a programmer, if I need a particular order, I can modify the program to guarantee it (this has been demonstrated already). If I don't care about the order, I can let the compiler choose based on performance, or code size, or other criteria. If the order were not unspecified, I could still write code that enforces a particular order, but I would no longer be able to write code that says "I don't care about the evaluation order, generate the best code you can". And if it were implementation-defined, code that depends on a particular implementation's documented behavior would still not be portable to other implementations with different documented behavior. -- Keith Thompson (The_Other_Keith) kst-u@mib.org Working, but not speaking, for JetHead Development, Inc. "We must do something. This is something. Therefore, we must do this." -- Antony Jay and Jonathan Lynn, "Yes Minister"