Path: csiph.com!eternal-september.org!reader02.eternal-september.org!.POSTED!not-for-mail From: Tim Rentsch Newsgroups: comp.lang.c++ Subject: Re: GCC hasn't even gotten around to sequencing argument evaluation yet??? Date: Wed, 06 Apr 2022 08:31:58 -0700 Organization: A noiseless patient Spider Lines: 108 Message-ID: <86mtgy9qj5.fsf@linuxsc.com> References: <87wng7fdea.fsf@bsb.me.uk> Mime-Version: 1.0 Content-Type: text/plain; charset=us-ascii Injection-Info: reader02.eternal-september.org; posting-host="cfa0770beb8101bb5d43e5e5d105b9bc"; logging-data="18771"; mail-complaints-to="abuse@eternal-september.org"; posting-account="U2FsdGVkX198h+V7KKsZXmJW7eKMs7rTEbdUnOWTw4k=" User-Agent: Gnus/5.11 (Gnus v5.11) Emacs/22.4 (gnu/linux) Cancel-Lock: sha1:0HiubKIDrFjyOrIS6Icua60d61A= sha1:GbnMb4vTQP75lm4HaFBGWU8Q4A8= Xref: csiph.com comp.lang.c++:83499 Andrey Tarasevich writes: > On 4/2/2022 1:17 PM, Ben Bacarisse wrote: > >> David Brown writes: >> >>> On 02/04/2022 12:30, Christian Gollwitzer wrote: >>> >>>> Am 02.04.22 um 05:34 schrieb Andrey Tarasevich: >>>> >>>>> int r = foo(++i, ++i); >>>>> >>>>> This outputs 6 in GCC 11.2 in `-std=c++17` mode and later. WTF? >>>>> Adding sequencing to argument evaluation, albeit indeterminate, >>>>> is a major and a very important change in C++17. How come it is >>>>> still not implemented in GCC? What are they waiting for? Is >>>>> there some sort of intentional opposition to that change in the >>>>> standard? >>>> >>>> I'm not an expert on the standard, but according to this page: >>>> https://en.cppreference.com/w/cpp/language/eval_order >>>> >>>> it is not specified. They have exactly your example down the >>>> page: >>>> >>>> f(++i, ++i); >>>> // undefined behavior until C++17, unspecified after C++17 >>>> >>>> To me that sounds like before C+17, the program could segfault, >>>> whereas with C++17, it can either output 5 or 6, but shold >>>> consistently do so. >>>> >>>> Am I wrong? >>> >>> The "unspecified" aspect refers to the ordering of evaluation of >>> the parameters - they are "indeterminately ordered". >>> >>> So given "int foo(int a, int b)", the call "f(++i, ++i)" should be >>> either: >>> >>> a = ++i; >>> b = ++i; >>> foo(a, b); >>> >>> or >>> >>> b = ++i; >>> a = ++i; >>> foo(a, b); >>> >>> It is thus unspecified whether a and b are 2 and 3, or 3 and 2 >>> respectively. But their sum will be the same. >>> >>> It seems gcc has handled this as: >>> >>> ++i; >>> ++i; >>> a = i; >>> b = i; >>> >>> and AFAIUI, this interleaving is not allowed in C++17. >> >> I am not 100% sure. The wording (C++20 but similar in C++17) is >> this: >> >> "The initialization of a parameter, including every associated >> value computation and side effect, is indeterminately sequenced >> with respect to that of any other parameter." >> >> That sounds like the two ++i expressions need not to be thought of >> as units with one sequenced before the other. It sounds as if any >> interleaving of the parts is permitted. At least that's how I >> would read it, unfamiliar as I am with the way the C++ authors use >> language. > > No, "sequenced before" is a very strong requirement preventing any > kind of interleaving. > > The modern C++ sequencing terminology abandoned the idea of a > "sequence point" and switched to some more finely attributed > variants, which might refer to value computation and side-effects > separately. One can say "value computation of the operand is > sequenced before..." or "side-effects of the argument are > sequenced after..." > > But a plain unattributed "sequenced before (or after)" is > basically the old-fashioned "sequence point": a full sequencing > requirement that covers everything, i.e. the value computation and > all side-effects together. > > The quote you provided completely compartmentalizes and isolates > argument expression evaluation and parameter initialization. No > interleaving is permitted. This is the intent. Going just by what is stated in the C++ standard, I would say the question is clearly ambiguous. There is no question that the initializations of _parameters_ are indeterminately sequenced. But the standard does not say the evaluations of _argument values_ are indeterminately sequenced. The standard does use the phrase "every associated value computation and side effect", but AFAICT there is no definition for what that phrase means. Perhaps it is meant to include the evaluation of argument values, and perhaps it isn't. What is clear is that the C++ standard doesn't state which of those possibilities is the case. Hence, going by just what is stated in the C++ standard, it appears the question is clearly ambiguous.