Why was N3853/N3994 rejected?

481 views
Skip to first unread message

Barry Revzin

unread,
Jul 24, 2016, 12:32:46 PM7/24/16
to ISO C++ Standard - Future Proposals
STL proposed:
for (elem : range) { ... }

as synonymous with:
for (auto&& elem : range ) { ... }

This apparently got dropped from the ballot in Urbana. Does anybody know why it was rejected?

Ville Voutilainen

unread,
Jul 24, 2016, 12:44:34 PM7/24/16
to ISO C++ Standard - Future Proposals
Mostly because 'elem' can shadow names in the surrounding scope, and
such shadowing was deemed too subtle.
The opponents thought that even making such shadowing ill-formed
wouldn't change their mind. I can find some remarks
according to which introducing names without types is problematic for
some people. See
http://open-std.org/JTC1/SC22/WG21/docs/papers/2014/n4251.html
and search for "Straw poll, CWG Motion 15"

FrankHB1989

unread,
Jul 26, 2016, 10:39:14 PM7/26/16
to ISO C++ Standard - Future Proposals
在 2016年7月25日星期一 UTC+8上午12:44:34,Ville Voutilainen写道:

I don't know why they were worrying about that. First, a variable introduced by declaration ensures there exists the declarator of type, but not the type of that variable. To expect a variable mapping to some type in a first glance of its declaration is already error-prone. The only sensible way is to fully read and parse the declaration. Then, why the implicit 'auto&&' is a problem? It actually hides some semantic noise as well as syntactic one. Second, as said, lambda initializers have already invalidate the assumption of the existence of a declarator of some variable.

 

Bo Persson

unread,
Jul 27, 2016, 6:35:00 AM7/27/16
to std-pr...@isocpp.org
On 2016-07-27 04:39, FrankHB1989 wrote:
> 在 2016年7月25日星期一 UTC+8上午12:44:34,Ville Voutilainen写道:
>
> On 24 July 2016 at 19:32, Barry Revzin <barry....@gmail.com
I believe the committee saw the "subtleness" in comparing

int i;
for (i = 0; i != 10; ++i) // reusing outer i
for (int i = 0; i != 10; ++i) // introduces a new variable

and

int i;
for (i : range) // reusing outer i? no?
for (int i : range) // introduces a new variable

How are we to recognize that the second version introduces a new
variable in both cases, but the first one does not?



Bo Persson


D. B.

unread,
Jul 27, 2016, 6:47:35 AM7/27/16
to std-pr...@isocpp.org
For sure. It really doesn't cost anything to type auto &&, IMO. And certainly isn't worth that much ambiguity.

Tony V E

unread,
Jul 27, 2016, 12:18:57 PM7/27/16
to Standard Proposals
It is not the cost of typing, it is the cost of understanding auto &&.  It would be nice if a common usage was easier to learn.
But still not worth the price, IMO.

I think there are people still planning on proposing something in this area.

Tony

Ren Industries

unread,
Jul 27, 2016, 12:31:40 PM7/27/16
to std-pr...@isocpp.org
auto&& is trivial to understand and learn. What's the problem?

--
You received this message because you are subscribed to the Google Groups "ISO C++ Standard - Future Proposals" group.
To unsubscribe from this group and stop receiving emails from it, send an email to std-proposal...@isocpp.org.
To post to this group, send email to std-pr...@isocpp.org.
To view this discussion on the web visit https://groups.google.com/a/isocpp.org/d/msgid/std-proposals/CAOHCbitEG6uChd%3DD_TwE-h7e4Ekf_GaqJXH%3DqPN1a%3DqNJ6NbCA%40mail.gmail.com.

Nicol Bolas

unread,
Jul 27, 2016, 12:56:25 PM7/27/16
to ISO C++ Standard - Future Proposals
On Wednesday, July 27, 2016 at 12:31:40 PM UTC-4, Ren Industries wrote:
auto&& is trivial to understand and learn. What's the problem?

