Date: Sat, 15 Feb 2025 09:54:06 +0100
> On Feb 14, 2025, at 7:41 AM, Sebastian Wittmeier via Std-Proposals <std-proposals_at_[hidden]> wrote:
>
>
> Hi Simon,
>
> could you shortly explain the possible bug in the example given?
>
For unsigned integers the condition “i>=0” is always true, so you got yourself an infinite loop. I didn’t even think about “size-1” being “negative” (and thus overflow). The loop would have been perfectly fine with a signed integer (but compilers at least warn because of an implicit cast from unsigned to signed, so I tend to not use signed integers to avoid warnings; at least ssize() instead of size() comes to the rescue).
Others have already replied to use std::views::iota and std::views::reverse (which I also mentioned a while ago) instead. I still think that this is a lot to type and so, people will most likely not use it. It would be a lot more useful if those lived directly in the std namespace.
I guess the main question to answer would be what something like 0..size would actually mean in C++. So far, C++ usually does not have any syntax elements that create a library type (with the exception of std::initializer_list which is not a full type like std::vector). Would we really want 0..size (or some similar syntax) to translate into a library type? Would I have to include a header in order to be able to write this kind of loop? Or would “for(std::size_t i : 0..vec.size())” just internally rewrite this to a regular loop counter “for(std::size_t i=0; i<vec.size(); ++i)”? In the latter case rewriting something like “for(std::size_t i : vec.size()..0)” (0 is inclusive, vec.size() is exclusive) would be more involved.
Currently, we could experiment with syntax by implementing an operator" to be able to write "0..42"_rng.
>
>
> To get the boundaries of size-1 and the >=0 correct or to avoid unsigned integer underflow?
>
>
>
> auto leads to unsigned and size is 0?
>
>
> -----Ursprüngliche Nachricht-----
> Von: Simon Schröder via Std-Proposals <std-proposals_at_[hidden]>
> Gesendet: Fr 14.02.2025 06:52
> Betreff: Re: [std-proposals] for-loops revision (simplification and new syntax)
> An: std-proposals_at_[hidden];
> CC: Simon Schröder <dr.simon.schroeder_at_[hidden]>;
>
> Some of the discussion now steered towards: “Is a new loop syntax useful?”
>
> I would prefer a syntax that leverages the existing range syntax (something similar to Rust or Swift). There is probably one case where such a new syntax would help avoid bugs:
> for(std::size_t i = vec.size()-1; i >= 0; --i) …
> i.e. counting down a loop with an unsigned integer. This might be obfuscated a little more if one uses ‘auto’ to declare the loop counter. With a new syntax (that also allows to specify the step size and the step size can be negative) the implementation would hopefully fix this edge case.
>
>>> On Feb 13, 2025, at 10:15 PM, Sebastian Wittmeier via Std-Proposals <std-proposals_at_[hidden]> wrote:
>>>
>>
>> One should add that the else branch is not run in Python, when the loop has been left with a corresponding break instruction.
>>
>>
>>
>>
>> -----Ursprüngliche Nachricht-----
>> Von: Magnus Fromreide via Std-Proposals <std-proposals_at_[hidden]>
>>
>> If we are talking of loop Pythonisms then a loop else branch does add some
>> value as that case often is a bit contrieved to test for. (The else branch
>> of a loop is executed when the loop condition fails to run the loop more
>> times)
>> --
>> Std-Proposals mailing list
>> Std-Proposals_at_[hidden]
>> https://lists.isocpp.org/mailman/listinfo.cgi/std-proposals
>
> --
> Std-Proposals mailing list
> Std-Proposals_at_[hidden]
> https://lists.isocpp.org/mailman/listinfo.cgi/std-proposals
>
> --
> Std-Proposals mailing list
> Std-Proposals_at_[hidden]
> https://lists.isocpp.org/mailman/listinfo.cgi/std-proposals
>
>
> Hi Simon,
>
> could you shortly explain the possible bug in the example given?
>
For unsigned integers the condition “i>=0” is always true, so you got yourself an infinite loop. I didn’t even think about “size-1” being “negative” (and thus overflow). The loop would have been perfectly fine with a signed integer (but compilers at least warn because of an implicit cast from unsigned to signed, so I tend to not use signed integers to avoid warnings; at least ssize() instead of size() comes to the rescue).
Others have already replied to use std::views::iota and std::views::reverse (which I also mentioned a while ago) instead. I still think that this is a lot to type and so, people will most likely not use it. It would be a lot more useful if those lived directly in the std namespace.
I guess the main question to answer would be what something like 0..size would actually mean in C++. So far, C++ usually does not have any syntax elements that create a library type (with the exception of std::initializer_list which is not a full type like std::vector). Would we really want 0..size (or some similar syntax) to translate into a library type? Would I have to include a header in order to be able to write this kind of loop? Or would “for(std::size_t i : 0..vec.size())” just internally rewrite this to a regular loop counter “for(std::size_t i=0; i<vec.size(); ++i)”? In the latter case rewriting something like “for(std::size_t i : vec.size()..0)” (0 is inclusive, vec.size() is exclusive) would be more involved.
Currently, we could experiment with syntax by implementing an operator" to be able to write "0..42"_rng.
>
>
> To get the boundaries of size-1 and the >=0 correct or to avoid unsigned integer underflow?
>
>
>
> auto leads to unsigned and size is 0?
>
>
> -----Ursprüngliche Nachricht-----
> Von: Simon Schröder via Std-Proposals <std-proposals_at_[hidden]>
> Gesendet: Fr 14.02.2025 06:52
> Betreff: Re: [std-proposals] for-loops revision (simplification and new syntax)
> An: std-proposals_at_[hidden];
> CC: Simon Schröder <dr.simon.schroeder_at_[hidden]>;
>
> Some of the discussion now steered towards: “Is a new loop syntax useful?”
>
> I would prefer a syntax that leverages the existing range syntax (something similar to Rust or Swift). There is probably one case where such a new syntax would help avoid bugs:
> for(std::size_t i = vec.size()-1; i >= 0; --i) …
> i.e. counting down a loop with an unsigned integer. This might be obfuscated a little more if one uses ‘auto’ to declare the loop counter. With a new syntax (that also allows to specify the step size and the step size can be negative) the implementation would hopefully fix this edge case.
>
>>> On Feb 13, 2025, at 10:15 PM, Sebastian Wittmeier via Std-Proposals <std-proposals_at_[hidden]> wrote:
>>>
>>
>> One should add that the else branch is not run in Python, when the loop has been left with a corresponding break instruction.
>>
>>
>>
>>
>> -----Ursprüngliche Nachricht-----
>> Von: Magnus Fromreide via Std-Proposals <std-proposals_at_[hidden]>
>>
>> If we are talking of loop Pythonisms then a loop else branch does add some
>> value as that case often is a bit contrieved to test for. (The else branch
>> of a loop is executed when the loop condition fails to run the loop more
>> times)
>> --
>> Std-Proposals mailing list
>> Std-Proposals_at_[hidden]
>> https://lists.isocpp.org/mailman/listinfo.cgi/std-proposals
>
> --
> Std-Proposals mailing list
> Std-Proposals_at_[hidden]
> https://lists.isocpp.org/mailman/listinfo.cgi/std-proposals
>
> --
> Std-Proposals mailing list
> Std-Proposals_at_[hidden]
> https://lists.isocpp.org/mailman/listinfo.cgi/std-proposals
Received on 2025-02-15 08:54:20