Sujet : Re: Loops (was Re: do { quit; } else { })
De : Keith.S.Thompson+u (at) *nospam* gmail.com (Keith Thompson)
Groupes : comp.lang.cDate : 17. Apr 2025, 01:47:49
Autres entêtes
Organisation : None to speak of
Message-ID : <87mscfzk96.fsf@nosuchdomain.example.com>
References : 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21
User-Agent : Gnus/5.13 (Gnus v5.13)
bart <
bc@freeuk.com> writes:
On 16/04/2025 22:43, Kaz Kylheku wrote:
[...]
Hey Bart, how would you handle a loop like
do x = m to n ...
where m and n are not known until run time, and may be the
extreme values of the type? Like C's INT_MIN and INT_MAX, respectively,
where x is of type int.
Because in this loop, x takes on every possible value of the type,
we cannot have a loop guard which prevents entry of the loop body
based on solely the value of x.
>
I'm not exactly sure what you are asking.
[...]
However, this languages evaluates using 64 bits. Perhaps this loop may
demonstrate the issues better:
>
for i in i64.bounds do
>
However, I would estimate it would take 190 years to finish.
>
I assume you're thinking of C which uses i32 and where comparisons
near the extreme values of the type are problemetical.
[...]
"C which uses i32"?
I'm going to guess that what you meant by that is that many, perhaps most,
C implementations have 32-bit int. Of course the language doesn't
specify that, and of course you can use expressions of any type you like
in a C for loop.
my language:
>
for i in i64.max-10 .. i64.max do println i
>
which doesn't stop (u64 is OK however). That doesn't worry me too
much, I can just add a Note to the language spec warning of UB when a
for-loop bound is at the limits of the type. Where all sorts of other
stuff can happen because of how values wrap.
And C's for loop has the same issue, though of course you don't need to
resort to 64-bit arithmetic to demonstrate it:
for (int i = INT_MAX-10; i <= INT_MAX; i++) {
printf("%d\n", i);
}
This will cause a signed integer overflow and undefined behavior
when i has reached INT_MAX, and the comparison `i <= INT_MAX`
might even be optimized away.
(Ada's for loop, for example, doesn't have this issue. The compiler is
required to generate whatever code is necessary to make the equivalent
loop iterate exactly 11 times. Ada's for loops are not nearly as
flexible as C's.)
[...]
You're trying too hard. I don't think the language needs to bother
providing solutions, it just needs to specify the limitations.
So this issue (overflowing at the top end of the range) *isn't*
something you dislike about C-style for loops. Good to know.
If the user needs to know about, and remember in the rare instance it
comes up, dedicated language features, then the user can also come up
with their own workarounds as I showed. Eg. in C:
>
long long int i, a=INT_MIN, b=INT_MAX, n=0;
>
for (i = a; i<=b; ++i) ++n;
>
printf("%lld\n", n);
That works only if long long int is wider than int, something the
language does not guarantee.
If hitting the top end of the range is a concern, I think a better
workaround is to do a test and break at the bottom of the loop.
That has the advantage of working even if no wider type is available.
C-style for loops aren't *quite* flexible enough to express that
directly, at least not cleanly.
-- Keith Thompson (The_Other_Keith) Keith.S.Thompson+u@gmail.comvoid Void(void) { Void(); } /* The recursive call of the void */