clang produces a static initializer when initializing an array of a struct that has a volatile field that is initialized via a constrexpr ctor |
||
Issue descriptionI was about to file this on https://llvm.org/bugs, but it looks like it takes an account and the account requires to send an email to the list admins :/ I'll move it there once I get an account, in the meantime filing here or I'll forget about this. I just found this very interesting behavior of Clang/LLVM. if I: 1. Initialize a global array of class/struct X 2. X has a constrexpr ctor which initializes a field X.v 3. X.v is volatile The constrexpr ctor ends up generating a static initializer anyways. g++ doesn't seem to be affected by this. This weird behavior happens only if initializing an array. Everything works fine if I initialize just one instance. -O{0,2,3} don't seem to make a difference. Repro (code below): $ /s/chrome/src/third_party/llvm-build/Release+Asserts/bin/clang++ -o clang_bug clang_bug.cc --std=c++11 && ./clang_bug a:42 a_arr:0 <------------------- !!! b:42 b_arr:42 c:42 c_arr:42 $ g++ -o clang_bug clang_bug.cc --std=c++11 && ./clang_bug a:42 a_arr:42 b:42 b_arr:42 c:42 c_arr:42 Interestingly if I use -Wglobal-constructors, clang warns about both |a| and |a_arr|, but only |a_arr| seems affected: ----- clang_bug.cc:23:3: warning: declaration requires a global constructor [-Wglobal-constructors] A a = {}; ^ ~~ clang_bug.cc:24:3: warning: declaration requires a global constructor [-Wglobal-constructors] A a_arr[1] = { {} }; ----- $ cat clang_bug.cc #include <stdio.h> class A { public: constexpr A(): v(42) {} volatile unsigned char v; }; class B { public: constexpr B(): v(42) {} unsigned char v; }; struct C { volatile unsigned char v; }; bool Initializer(); bool init = Initializer(); A a = {}; A a_arr[1] = { {} }; B b = {}; B b_arr[1] = { {} }; C c = {42}; C c_arr[1] = { {42} }; bool Initializer() { printf("a:%d a_arr:%d\n", a.v, a_arr[0].v); printf("b:%d b_arr:%d\n", b.v, b_arr[0].v); printf("c:%d c_arr:%d\n", c.v, c_arr[0].v); return true; } int main() { return 0; }
,
Oct 31 2016
> Playing with initialization order in C++ is like playing with fire, and now you're mixing in constexpr and volatile too :-) Well, what I'm ultimately trying to achieve is to have no initialization at all and have all this being linker initialized. at the end the final result should be ismple, as it involves no code at all and just injecting a bit of zeros and ones in the .rwdata. In practice, I seem to fail to convince the various compilers about what I want them to do. > Trying to wrap my head around your example, I shortened it a little: Right, A, B and C in my example was the sequence of tests that led me to think that the problem is "volatile".
,
Oct 31 2016
This is what Richard said on IRC: > a class with a volatile member is not a literal type > in c++11, there was a special rule that guaranteed constant initialization in that special case, which is why the "S s;" case gets constant initialization > in c++14 onwards, that special case is extended to volatile subobjects nested somewhat arbitrarily > gcc appears to be miscompiling arr2; i would guess that it's incorrectly imagining that a copy is performed for the array element So.. not sure what GCC is up to, but at least that explains Clang's behaviour, and if you turn on -std=c++14, Clang will also constant-initialize arr1 and arr2. And yes, "volatile" is making things harder here, I suppose.
,
Oct 31 2016
Allright I'll not use volatile and volatilize the accessors. FWIW msvc seems aligned with gcc here. Thanks for digging further.
,
Nov 1 2017
This issue has been Available for over a year. If it's no longer important or seems unlikely to be fixed, please consider closing it out. If it is important, please re-triage the issue. Sorry for the inconvenience if the bug really should have been left as Available. If you change it back, also remove the "Hotlist-Recharge-Cold" label. For more details visit https://www.chromium.org/issue-tracking/autotriage - Your friendly Sheriffbot
,
Oct 22
Since we're now on C++14 and comment 3 says this is fine with C++14, is this still an issue? |
||
►
Sign in to add a comment |
||
Comment 1 by h...@chromium.org
, Oct 31 2016Status: Available (was: Untriaged)