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

will wray via cfe-dev cfe-dev at lists.llvm.org
Thu Dec 20 12:21:28 PST 2018


Ah, so same issue for actual scalars as for scalar members of aggregates.

This bug prevents a port of my lib* to Clang, so I'd like to see it
addressed.
There's no related bug report in Clang bugzilla AFAICT.

Shall I report?

Will

* The lib extends magic_get to support array type aggregate members
 as described here https://github.com/apolukhin/magic_get/issues/20
 - it relies on a sfinae / requires error to catch 'too-many-braces'.
This is a valuable niche use case, at least until static reflection arrives.

Oddly, the GCC bug that gives an error on single-brace-init of a scalar
member
allows to discriminate a scalar member from an array-of-one-scalar member -
it seems a conforming implementation can't distinguish, say, int from
int[1] -
but this ability comes at a cost of awkward non-uniform initialization
syntax.


On Thu, Dec 20, 2018 at 2:09 PM Richard Smith <richard at metafoo.co.uk> wrote:

> [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/136428e6/attachment.html>


More information about the cfe-dev mailing list