2

Consider the following program:

#include <iostream>
int main()
{
    int n = 3;
    int fact = 1;
    for(auto i{1};i<=n;i++)
        fact*=i;
    std::cout<<"fact of "<<n<<" is "<<fact;
}

It compiles fine on ideone even when I use -std=c++14 option. See live demo here. But in C++14 the variable i should be deduced as initializer_list according to this.

There is a proposal for C++1z that implements new type deduction rules for brace initialization:

For direct list-initialization:

  1. For a braced-init-list with only a single element, auto deduction will deduce from that entry;

  2. For a braced-init-list with more than one element, auto deduction will be ill-formed.

[Example:

auto x1 = { 1, 2 }; // decltype(x1) is std::initializer_list

auto x2 = { 1, 2.0 }; // error: cannot deduce element type

auto x3{ 1, 2 }; // error: not a single element

auto x4 = { 3 }; // decltype(x4) is std::initializer_list

auto x5{ 3 }; // decltype(x5) is int.

-- end example]

So, the rules changed in C++17. As such, the program shouldn't compile when I use -std=c++14. Is this bug in g++? Shouldn't the variable i deduced as initializer_list in C++14?

Community
  • 1
  • 1
Destructor
  • 14,123
  • 11
  • 61
  • 126
  • See [Different compiler behavior for expression: auto p {make_pointer()};](http://stackoverflow.com/q/31301369/1708801), it is unclear if the proposal mentioned in there should be applied to C++14 or not, there is conflicting information wrt to this. There is implementation divergence here as well. – Shafik Yaghmour Nov 03 '15 at 14:04
  • @ShafikYaghmour It looks like [the Clang devs intend to (eventually) apply this change retroactively too](http://lists.llvm.org/pipermail/cfe-commits/Week-of-Mon-20150209/123102.html). – T.C. Nov 03 '15 at 19:24
  • 1
    @T.C. thank you for digging that up, interesting but head is currently `3.8` and the behavior has not changed and it still doesn't answer whether this was decided as a defect or not :-( – Shafik Yaghmour Nov 03 '15 at 19:30

1 Answers1

6

There is a proposal for C++1z that implements new type deduction rules for brace initialization

Not exactly. If you follow the link to the actual paper, it reads:

Direction from EWG is that we consider this a defect in C++14.

Which is enough to get implementors to also treat it as a defect, and hence change the compiler behaviour even in C++14 mode.

  • 1
    You can make an argument that an implementation shouldn't treat it as a C++14 defect until there's an official DR, but I wouldn't be convinced by such an argument, I think the GCC behaviour is at least not wrong. –  Nov 03 '15 at 13:57
  • If you don't nip these things in the bud, the trailing edge of conformance can get a little out of hand. I'm reminded of the nightmare that is web browser compliance: `Microsoft said that Acid3 did not agree with the goal of [IE8] and that IE8 would improve only some of the standards... scored 20/100, which is much worse than all relevant competitors...` IMHO, GCC can step *exclusively* on toes if that's what it takes to keep that kind of divergence in check. – John P Dec 26 '17 at 14:57