int count = 23; int foo[] = { count++, count++, count++ }; results: foo == { 23, 23, 23 }, count == 26; expected: foo == { 23, 24, 25 }, count == 26; === Tested only on intel platform with g++. on debian stable version 2.95.4 and a on Redhat AS 2.1 with a self compiled version 3.3. With g++ 2.96 from Redhat AS 2.1, if foo is a global variable (not inside any function scope), then foo is initialized correctly to different values. Attached to the bug is a simple test program... beta.cc g++ -Wall -g -o beta beta.cc gdb -q ./beta === (gdb) b main Breakpoint 1 at 0x8048674: file beta.cc, line 21. (gdb) r Starting program: ./beta Breakpoint 1, main () at beta.cc:21 21 static_func(); (gdb) p foo $1 = {23, 24, 25} (gdb) p zap $2 = {26, 26, 26} (gdb) s static_func() () at beta.cc:8 8 static int bar[] = { value(), value(), value() }; (gdb) n 9 static int baz[] = { count++, count++, count++ }; (gdb) n 11 return bar[0] + baz[0]; (gdb) p bar $3 = {29, 30, 31} (gdb) p baz $4 = {32, 32, 32} === Notice that the function calls are handled correctly, but the count++ is not. I do not know the c++ standard, it is *possible* that the code above is "undefined" by the standard and what g++ is doing is correct. However, the same code compiled with at least 5 commercial compilers on various platforms all resulted in what I say is the "expected" result with different values.
Created attachment 4452 [details] Sample program for structure initialization bug
The question is whether commas in initializers are sequence points. I don't know whether they are, though. W.
Hm, 8.5.1 is the normative part of the standard, but it doesn't say anything about the order of evaluation. Nathan, language lawyers to the front? W.
static int zap[] = { ++count-1, ++count-1, ++count-1 }; static int baz[] = { ++count-1, ++count-1, ++count-1 }; === Changing the code to the above... works around this problem in this sample.
A friend pointed out language in the gcc.info file which appears to cover the 'comma' ordering case: === * Making side effects happen in the same order as in some other compiler. It is never safe to depend on the order of evaluation of side effects. For example, a function call like this may very well behave differently from one compiler to another: void func (int, int); int i = 2; func (i++, i++); There is no guarantee (in either the C or the C++ standard language definitions) that the increments will be evaluated in any particular order. Either increment might happen first. `func' might get the arguments `2, 3', or it might get `3, 2', or even `2, 2'. === I'm not sure if this applies here... and if it *does* apply it seems inconsistant that things like: ++foo-1, ++foo-1 ... foo++ + 0, foo++ + 0 ... and value(), value()... all get evaluated left to right, but foo++, foo++ value gets looked up once, and gets somehow the increment happens N times. I am very interested in what the c++ language lawyers have to say about this sample. If it is truely undefined I am *amazed* that practically all of the remaining commercial unix, c++ compilers do it the same way.
Commas separating function call arguments are not sequence points, so foo(x++, x++) can really be evaluated in different ways. On the other hand, commas in comma expressions as in while (x++, x++) _are_ sequence points, so the order of evaluation is defined. The only question which I can't answer from the standard is whether commas in initializer expressions are sequence points. If the order of evaluation is undefined, then the fact that some compilers implement one way of doing things is not a reason to rely on a feature. Likewise, random changes to the code _may_ make the code do what you expect, but the code still triggers undefined behavior and may break again with the next compiler version. The only way around this is to make the code use only well defined semantics. W.
For the C language, in a draft of the C99 spec around section 6.7.8 "Initialization", it talks about initialization lists. === [#23] The order in which any side effects occur among the initialization list expressions is unspecified. (121) 121 - In particular, the evaluation order need not be the same as the order of subobject initialization. === Perhaps someone with the c++ standard handy can find "initialization lists". If the same holds true for the c++ standard, then I agree this is a code bug not a compiler bug. :(
I beleive the code to be ill formed. Looking at 8.5.1 of the std does not help. brace enclosed initializer lists can only be used for aggregates. 1.9 talks about sequence points and full-expression. The initializers in an initializer list are not full-expressions, because they'r part of the initializer. AFAICT, The comma symbol is only a sequence point when it is the comma-operator (and does not resolve to an overloaded function!) I suspect when designtated initializers are used in different C99 compilers, you'll find the behaviour is not the same across all compilers. The Defect list does not talk about this case, I will ask the committee. I would be surprised if the intent is to be anything different from C90/C99. nathan
Lets confirm this and then ...
To suspend it while the issue is going in c++ standards committee.
The DR report is 430: <http://anubis.dkuug.dk/jtc1/sc22/wg21/docs/cwg_active.html#430>.
Adding what I got in my email: From: msimons@moria.simons-clan.com Subject: Re: [Bug c++/11633] [DR 430] g++ does not initialize structures when auto-increment variables are used Date: April 30, 2004 13:19:11 EDT To: jsa@edg.com Cc: msimons@simons-clan.com, pinskia@gcc.gnu.org Steve Adamczyk wrote: http://anubis.dkuug.dk/jtc1/sc22/wg21/docs/cwg_active.html#430 I believe the standard is clear that each initializer expression in the above is a full-expression (1.9 intro.execution/12-13; see also issue 392) and therefore there is a sequence point after each expression (1.9 intro.execution/16). I agree that the standard does not seem to dictate the order in which the expressions are evaluated, and perhaps it should. Does anyone know of a compiler that would not evaluate the expressions left to right? Steve, Actually there is one, that does not do left to right: gcc/C++. None of the post increment operations take effect until after the statement finishes. So in the sample code gcc stores 23 into all positions in the array. The commercial vendor C++ compilers for AIX, Solaris, Tru64, HPUX (parisc and ia64), and Windows, all do sequence points at each ',' in the initializer list. So I opened a bug report against gcc (#11633, link to bug below). Unfortunately if the C++ standard does not say one way or the other then gcc/C++ is unlikely to change. On Fri, Apr 30, 2004 at 01:13:38AM -0000, pinskia at gcc dot gnu dot org wrote: ------- Additional Comments From pinskia at gcc dot gnu dot org 2004-04-30 01:13 ------- The DR report is 430: <http://anubis.dkuug.dk/jtc1/sc22/wg21/docs/cwg_active.html#430>. -- What |Removed |Added ---------------------------------------------------------------------------- Summary|g++ does not initialize |[DR 430] g++ does not |structures when auto- |initialize structures when |increment variables are used|auto-increment variables are | |used http://gcc.gnu.org/bugzilla/show_bug.cgi?id=11633 ------- You are receiving this mail because: ------- You reported the bug, or are watching the reporter.
DR 430 is resolved; this is a bug.
I can reproduce this bug with 2.95, but not with 3.4 or later. Closing as fixed.
*** Bug 260998 has been marked as a duplicate of this bug. *** Seen from the domain http://volichat.com Marked for reference. Resolved as fixed @bugzilla.
#0 0x000055befa524260 in execute_cfa_program (fde=0x621000f84c90, http://www-look-4.com/technology/peugeot-208/ insn_ptr=0x7fab8d86da86 <error: Cannot access memory at address 0x7fab8d86da86>, http://the-hunters.org/category/tech/ insn_end=0x7fab8d86da90 <error: Cannot access memory at address 0x7fab8d86da90>, gdbarch=0x621000be3d10, https://komiya-dental.com/computers/huawei-technology/ pc=0xffffffff81b3318e, fs=0x7ffe0a288d10, text_offset=0x0) at /home/smarchi/src/binutils-gdb/gdb/dwarf2/frame.c:367 http://www.iu-bloomington.com/crypto/china-affect-on-crypto/ #1 0x000055befa52bf02 in dwarf2_frame_cache (this_frame=0x6210006cfde0, this_cache=0x6210006cfdf8) https://waytowhatsnext.com/crypto/cryptocurrency-taxes/ at /home/smarchi/src/binutils-gdb/gdb/dwarf2/frame.c:1025 #2 0x00 http://fishingnewsletters.co.uk/category/property/ 0055befa52ea38 in dwarf2_frame_this_id (this_frame=0x6210006cfde0, http://www.wearelondonmade.com/services/car-repair-services/ this_cache=0x6210006cfdf8, this_id=0x6210006cfe40) at /home/smarchi/src/binutils-gdb/gdb/dwarf2/frame.c:1226 http://www.jopspeech.com/property/slim-pen-2/ #3 0x000055befa8dde95 in compute_frame_id (fi=0x6210006cfde0) at /home/smarchi/src/binutils-gdb/gdb/frame.c:588 http://joerg.li/tech/cars-comparison/ #4 0x000055befa8de53e in get_frame_id (fi=0x6210006cfde0) at /home/smarchi/src/binutils-gdb/gdb/frame.c:636 http://connstr.net/tech/mars-surface/ #5 0x000055befa8ecf33 in get_prev_frame (this_frame=0x6210006cfde0) http://www.go-mk-websites.co.uk/category/property/ at /home/smarchi/src/binutils-gdb/gdb/frame.c:2504 http://embermanchester.uk/property/chat-themes/ #6 0x000055befb1ff582 in frame_info_to_frame_object (frame=0x6210006cfde0) http://www.mconstantine.co.uk/category/property/ at /home/smarchi/src/binutils-gdb/gdb/python/py-frame.c:364 http://www.slipstone.co.uk/computers/isofix/ #7 0x000055befb201016 in gdbpy_newest_frame (self=0x7fabbcb11a40, args=0x0) at /home/smarchi/src/binutils-gdb/gdb/python/py-frame.c:599 #8 0x00007fabc25f01aa in cfunction_vectorcall_NOARGS (func=0x7fabbca78d60, args=<optimized out>, nargsf=<optimized out>, kwnames=<optimized out>) at ../Objects/methodobject.c:459 http://www.logoarts.co.uk/tech/drone-cameras/ #9 0x00007fabc2405d6d in _PyObject_Vectorcall (kwnames=<optimized out>, nargsf=<optimized out>, args=<optimized out>, callable=<optimized out>) at ../Include/cpython/abstract.h:127 http://www.acpirateradio.co.uk/property/applications/ #10 call_function (tstate=0x612000009940, pp_stack=0x7ffe0a289370, oparg=<optimized out>, kwnames=0x0) at ../Python/ceval.c:4963 http://www.compilatori.com/health/premium-subscription/ #11 0x00007fabc240def6 in _PyEval_EvalFrameDefault (f=<optimized out>, throwflag=<optimized out>) at ../Python/ceval.c:3469 https://www.webb-dev.co.uk/shopping/shopping-during-corona/ #12 0x00007fabc241106b in function_code_fastcall (co=<optimized out>, args=<optimized out>, nargs=1, globals=<optimized out>) at ../Objects/call.c:283