[cfe-dev] 'braces around scalar initializer' warning, should be error?

Richard Smith via cfe-dev cfe-dev at lists.llvm.org
Thu Dec 20 11:08:57 PST 2018


[Adding back cfe-dev]

On Wed, 19 Dec 2018 at 08:11, will wray <wjwray at gmail.com> wrote:

> Thanks, as ever, for your detailed explanation and for clarifying my
> question as C++ related.
>
> Here's a Christmas tree (in concept): https://concept.godbolt.org/z/aFoGUL
>
> template <class T> concept braces0 = requires {    T{0};    };
> template <class T> concept braces1 = requires {   T{{0}};   };
> template <class T> concept braces2 = requires {  T{{{0}}};  };
> template <class T> concept braces3 = requires { T{{{{0}}}}; };
>
> So, for our class S with single scalar member we'd expect braces2<S> and
> on to evaluate false.
> But Clang evaluates all as true - it doesn't catch the error in the
> expression (well, declaration statement)
> in this unevaluated context (same in conventional sfinae attempts).
>
> Is this expected behaviour?
>

No, that looks like a bug. Here's a testcase against clang trunk:
https://gcc.godbolt.org/z/wLXqPD

ICC and MSVC get this right; GCC and Clang get it wrong in two different
ways.


> On Tue, Dec 18, 2018 at 8:35 PM Richard Smith <richard at metafoo.co.uk>
> wrote:
>
>> (For clarity, since you didn't say, I'm assuming this is a question about
>> C++, and I'm going to assume you mean Clang's default C++ mode, C++14.)
>>
>> On Tue, 18 Dec 2018 at 12:17, will wray via cfe-dev <
>> cfe-dev at lists.llvm.org> wrote:
>>
>>> *    struct S { int i; };*
>>>
>>> *    S s{{0}};*
>>> *Clang*: `*warning*: braces around scalar initializer
>>> [-Wbraced-scalar-init]`
>>>
>>> or, with more braces:
>>>
>>>  `*warning*: too many braces around scalar initializer
>>> [-Wmany-braces-around-scalar-init]
>>> (consistent as a warning since at least clang 3.0.0)
>>>
>>> *GCC*: `*error*: braces around scalar initializer for type 'int'`
>>>
>>> (consistent as an error since ~gcc 4.4.7)
>>>
>>> *MSVC*: no warning (with \Wall)
>>> *Intel*: warning #1119: extra braces are nonstandard
>>>
>>> I believe that this is a non-standard extension in Clang. Can anyone
>>> confirm?
>>>
>>
>> Nope, this is valid, and I'm frankly stunned that GCC rejects.
>>
>> C++14 [dcl.init.aggr]/2 says: "Each member is copy-initialized from the
>> corresponding initializer-clause. [...] [ Note: If an initializer-clause is
>> itself an initializer list, the member is list-initialized, which will
>> result in a recursive application of the rules in this section if the
>> member is an aggregate.  — end note ]"
>> C++14 [dcl.init.list]/3.5: "Otherwise, if the initializer list has a
>> single element of type E and either T is not a reference type or its
>> referenced type is reference-related to E, the object or reference is
>> initialized from that element;"
>>
>> In fact, it's valid in every revision of C++ since C++11. (It was
>> ill-formed in C++98, which allowed int n = {0}, but not S s = {{0}};, but
>> the syntax you used was added in C++11.)
>>
>> The fact that clang accepts
>>
>> struct S { int i; };
>> S s = {{0}};
>>
>> in C++98 mode under -pedantic-errors is a (minor) bug.
>>
>> Does the standard does mandate an error here?
>>> If so then is there any flag to make this an error in Clang?
>>> (-pedantic-errors flag makes no difference, for gcc or for clang.)
>>> Maybe it's for MSVC / EDG compatibility? Or C compatibility? What reason?
>>>
>>> An error allows compile-time code to distinguish between scalar and
>>> non-scalar,
>>> to count the number of allowable braces and so to detect array rank &
>>> dims.
>>>
>>> On the other hand, an error forces different syntax for initializing
>>> scalar and non-scalar
>>> so disallows generic 'uniform' braced-init syntax where there may be
>>> scalars.
>>>
>>> Thanks for any thoughts,
>>> Will
>>>
>>> Here are some issues/DRs & commits that may or may not be relevant
>>> An old pre-11 issue
>>> 632. Brace-enclosed initializer for scalar member of aggregate
>>> <http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#632>
>>> explains that this was a C/C++ incompatibility, says it was resolved by Initializer
>>> Lists
>>> <http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2008/n2672.htm>
>>> (LOL) (I can't see how or where it is resolved)
>>>
>>
>> See above.
>>
>>
>>> h1501. Nested braces in list-initialization
>>> <http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_closed.html#1501>
>>>
>>
>> As noted here, one set of braces around a scalar initialization is
>> permitted, and two or more sets is invalid. So:
>>
>> S s = {{{0}}}; // error
>>
>> and indeed for that Clang reports
>>
>> error: too many braces around scalar initializer
>> [-Werror,-Wmany-braces-around-scalar-init]
>> S s = {{{0}}};
>>         ^~~
>>
>> As part of changes for DR1467 List-initialization of aggregate from
>>> same-type object
>>> <http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#1467>
>>> this Clang commit
>>> r228896
>>> <http://lists.llvm.org/pipermail/cfe-commits/Week-of-Mon-20150209/123171.html>-
>>> Improve the "braces around scalar init" warning to determine whether to warn
>>> _______________________________________________
>>> cfe-dev mailing list
>>> cfe-dev at lists.llvm.org
>>> http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-dev
>>>
>>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.llvm.org/pipermail/cfe-dev/attachments/20181220/4bfc30b4/attachment-0001.html>


More information about the cfe-dev mailing list