This is the mail archive of the
gcc-bugs@gcc.gnu.org
mailing list for the GCC project.
[Bug c++/84464] New: Pack expansion in mem-initializer-list with expression-list
- From: "tadeus.prastowo at unitn dot it" <gcc-bugzilla at gcc dot gnu dot org>
- To: gcc-bugs at gcc dot gnu dot org
- Date: Mon, 19 Feb 2018 14:53:05 +0000
- Subject: [Bug c++/84464] New: Pack expansion in mem-initializer-list with expression-list
- Auto-submitted: auto-generated
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=84464
Bug ID: 84464
Summary: Pack expansion in mem-initializer-list with
expression-list
Product: gcc
Version: 7.3.0
Status: UNCONFIRMED
Severity: normal
Priority: P3
Component: c++
Assignee: unassigned at gcc dot gnu.org
Reporter: tadeus.prastowo at unitn dot it
Target Milestone: ---
I am referring to C++14 standard
(http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2013/n3797.pdf) for the
following problem. Section 12.6.2 "Initializing bases and members" paragraph 1
says that mem-initializer can either be mem-initializer-id(expression-list_opt)
or mem-initializer-id braced-init-list, and mem-initializer... is a valid
construct. But, GCC rejects the first alternative of the valid construct but
accepts the second alternative of the valid construct as demonstrated by the
following program. Since both alternatives are valid constructs, GCC shall
accept the first alternative as well.
GCC cannot compile the following program (cf. https://godbolt.org/g/QWj5Q3),
but Clang can (cf. https://godbolt.org/g/jA7Z8H). I use flag `-std=c++14'.
#include <cstdio>
struct C1 {
bool a;
float b;
C1(bool x, float y) : a(x), b(y) {}
};
struct C2 {
bool c;
float d;
C2(bool x, float y) : c(x), d(y) {}
};
struct C3 {
bool e;
float f;
C3(bool x, float y) : e(x), f(y) {}
};
template<class... baseclasses>
struct A : public baseclasses...
{
template<class... Ts> A(Ts... args) : baseclasses(args...)... {
// This uses mem-initializer-id(expression-list_opt).
// Section 5.2 par 1 says that expression-list is initializer-list.
// Section 8.5 par 1 says that initializer-list can be
// initializer-clause... with initializer-clause being
// assignment-expression.
// Section 5.17 par 1 says that assignment-expression can boil down
// to an identifier, for example, args.
// So, the construct is valid as far as I can see. But,
// g++ 5.4.1 fails with: invalid use of pack expansion expression.
// g++ 7.3.0 fails with: no matching function for call to
// ‘C1::C1(bool)’.
// The fix is to use mem-initializer-id braced-init-list as in:
// : baseclasses{args...}...
}
};
int main() {
A<C1, C2, C3> a(true, 1.0F);
std::printf("%d %f %d %f %d %f\n", a.a, a.b, a.c, a.d, a.e, a.f);
}