Unlike GCC in C mode, G++ accepts explicitly initialized variable length arrays (as specified in WG21 N3639, http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2013/n3639.html). However, when initializing VLAs with more elements than explicitly specified in the initializer, G++ fails to zero-initialize the remaining elements as would be the case for ordinary arrays. The following test case demonstrates the problem: cat z.cpp && /build/gcc-trunk/gcc/xgcc -B /build/gcc-trunk/gcc -Wall -Wextra -Wpedantic z.cpp && ./a.out void __attribute__ ((noclone, noinline)) bar (int n) { const int m = 2; char a [m][n] = { { 0, 1, 2 } }; for (int i = 0; i < m; ++i) for (int j = 0; j < n; ++j) __builtin_printf ("%hhi ", a [i][j]); __builtin_printf ("\n"); if (a [0][n - 1] != 0) __builtin_abort (); } int main () { bar (4); } z.cpp: In function ‘void bar(int)’: z.cpp:4:15: warning: ISO C++ forbids variable length array ‘a’ [-Wvla] char a [m][n] = { { 0, 1, 2 } }; ^ 0 1 2 12 -1 127 0 0 Aborted (core dumped)
I believe this case is simply not supported by the output machinery. It's probably substantial work to get it working unless the FE always emits a full zero init of the VLA and then the partial init from the CONSTRUCTOR.
(In reply to Martin Sebor from comment #0) > Unlike GCC in C mode, G++ accepts explicitly initialized variable length > arrays (as specified in WG21 N3639, > http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2013/n3639.html). > However, when initializing VLAs with more elements than explicitly specified > in the initializer, G++ fails to zero-initialize the remaining elements as > would be the case for ordinary arrays. > > The following test case demonstrates the problem: > > cat z.cpp && /build/gcc-trunk/gcc/xgcc -B /build/gcc-trunk/gcc -Wall > -Wextra -Wpedantic z.cpp && ./a.out > void __attribute__ ((noclone, noinline)) bar (int n) > { > const int m = 2; > char a [m][n] = { { 0, 1, 2 } }; > > for (int i = 0; i < m; ++i) > for (int j = 0; j < n; ++j) > __builtin_printf ("%hhi ", a [i][j]); > __builtin_printf ("\n"); > > if (a [0][n - 1] != 0) > __builtin_abort (); > } > > int main () > { > bar (4); > } > z.cpp: In function ‘void bar(int)’: > z.cpp:4:15: warning: ISO C++ forbids variable length array ‘a’ [-Wvla] > char a [m][n] = { { 0, 1, 2 } }; > ^ > 0 1 2 12 -1 127 0 0 > Aborted (core dumped) I get this output on i386-apple-darwin9.8.0 with gcc8: $ /usr/local/bin/g++ -Wall -Wextra -Wpedantic -o 70075.exe 70075.cc 70075.cc: In function ‘void bar(int)’: 70075.cc:4:13: warning: ISO C++ forbids variable length array ‘a’ [-Wvla] char a[m][n] = { { 0, 1, 2 } }; ^ $ ./70075.exe 0 1 2 0 0 0 -32 -113 $ (i.e. no errors)
(In reply to Eric Gallager from comment #2) > > I get this output on i386-apple-darwin9.8.0 with gcc8: > > $ /usr/local/bin/g++ -Wall -Wextra -Wpedantic -o 70075.exe 70075.cc > 70075.cc: In function ‘void bar(int)’: > 70075.cc:4:13: warning: ISO C++ forbids variable length array ‘a’ [-Wvla] > char a[m][n] = { { 0, 1, 2 } }; > ^ > $ ./70075.exe > 0 1 2 0 0 0 -32 -113 > $ > > (i.e. no errors) Running the program on x86_64-apple-darwin10.8.0 with gcc9, it prints this instead: 0 1 2 0 9 0 0 0 (still no errors though)
*** Bug 95993 has been marked as a duplicate of this bug. ***
(In reply to Eric Gallager from comment #3) > (In reply to Eric Gallager from comment #2) > > > > I get this output on i386-apple-darwin9.8.0 with gcc8: > > > > $ /usr/local/bin/g++ -Wall -Wextra -Wpedantic -o 70075.exe 70075.cc > > 70075.cc: In function ‘void bar(int)’: > > 70075.cc:4:13: warning: ISO C++ forbids variable length array ‘a’ [-Wvla] > > char a[m][n] = { { 0, 1, 2 } }; > > ^ > > $ ./70075.exe > > 0 1 2 0 0 0 -32 -113 > > $ > > > > (i.e. no errors) > > Running the program on x86_64-apple-darwin10.8.0 with gcc9, it prints this > instead: > 0 1 2 0 9 0 0 0 > (still no errors though) Update for gcc 11 on x86_64-apple-darwin19.6.0: 0 1 2 0 0 0 0 0 So, not only are there no errors now, but it also looks like everything after the "0 1 2" is now properly zero-initialized? FIXED?