Consider following code:
#include <iostream>
class A
{
char name[40] = { "Blank" }; // note the braces here
public:
const char *getName() { return name; }
};
int main()
{
A a;
std::cout << a.getName() << std::endl;
}
It gives an error in gcc
(latest version 5.2.0
):
prog.cpp:5:28: error: invalid conversion from 'const char*' to 'char' [-fpermissive]
char name[40] = { "Blank" };
^
But it's not the case for clang
, that compiles it flawlessly with -std=c++11 -pedantic -Wall
.
Is it really incorrect to put braces for non-static initializer here?
AFAIR it doesn't matter if braces are present or not. For instance, the definition of array, such as:
char text[] = "some text";
is equivalent to:
char text[] = { "some text" };
The code is valid, and is now accepted by GCC trunk. I think it was fixed by PR 65815 brace elision doesn't work in NSDMI
Well the standard is not very clear in my opinion, but I would say that CLang is right :
8.5.1 says :
§2 : When an aggregate is initialized by an initializer list, as specified in 8.5.4, the elements of the initializer list are taken as initializers for the members of the aggregate, in increasing subscript or member order. That is gcc interpretation : name is an array, there is a brace-init-list so first element of the array (a char) is initialized with the char array => error
But 8.5.2 explicitely says : An array of narrow character type ... can be initialized by a narrow string literal ... or by an appropriately-typed string literal enclosed in braces (emphasize mine)
My interpretation is that the standard consideres char arrays as special enough to explicitely allow a string literal enclosed in braces as valid even if it defeats 8.5.1 §2
From the C++ standard working draft n4527 [dcl.init]. An initialization can be written like :
Initializers
initializer: brace-or-equal-initializer ( expression-list ) brace-or-equal-initializer: = initializer-clause braced-init-list initializer-clause: assignment-expression braced-init-list initializer-list: initializer-clause...opt initializer-list,initializer-clause...opt braced-init-list: {initializer-list,opt} { }
A Class member declaration
member-declarator: declarator virt-specifier-seq opt pure-specifier opt declarator brace-or-equal-initializer opt
From what I read it seems like gcc does not meet the standard. Because the class member initialization using the braces is accepted by the standard.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With