'braces around scalar initializer' warning, should be error?

classic Classic list List threaded Threaded
7 messages Options
Reply | Threaded
Open this post in threaded view
|

'braces around scalar initializer' warning, should be error?

Richard Smith via cfe-dev
    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?
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
explains that this was a C/C++ incompatibility, says it was resolved by Initializer Lists
(LOL) (I can't see how or where it is resolved)
this Clang commit
r228896 - Improve the "braces around scalar init" warning to determine whether to warn

_______________________________________________
cfe-dev mailing list
[hidden email]
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-dev
Reply | Threaded
Open this post in threaded view
|

Re: 'braces around scalar initializer' warning, should be error?

Richard Smith via cfe-dev
(^^^ sorry for the duff formatting)

Promoting warnings to errors doesn't work as I'd hoped
as the resulting errors are not detected in requires clauses:

using flags
  -Werror=braced-scalar-init 
  -Werror=many-braces-around-scalar-init

    struct S { int i; };

    template <class S>
    inline constexpr bool braces0 = requires { S{0}; };

    static_assert(braces0<S>);

    template <class S>
    inline constexpr bool braces1 = requires { S{{0}}; };

    static_assert(!braces1<S>);

The second assert fails on Clang (experimental concepts build)


On Tue, Dec 18, 2018 at 3:16 PM will wray <[hidden email]> 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?
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
explains that this was a C/C++ incompatibility, says it was resolved by Initializer Lists
(LOL) (I can't see how or where it is resolved)
this Clang commit
r228896 - Improve the "braces around scalar init" warning to determine whether to warn

_______________________________________________
cfe-dev mailing list
[hidden email]
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-dev
Reply | Threaded
Open this post in threaded view
|

Re: 'braces around scalar initializer' warning, should be error?

Richard Smith via cfe-dev
In reply to this post by Richard Smith via cfe-dev
(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 <[hidden email]> 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
explains that this was a C/C++ incompatibility, says it was resolved by Initializer Lists
(LOL) (I can't see how or where it is resolved)

See above.
 

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}}};
        ^~~

this Clang commit
r228896 - Improve the "braces around scalar init" warning to determine whether to warn
_______________________________________________
cfe-dev mailing list
[hidden email]
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-dev

_______________________________________________
cfe-dev mailing list
[hidden email]
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-dev
Reply | Threaded
Open this post in threaded view
|

Re: 'braces around scalar initializer' warning, should be error?

Richard Smith via cfe-dev
[Adding back cfe-dev]

On Wed, 19 Dec 2018 at 08:11, will wray <[hidden email]> 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 <[hidden email]> 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 <[hidden email]> 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
explains that this was a C/C++ incompatibility, says it was resolved by Initializer Lists
(LOL) (I can't see how or where it is resolved)

See above.
 

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}}};
        ^~~

this Clang commit
r228896 - Improve the "braces around scalar init" warning to determine whether to warn
_______________________________________________
cfe-dev mailing list
[hidden email]
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-dev

_______________________________________________
cfe-dev mailing list
[hidden email]
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-dev
Reply | Threaded
Open this post in threaded view
|

Re: 'braces around scalar initializer' warning, should be error?

Richard Smith via cfe-dev
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
 - 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 <[hidden email]> wrote:
[Adding back cfe-dev]

On Wed, 19 Dec 2018 at 08:11, will wray <[hidden email]> 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 <[hidden email]> 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 <[hidden email]> 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
explains that this was a C/C++ incompatibility, says it was resolved by Initializer Lists
(LOL) (I can't see how or where it is resolved)

See above.
 

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}}};
        ^~~

this Clang commit
r228896 - Improve the "braces around scalar init" warning to determine whether to warn
_______________________________________________
cfe-dev mailing list
[hidden email]
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-dev

_______________________________________________
cfe-dev mailing list
[hidden email]
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-dev
Reply | Threaded
Open this post in threaded view
|

Re: 'braces around scalar initializer' warning, should be error?

Richard Smith via cfe-dev
On Thu, 20 Dec 2018 at 12:22, will wray via cfe-dev <[hidden email]> wrote:
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?

Should be fixed in r349820. (Our "extension" diagnostics should probably cause SFINAE failures by default, but for now I've just marked this particular one as doing so.)
 
Will

* The lib extends magic_get to support array type aggregate members
 - 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.

Clang trunk accepts:

valid a = braces1<int[1]>(0);
valid b = braces2<int[1]>(0);
invalid c = braces3<int[1]>(0);

struct X { int n[1]; };
valid d = braces1<X>(0);
valid e = braces2<X>(0);
valid f = braces3<X>(0);                              

... which I believe is correct. (int[1] allows one more set of braces than int.)
 
On Thu, Dec 20, 2018 at 2:09 PM Richard Smith <[hidden email]> wrote:
[Adding back cfe-dev]

On Wed, 19 Dec 2018 at 08:11, will wray <[hidden email]> 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 <[hidden email]> 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 <[hidden email]> 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
explains that this was a C/C++ incompatibility, says it was resolved by Initializer Lists
(LOL) (I can't see how or where it is resolved)

See above.
 

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}}};
        ^~~

this Clang commit
r228896 - Improve the "braces around scalar init" warning to determine whether to warn
_______________________________________________
cfe-dev mailing list
[hidden email]
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-dev
_______________________________________________
cfe-dev mailing list
[hidden email]
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-dev

_______________________________________________
cfe-dev mailing list
[hidden email]
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-dev
Reply | Threaded
Open this post in threaded view
|

Re: 'braces around scalar initializer' warning, should be error?

Richard Smith via cfe-dev
Your fix is live on compiler explorer already - an early present delivered in time for xmas.

And, of course, it does allow to distinguish scalar member from array-of-one-scalar,
just by testing one more set of braces.

Excellent service, thanks.

I'll take a look at gcc bugzilla today and see about reporting that braced-scalar error as a bug.


On Thu, Dec 20, 2018 at 4:04 PM Richard Smith <[hidden email]> wrote:
On Thu, 20 Dec 2018 at 12:22, will wray via cfe-dev <[hidden email]> wrote:
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?

Should be fixed in r349820. (Our "extension" diagnostics should probably cause SFINAE failures by default, but for now I've just marked this particular one as doing so.)
 
Will

* The lib extends magic_get to support array type aggregate members
 - 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.

Clang trunk accepts:

valid a = braces1<int[1]>(0);
valid b = braces2<int[1]>(0);
invalid c = braces3<int[1]>(0);

struct X { int n[1]; };
valid d = braces1<X>(0);
valid e = braces2<X>(0);
valid f = braces3<X>(0);                              

... which I believe is correct. (int[1] allows one more set of braces than int.)
 
On Thu, Dec 20, 2018 at 2:09 PM Richard Smith <[hidden email]> wrote:
[Adding back cfe-dev]

On Wed, 19 Dec 2018 at 08:11, will wray <[hidden email]> 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 <[hidden email]> 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 <[hidden email]> 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
explains that this was a C/C++ incompatibility, says it was resolved by Initializer Lists
(LOL) (I can't see how or where it is resolved)

See above.
 

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}}};
        ^~~

this Clang commit
r228896 - Improve the "braces around scalar init" warning to determine whether to warn
_______________________________________________
cfe-dev mailing list
[hidden email]
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-dev
_______________________________________________
cfe-dev mailing list
[hidden email]
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-dev

_______________________________________________
cfe-dev mailing list
[hidden email]
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-dev