Learning to type `auto&&` in that case is "trivial to understand and learn". But that's hardly understanding why you're doing that instead of just `auto`, which is what many people are being trained to use whenever they declare variables.

FrankHB1989

unread,
Jul 28, 2016, 7:04:19 AM7/28/16
to ISO C++ Standard - Future Proposals
 
Maybe. I actually don't care much about the extra typing, though I don't like to see redundant syntactic noise when reading, either.

But I really don't appreciate the reason of rejection here, as most excuses raised about readability in disputation on endorsement of using of `auto` by default. (Teachability issue sounds more plausible to me.)

Parsing the contents between lparan and the initial semicolon after several tokens in a 'for' statement should be trivial daily work for C++ users. Note there is no ambiguity in grammar simply due to different 'for' statement once you have parsed the init-statement correctly. It should not be ambiguous easily for anyone who does read it carefully enough, otherwise the code must be badly constructed. Anyway, this kind of work can't be omitted if you want to know the meaning for the code. So I can hardly believe it is a real problem.

For the code illustrated... I think it would always be subtle enough if you only show the 'for' statement without the dummy variable declaration near the code. Keep them compact, please.

BTW, I have no need to target pre-C99 ancient dialects or (damnit!) VC6, so I haven't written 'for' statement whose init-statement is not a declaration for years. Everything is OK.

I'd even be glad if the ancient form of 'for' statement is deprecated, just to reduce the amount of naive excuses.

Matthew Woehlke

unread,
Jul 29, 2016, 7:20:15 PM7/29/16
to std-pr...@isocpp.org
On 2016-07-28 07:04, FrankHB1989 wrote:
> I'd even be glad if the ancient form of 'for' statement is deprecated, just
> to reduce the amount of naive excuses.

No. Declaring the iterator outside the loop also preserves its value
outside the loop. That is sometimes useful. Perhaps even more so with
range-based for which is less easily rewritten as a while loop.

--
Matthew

FrankHB1989

unread,
Jul 30, 2016, 5:56:48 AM7/30/16
to ISO C++ Standard - Future Proposals, mwoehlk...@gmail.com


在 2016年7月30日星期六 UTC+8上午7:20:15,Matthew Woehlke写道:
No. I did not suggest that. However, for any loop like

for(i = first; i != last; ++i)
 //...;

Practically, you should always be allowed to rewrite it as

i = first;
for(; i != last; ++i) // Where the first ';' is an empty declaration.
 //...

Or even:

i = first;
while(i != last)
{
  //...
  ++i;
}
As long as the names do not clash. Anyway, 'for' statement is a kind of syntax sugar. There is no need to have more than one flavor to work in general.

And unless you like extra '{}' around the loop, you have to allow the scoped syntax to avoid name pollution out of the loop in some cases, which are perhaps more common. (I also don't like raw do-while statement because it can't work in this way well.)


 

D. B.

unread,
Jul 30, 2016, 6:49:33 AM7/30/16
to std-pr...@isocpp.org
On Sat, Jul 30, 2016 at 10:56 AM, FrankHB1989 <frank...@gmail.com> wrote:
And unless you like extra '{}' around the loop, you have to allow the scoped syntax to avoid name pollution out of the loop in some cases, which are perhaps more common. (I also don't like raw do-while statement because it can't work in this way well.)

Speaking of which, I've been wondering why there was no while (type t = f(); t--) { /*...*/ } accepted alongside the if and switch versions coming in C++17.

I can only assume that it's because you can already do the same thing using for (type t = f(); t--; ) but then since we're already redundant, it wouldn't have hurt to add it for while too, surely?

Also, for doesn't cover the same semantics as do, so we could also add that: do ( type t = f() ) { /*...*/ } while ( cond() );

Might as well be consistent, otherwise the while keywords look kinda unmaintained and like they're kept around for compatibility only.

Nicol Bolas

unread,
Jul 30, 2016, 12:02:16 PM7/30/16
to ISO C++ Standard - Future Proposals

