Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

{}

64 views
Skip to first unread message

Daniel

unread,
Sep 4, 2019, 8:58:36 AM9/4/19
to
Consider

#include <iostream>
#include <initializer_list>

struct arg_t
{
};

constexpr arg_t arg = arg_t();

class C
{
public:
C(size_t n) {}
};

class A
{
public:
explicit A(size_t n)
{
std::cout << "1\n";
}
A(std::initializer_list<C> item)
{
std::cout << "2\n";
}
A(arg_t, size_t n)
{
std::cout << "3\n";
}
A(arg_t, std::initializer_list<C> item)
{
std::cout << "4\n";
}
};

int main()
{
A a{ { 2 } }; // (1)
A b{ arg, { 2 } }; // (2)
}

Output (vs2019):

2
3

I don't understand why one of these constructors is using the
initializer_list, and the other is not. Explanation?

Thanks,
Daniel

Ian Collins

unread,
Sep 4, 2019, 2:59:50 PM9/4/19
to
Does the compiler issue any warnings?

gcc gives your expected result (2,4), clang thinks you intended to call
A(arg_t, size_t n) and issues a warning

/tmp/x.cc:40:15: warning: braces around scalar initializer
[-Wbraced-scalar-init]
A b{ arg, { 2 } }; // (2)
^~~~~~

I'm not sure which one is correct in this case!

Cheers,
Ian.

Daniel

unread,
Sep 4, 2019, 3:48:51 PM9/4/19
to
Thanks for the observations, I thought I understood the issues with the
uniform initialization and std::initializer_list, but I don't understand this
result. vs2019 doesn't give any warnings at level 4, apart from my
unreferenced parameters.

Best regards,
Daniel

Manfred

unread,
Sep 5, 2019, 8:12:56 AM9/5/19
to
To me, it looks like gcc is the correct one.

Öö Tiib

unread,
Sep 5, 2019, 11:24:51 AM9/5/19
to
It may be unsure and so it is bad that only clang warns about it.
The [dcl.init.list] has felt ambiguous since 2011 and so
gcc, clang, MSVC and ICC have had slight differences with
those initializer_lists.
Current issue seems to be about differences of interpretation
of "list has a single element" special cases in it.

Manfred

unread,
Sep 5, 2019, 2:52:36 PM9/5/19
to
Thanks for the link.
Indeed the wording seems ambiguous, and even the examples in (1.10) are
of limited help:
int a = {1};
...
return { "Norah" }; // return list of one element

What would be the rationale to distinguish between these two cases?

Reading on, you probably mean clause (3.8). Here the examples focus on
the constructor syntax only, but indeed there is a problem on where a
single object or a list of one object is initialized.

Daniel

unread,
Sep 5, 2019, 4:23:48 PM9/5/19
to
On Thursday, September 5, 2019 at 11:24:51 AM UTC-4, Öö Tiib wrote:

> It may be unsure and so it is bad that only clang warns about it.
> The [dcl.init.list] has felt ambiguous since 2011 and so
> gcc, clang, MSVC and ICC have had slight differences with
> those initializer_lists.
> Current issue seems to be about differences of interpretation
> of "list has a single element" special cases in it.

This appears to be the issue

https://wg21.cmeerw.net/cwg/issue1589

There is a suggested resolution that applies to 1589 in

https://wg21.cmeerw.net/cwg/issue1467

Anyone can tell me what is status "cd4"?

Thanks,
Daniel

Öö Tiib

unread,
Sep 6, 2019, 2:44:38 AM9/6/19
to
On Thursday, 5 September 2019 23:23:48 UTC+3, Daniel wrote:
>
> Anyone can tell me what is status "cd4"?

The "C++ Standard Core Language Active Issues" document describes it as:
"CD4: A DR/DRWP or Accepted/WP issue not resolved in C++14 but included in the Committee Draft advanced for balloting at the June, 2014 WG21 meeting."
<http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html>

Öö Tiib

unread,
Sep 6, 2019, 5:07:09 AM9/6/19
to
In layman terms CD4 means that the changes proposed made it into C++17.

My current impression is that clang does not do what
[over.ics.rank] of C++17 seems to say. The
<https://clang.llvm.org/cxx_dr_status.html> shows that they
consider themselves good with 1467 and 1589 since clang 3.7.
Yet there are differences:

#include <initializer_list>
#include <string>
#include <iostream>

void f1(int)
{
std::cout << "f1 1\n";
}

void f1(std::initializer_list<long>)
{
std::cout << "f1 2\n";
}

void foo(char const*)
{
std::cout << "foo 1\n";
}

void foo(std::initializer_list<std::string>)
{
std::cout << "foo 2\n";
}

int main()
{
f1({42}); // both output fl 2 like standard suggests
foo({"bar"}); // clang outputs foo 1, g++ outputs foo 2
// despite standard seems to suggest foo 2
}

Daniel

unread,
Sep 6, 2019, 2:28:07 PM9/6/19
to
On Friday, September 6, 2019 at 5:07:09 AM UTC-4, Öö Tiib wrote:
>
> In layman terms CD4 means that the changes proposed made it into C++17.
>
Thanks :-)
Daniel
0 new messages