Well, they kinda are. Not for compatibility, but for the same reason we keep `goto` around. Because sometimes, you really need that one special tool, and it'd better be in your toolbox when you need it.

That doesn't mean it needs to be the most well-polished tool in your box.

Think about the ratio of `while` loops to `for` loops in your code. Think about the ratio of `while` loops to `do/while`. And the ratio of all of them to the number of `goto`. And with range-based algorithms, adapters, filters, and so forth on the way, these kinds of explicit control structures are only going to get even more rare.

So what's does it matter if they "look kinda unmaintained"? As long as they're in your toolbox when the need arises, it's fine. Indeed, the lack of elegant features helps get across the idea that these things should be avoided where reasonable.

FrankHB1989

unread,
Jul 31, 2016, 11:34:22 PM7/31/16
to ISO C++ Standard - Future Proposals


在 2016年7月30日星期六 UTC+8下午6:49:33,D. B.写道:
On Sat, Jul 30, 2016 at 10:56 AM, FrankHB1989 <frank...@gmail.com> wrote:
And unless you like extra '{}' around the loop, you have to allow the scoped syntax to avoid name pollution out of the loop in some cases, which are perhaps more common. (I also don't like raw do-while statement because it can't work in this way well.)

Speaking of which, I've been wondering why there was no while (type t = f(); t--) { /*...*/ } accepted alongside the if and switch versions coming in C++17.

I can only assume that it's because you can already do the same thing using for (type t = f(); t--; ) but then since we're already redundant, it wouldn't have hurt to add it for while too, surely?

Also, for doesn't cover the same semantics as do, so we could also add that: do ( type t = f() ) { /*...*/ } while ( cond() );

I personally even do not use "do-while" statement at all, exception a few cases. This is because the code is often concerned with variable only living in the scope of the loop body plus the condition, and "do-while" will almost always pollute the enclosing scope, leading to more pressure about naming. Instead, I invent my own wheel, specifically to replace almost all ordinary instances of "do-while" statement - not too intuitive, but handy. This eventually eliminate for new core features. (BTW, regular void will make it easier...)

 

Matthew Woehlke

unread,
Aug 3, 2016, 12:16:56 PM8/3/16
to std-pr...@isocpp.org
On 2016-07-30 05:56, FrankHB1989 wrote:
> 在 2016年7月30日星期六 UTC+8上午7:20:15,Matthew Woehlke写道:
>> On 2016-07-28 07:04, FrankHB1989 wrote:
>>> I'd even be glad if the ancient form of 'for' statement is deprecated,
>>> just to reduce the amount of naive excuses.
>>
>> No. Declaring the iterator outside the loop also preserves its value
>> outside the loop. That is sometimes useful. Perhaps even more so with
>> range-based for which is less easily rewritten as a while loop.
>
> No. I did not suggest that [...]

I'm confused. I thought the suggestion was to make 'for(var : ...)' to
*always* mean 'for(atuo&& var : ...)'. If not, then never mind :-).

--
Matthew

FrankHB1989

unread,
Aug 8, 2016, 3:15:46 AM8/8/16
to ISO C++ Standard - Future Proposals, mwoehlk...@gmail.com


在 2016年8月4日星期四 UTC+8上午12:16:56,Matthew Woehlke写道:
I think this transformation (specific to range-based for) is OK, since relying on the existence of declarator is already error-prone so I will never be confused by omission of 'auto&&'.

However, if you do want to have an lived-out-of-loop iterator, then it has nothing to do with the range-based for statement because the iteration is not based on specific range. I think the classic for statement with for-scoped declaration is enough. The ancient one I mentioned is the oldest and the only syntax which conforming to C89 (C89 does not accept other forms of "for" statements). Besides to compatibility concerns, it is not necessary now since the embedded declaration in the "for" statement can be empty (a single semicolon) in the form introduced in C99/C++.



Reply all
Reply to author
Forward
0 new messages