Groups | Search | Server Info | Keyboard shortcuts | Login | Register [http] [https] [nntp] [nntps]
Groups > comp.lang.c > #148702 > unrolled thread
| Started by | "Walter H." <Walter.H-Nntp@mathemainzel.info> |
|---|---|
| First post | 2020-01-03 13:27 +0100 |
| Last post | 2020-01-04 22:17 +0000 |
| Articles | 8 on this page of 68 — 17 participants |
Back to article view | Back to comp.lang.c
for-loop mutates to an endless-loop "Walter H." <Walter.H-Nntp@mathemainzel.info> - 2020-01-03 13:27 +0100
Re: for-loop mutates to an endless-loop David Brown <david.brown@hesbynett.no> - 2020-01-03 14:01 +0100
Re: for-loop mutates to an endless-loop Dan Purgert <dan@djph.net> - 2020-01-03 13:18 +0000
Re: for-loop mutates to an endless-loop James Kuyper <jameskuyper@alumni.caltech.edu> - 2020-01-03 08:28 -0500
Re: for-loop mutates to an endless-loop Dan Purgert <dan@djph.net> - 2020-01-03 13:33 +0000
Re: for-loop mutates to an endless-loop James Kuyper <jameskuyper@alumni.caltech.edu> - 2020-01-03 21:10 -0500
Re: for-loop mutates to an endless-loop David Brown <david.brown@hesbynett.no> - 2020-01-03 15:34 +0100
Re: for-loop mutates to an endless-loop James Kuyper <jameskuyper@alumni.caltech.edu> - 2020-01-03 08:26 -0500
Re: for-loop mutates to an endless-loop "Walter H." <Walter.H-Nntp@mathemainzel.info> - 2020-01-04 16:15 +0100
Re: for-loop mutates to an endless-loop David Brown <david.brown@hesbynett.no> - 2020-01-04 17:17 +0100
Re: for-loop mutates to an endless-loop Ben Bacarisse <ben.usenet@bsb.me.uk> - 2020-01-04 16:20 +0000
Re: for-loop mutates to an endless-loop "Walter H." <Walter.H-Nntp@mathemainzel.info> - 2020-01-04 18:43 +0100
Re: for-loop mutates to an endless-loop David Brown <david.brown@hesbynett.no> - 2020-01-04 19:28 +0100
Re: for-loop mutates to an endless-loop Bart <bc@freeuk.com> - 2020-01-04 18:59 +0000
Re: for-loop mutates to an endless-loop David Brown <david.brown@hesbynett.no> - 2020-01-05 14:24 +0100
Re: for-loop mutates to an endless-loop Keith Thompson <Keith.S.Thompson+u@gmail.com> - 2020-01-04 13:47 -0800
Re: for-loop mutates to an endless-loop David Brown <david.brown@hesbynett.no> - 2020-01-05 14:26 +0100
Re: for-loop mutates to an endless-loop "Walter H." <Walter.H-Nntp@mathemainzel.info> - 2020-01-06 20:31 +0100
Re: for-loop mutates to an endless-loop Ben Bacarisse <ben.usenet@bsb.me.uk> - 2020-01-04 22:25 +0000
Re: for-loop mutates to an endless-loop Keith Thompson <Keith.S.Thompson+u@gmail.com> - 2020-01-04 14:08 -0800
Re: for-loop mutates to an endless-loop James Kuyper <jameskuyper@alumni.caltech.edu> - 2020-01-04 21:32 -0500
Re: for-loop mutates to an endless-loop scott@slp53.sl.home (Scott Lurndal) - 2020-01-05 21:48 +0000
Re: for-loop mutates to an endless-loop James Kuyper <jameskuyper@alumni.caltech.edu> - 2020-01-04 21:43 -0500
Re: for-loop mutates to an endless-loop Bonita Montero <Bonita.Montero@gmail.com> - 2020-01-03 14:47 +0100
Re: for-loop mutates to an endless-loop Ben Bacarisse <ben.usenet@bsb.me.uk> - 2020-01-03 14:39 +0000
Re: for-loop mutates to an endless-loop Bonita Montero <Bonita.Montero@gmail.com> - 2020-01-03 15:42 +0100
Re: for-loop mutates to an endless-loop Ben Bacarisse <ben.usenet@bsb.me.uk> - 2020-01-03 15:07 +0000
Re: for-loop mutates to an endless-loop Bonita Montero <Bonita.Montero@gmail.com> - 2020-01-03 16:18 +0100
Re: for-loop mutates to an endless-loop Bonita Montero <Bonita.Montero@gmail.com> - 2020-01-03 16:47 +0100
Re: for-loop mutates to an endless-loop Ben Bacarisse <ben.usenet@bsb.me.uk> - 2020-01-03 20:41 +0000
Re: for-loop mutates to an endless-loop Bonita Montero <Bonita.Montero@gmail.com> - 2020-01-04 01:05 +0100
Re: for-loop mutates to an endless-loop gazelle@shell.xmission.com (Kenny McCormack) - 2020-01-03 18:30 +0000
Re: for-loop mutates to an endless-loop Robert Wessel <robertwessel2@yahoo.com> - 2020-01-04 00:23 -0600
Re: for-loop mutates to an endless-loop Bonita Montero <Bonita.Montero@gmail.com> - 2020-01-04 08:10 +0100
Re: for-loop mutates to an endless-loop scott@slp53.sl.home (Scott Lurndal) - 2020-01-04 16:41 +0000
Re: for-loop mutates to an endless-loop Bonita Montero <Bonita.Montero@gmail.com> - 2020-01-04 17:44 +0100
Re: for-loop mutates to an endless-loop Bart <bc@freeuk.com> - 2020-01-04 11:15 +0000
Re: for-loop mutates to an endless-loop Jorgen Grahn <grahn+nntp@snipabacken.se> - 2020-01-04 12:33 +0000
Re: for-loop mutates to an endless-loop "Walter H." <Walter.H-Nntp@mathemainzel.info> - 2020-01-04 15:59 +0100
Re: for-loop mutates to an endless-loop Bonita Montero <Bonita.Montero@gmail.com> - 2020-01-04 16:01 +0100
Re: for-loop mutates to an endless-loop Jorgen Grahn <grahn+nntp@snipabacken.se> - 2020-01-04 16:04 +0000
Re: for-loop mutates to an endless-loop Bonita Montero <Bonita.Montero@gmail.com> - 2020-01-04 17:06 +0100
Re: for-loop mutates to an endless-loop scott@slp53.sl.home (Scott Lurndal) - 2020-01-04 16:42 +0000
Re: for-loop mutates to an endless-loop Bonita Montero <Bonita.Montero@gmail.com> - 2020-01-04 17:44 +0100
Re: for-loop mutates to an endless-loop Robert Wessel <robertwessel2@yahoo.com> - 2020-01-04 17:55 -0600
Re: for-loop mutates to an endless-loop "Walter H." <Walter.H-Nntp@mathemainzel.info> - 2020-01-06 20:43 +0100
Re: for-loop mutates to an endless-loop scott@slp53.sl.home (Scott Lurndal) - 2020-01-06 19:50 +0000
Re: for-loop mutates to an endless-loop Lew Pitcher <lew.pitcher@digitalfreehold.ca> - 2020-01-06 15:37 -0500
Re: for-loop mutates to an endless-loop scott@slp53.sl.home (Scott Lurndal) - 2020-01-06 21:59 +0000
Re: for-loop mutates to an endless-loop Robert Wessel <robertwessel2@yahoo.com> - 2020-01-06 17:33 -0600
Re: for-loop mutates to an endless-loop gazelle@shell.xmission.com (Kenny McCormack) - 2020-01-03 18:31 +0000
Re: for-loop mutates to an endless-loop Bonita Montero <Bonita.Montero@gmail.com> - 2020-01-04 01:06 +0100
Re: for-loop mutates to an endless-loop Ben Bacarisse <ben.usenet@bsb.me.uk> - 2020-01-04 01:38 +0000
Re: for-loop mutates to an endless-loop Bonita Montero <Bonita.Montero@gmail.com> - 2020-01-04 08:10 +0100
Re: for-loop mutates to an endless-loop Ben Bacarisse <ben.usenet@bsb.me.uk> - 2020-01-04 16:39 +0000
Re: for-loop mutates to an endless-loop Bonita Montero <Bonita.Montero@gmail.com> - 2020-01-04 17:41 +0100
Re: for-loop mutates to an endless-loop Bonita Montero <Bonita.Montero@gmail.com> - 2020-01-04 17:49 +0100
Re: for-loop mutates to an endless-loop Ben Bacarisse <ben.usenet@bsb.me.uk> - 2020-01-04 22:49 +0000
Re: for-loop mutates to an endless-loop Bonita Montero <Bonita.Montero@gmail.com> - 2020-01-05 03:44 +0100
Re: for-loop mutates to an endless-loop David Brown <david.brown@hesbynett.no> - 2020-01-04 13:09 +0100
Re: for-loop mutates to an endless-loop Ben Bacarisse <ben.usenet@bsb.me.uk> - 2020-01-03 14:28 +0000
Re: for-loop mutates to an endless-loop jak <nospam@please.ty> - 2020-01-05 00:40 +0100
Re: for-loop mutates to an endless-loop "Walter H." <Walter.H-Nntp@mathemainzel.info> - 2020-01-06 20:50 +0100
Re: for-loop mutates to an endless-loop Manfred <noname@add.invalid> - 2020-01-06 21:28 +0100
Re: for-loop mutates to an endless-loop Manfred <noname@add.invalid> - 2020-01-06 21:02 +0100
Re: for-loop mutates to an endless-loop Tim Rentsch <tr.17687@z991.linuxsc.com> - 2020-01-11 10:01 -0800
Re: for-loop mutates to an endless-loop Richard Damon <Richard@Damon-Family.org> - 2020-01-04 16:21 -0500
Re: for-loop mutates to an endless-loop Ben Bacarisse <ben.usenet@bsb.me.uk> - 2020-01-04 22:17 +0000
Page 4 of 4 — ← Prev page 1 2 3 [4]
| From | Ben Bacarisse <ben.usenet@bsb.me.uk> |
|---|---|
| Date | 2020-01-03 14:28 +0000 |
| Message-ID | <87ftgwpqbi.fsf@bsb.me.uk> |
| In reply to | #148702 |
"Walter H." <Walter.H-Nntp@mathemainzel.info> writes:
<cut>
> then I tried the same in C with several compilers
> 32-bit, 64-bit Intel, GNU under Linux or Visual C++ under Windows
> even QuickC or Turbo C every one built this programme with an endless-loop;
>
> [code]
> #include <stdio.h>
> int main( int argc, char* argv[ ] )
> {
> short int nIter;
This may or may not by a 16-bit integer. It probably will be, but
modern C has the type int16_t that you can use to be sure. #include
<stdint.h> to get these new known-width types.
> long lSum = 0;
> for ( nIter = -32768; nIter <= 32767; nIter++ )
When you need numbers like this it better to #include <limits.h> and use
SHRT_MIN and SHRT_MAX. If you included stdint.h to use int16_t then
INT16_MIN and INT16_MAX are available.
Also, in modern C you can declare the loop variable in the for
statement:
for (short nIter = -32768; nIter <= 32767; nIter++) ...
> lSum += nIter;
> printf( "sum: %ld\n", lSum );
> return 0;
> }
> [/code]
Adding a bit to the answer you already have...
If nInter is indeed a 16-bit integer type, and int is wider (the most
likely situation here) then the behaviour of the code above is
implementation-defined.
Once nIter gets to 32767, the increment in the for loop causes a problem
when the result (which will be of type int) is converted back to short.
The result is either an implementation-defined value or an
implementation-defined signal will be raised.
Anyway, unless a signal is raised, the result is bound to be <= 32767
so, as has been pointed out, the test is never false.
> here the same in old FORTRAN which also worked as expected;
>
> [code]
> PROGRAM SumDemo
> INTEGER*2 nIter
> INTEGER*4 lSum
> lSum = 0
> DO nIter = -32768,32767,1
> lSum = lSum + nIter
> END DO
> WRITE ( *, * ) 'sum: ', lSum
> END
> [/code]
Curiously, the GNU Fortran compiler gets this wrong (at least as far as
my understanding of F77 goes) and generates an endless loop.
<cut>
> what would be the correct way of a for-loop
> with the complete range of an integral type?
One solution is to use a wider type:
for (int_fast32_t i = INT16_MIN; i <= INT16_MAX; i++) ...
but that is not always possible. The general solution is to test at the
end, after the increment:
short i = SHRT_MIN;
do sum += i; while (i++ < SHRT_MAX);
but this is not portable to implementations where (a) short is as wide
as int (in which case the increment is undefined behaviour), or (b)
implementations that raise a signal when converting an out-of-range
value to short.
A portable solution must increment only when i < SHRT_MAX:
do sum += i; while (i < SHRT_MAX && i++ | 1);
Of course you can just special-case the last value:
for (i = SHRT_MIN; i < SHRT_MAX; i++)
sum += i;
sum += i;
<cut>
--
Ben.
[toc] | [prev] | [next] | [standalone]
| From | jak <nospam@please.ty> |
|---|---|
| Date | 2020-01-05 00:40 +0100 |
| Message-ID | <qur7pn$ij6$1@gioia.aioe.org> |
| In reply to | #148709 |
Il 03/01/2020 15:28, Ben Bacarisse ha scritto:
> "Walter H." <Walter.H-Nntp@mathemainzel.info> writes:
> <cut>
>> then I tried the same in C with several compilers
>> 32-bit, 64-bit Intel, GNU under Linux or Visual C++ under Windows
>> even QuickC or Turbo C every one built this programme with an endless-loop;
>>
>> [code]
>> #include <stdio.h>
>> int main( int argc, char* argv[ ] )
>> {
>> short int nIter;
>
> This may or may not by a 16-bit integer. It probably will be, but
> modern C has the type int16_t that you can use to be sure. #include
> <stdint.h> to get these new known-width types.
>
>> long lSum = 0;
>> for ( nIter = -32768; nIter <= 32767; nIter++ )
>
> When you need numbers like this it better to #include <limits.h> and use
> SHRT_MIN and SHRT_MAX. If you included stdint.h to use int16_t then
> INT16_MIN and INT16_MAX are available.
>
> Also, in modern C you can declare the loop variable in the for
> statement:
>
> for (short nIter = -32768; nIter <= 32767; nIter++) ...
>
>> lSum += nIter;
>> printf( "sum: %ld\n", lSum );
>> return 0;
>> }
>> [/code]
>
> Adding a bit to the answer you already have...
>
> If nInter is indeed a 16-bit integer type, and int is wider (the most
> likely situation here) then the behaviour of the code above is
> implementation-defined.
>
> Once nIter gets to 32767, the increment in the for loop causes a problem
> when the result (which will be of type int) is converted back to short.
> The result is either an implementation-defined value or an
> implementation-defined signal will be raised.
>
> Anyway, unless a signal is raised, the result is bound to be <= 32767
> so, as has been pointed out, the test is never false.
>
>> here the same in old FORTRAN which also worked as expected;
>>
>> [code]
>> PROGRAM SumDemo
>> INTEGER*2 nIter
>> INTEGER*4 lSum
>> lSum = 0
>> DO nIter = -32768,32767,1
>> lSum = lSum + nIter
>> END DO
>> WRITE ( *, * ) 'sum: ', lSum
>> END
>> [/code]
>
> Curiously, the GNU Fortran compiler gets this wrong (at least as far as
> my understanding of F77 goes) and generates an endless loop.
>
> <cut>
>> what would be the correct way of a for-loop
>> with the complete range of an integral type?
>
> One solution is to use a wider type:
>
> for (int_fast32_t i = INT16_MIN; i <= INT16_MAX; i++) ...
>
> but that is not always possible. The general solution is to test at the
> end, after the increment:
>
> short i = SHRT_MIN;
> do sum += i; while (i++ < SHRT_MAX);
>
> but this is not portable to implementations where (a) short is as wide
> as int (in which case the increment is undefined behaviour), or (b)
> implementations that raise a signal when converting an out-of-range
> value to short.
>
> A portable solution must increment only when i < SHRT_MAX:
>
> do sum += i; while (i < SHRT_MAX && i++ | 1);
>
> Of course you can just special-case the last value:
>
> for (i = SHRT_MIN; i < SHRT_MAX; i++)
> sum += i;
> sum += i;
>
> <cut>
>
...or just don't increment last time:
for (short int nIter = -32768;; nIter++)
{
lSum += nIter;
if(!(nIter < 32767))
break;
}
[toc] | [prev] | [next] | [standalone]
| From | "Walter H." <Walter.H-Nntp@mathemainzel.info> |
|---|---|
| Date | 2020-01-06 20:50 +0100 |
| Message-ID | <h7hhc1Ft33kU1@mid.individual.net> |
| In reply to | #148709 |
On 03.01.2020 15:28, Ben Bacarisse wrote: > "Walter H."<Walter.H-Nntp@mathemainzel.info> writes: > >> here the same in old FORTRAN which also worked as expected; >> >> [code] >> PROGRAM SumDemo >> INTEGER*2 nIter >> INTEGER*4 lSum >> lSum = 0 >> DO nIter = -32768,32767,1 >> lSum = lSum + nIter >> END DO >> WRITE ( *, * ) 'sum: ', lSum >> END >> [/code] > > Curiously, the GNU Fortran compiler gets this wrong (at least as far as > my understanding of F77 goes) and generates an endless loop. mine worked as expected, the same with Turbo Pascal, probably any other Pascal, too;
[toc] | [prev] | [next] | [standalone]
| From | Manfred <noname@add.invalid> |
|---|---|
| Date | 2020-01-06 21:28 +0100 |
| Message-ID | <qv058q$mav$1@gioia.aioe.org> |
| In reply to | #148806 |
On 1/6/2020 8:50 PM, Walter H. wrote:
> On 03.01.2020 15:28, Ben Bacarisse wrote:
>> "Walter H."<Walter.H-Nntp@mathemainzel.info> writes:
>>
>>> here the same in old FORTRAN which also worked as expected;
>>>
>>> [code]
>>> PROGRAM SumDemo
>>> INTEGER*2 nIter
>>> INTEGER*4 lSum
>>> lSum = 0
>>> DO nIter = -32768,32767,1
>>> lSum = lSum + nIter
>>> END DO
>>> WRITE ( *, * ) 'sum: ', lSum
>>> END
>>> [/code]
>>
>> Curiously, the GNU Fortran compiler gets this wrong (at least as far as
>> my understanding of F77 goes) and generates an endless loop.
>
> mine worked as expected, the same with Turbo Pascal, probably any other
> Pascal, too;
Actually with f77 it doesn't play nice either (gfortran compiles f95 and
later resulting in an endless loop indeed):
$ f77 --version
GNU Fortran (GCC) 3.4.6 20060404 (Red Hat 3.4.6-46.fc28)
Copyright (C) 2006 Free Software Foundation, Inc.
$ f77 full_loop.f
full_loop.f: In program `sumdemo':
full_loop.f:5: warning:
DO nIter = -32768,32767,1
^
Iterative DO loop begin, end, and step-count values known to result in
no iterations at (^)
full_loop.f:5: warning:
DO nIter = -32768,32767,1
^
Iterative DO loop end value plus step count known to overflow at (^)
$ ./a.out
sum: 0
[toc] | [prev] | [next] | [standalone]
| From | Manfred <noname@add.invalid> |
|---|---|
| Date | 2020-01-06 21:02 +0100 |
| Message-ID | <qv03o5$esp$1@gioia.aioe.org> |
| In reply to | #148709 |
On 1/3/2020 3:28 PM, Ben Bacarisse wrote:
> A portable solution must increment only when i < SHRT_MAX:
>
> do sum += i; while (i < SHRT_MAX && i++ | 1);
I find that somehow stinging for the eye.
do sum += i; while (i < SHRT_MAX && (++i, 1));
[toc] | [prev] | [next] | [standalone]
| From | Tim Rentsch <tr.17687@z991.linuxsc.com> |
|---|---|
| Date | 2020-01-11 10:01 -0800 |
| Message-ID | <86pnfp27oz.fsf@linuxsc.com> |
| In reply to | #148709 |
Ben Bacarisse <ben.usenet@bsb.me.uk> writes:
> "Walter H." <Walter.H-Nntp@mathemainzel.info> writes:
> <cut>
>
>> then I tried the same in C with several compilers
>> 32-bit, 64-bit Intel, GNU under Linux or Visual C++ under Windows
>> even QuickC or Turbo C every one built this programme with an endless-loop;
>>
>> [code]
>> #include <stdio.h>
>> int main( int argc, char* argv[ ] )
>> {
>> short int nIter;
>
> This may or may not by a 16-bit integer. It probably will be, but
> modern C has the type int16_t that you can use to be sure. #include
> <stdint.h> to get these new known-width types.
>
>> long lSum = 0;
>> for ( nIter = -32768; nIter <= 32767; nIter++ )
>
> When you need numbers like this it better to #include <limits.h> and use
> SHRT_MIN and SHRT_MAX. If you included stdint.h to use int16_t then
> INT16_MIN and INT16_MAX are available.
>
> Also, in modern C you can declare the loop variable in the for
> statement:
>
> for (short nIter = -32768; nIter <= 32767; nIter++) ...
>
>> lSum += nIter;
>> printf( "sum: %ld\n", lSum );
>> return 0;
>> }
>> [/code]
>
> Adding a bit to the answer you already have...
>
> If nInter is indeed a 16-bit integer type, and int is wider (the most
> likely situation here) then the behaviour of the code above is
> implementation-defined.
>
> Once nIter gets to 32767, the increment in the for loop causes a problem
> when the result (which will be of type int) is converted back to short.
> The result is either an implementation-defined value or an
> implementation-defined signal will be raised.
>
> Anyway, unless a signal is raised, the result is bound to be <= 32767
> so, as has been pointed out, the test is never false.
>
>> here the same in old FORTRAN which also worked as expected;
>>
>> [code]
>> PROGRAM SumDemo
>> INTEGER*2 nIter
>> INTEGER*4 lSum
>> lSum = 0
>> DO nIter = -32768,32767,1
>> lSum = lSum + nIter
>> END DO
>> WRITE ( *, * ) 'sum: ', lSum
>> END
>> [/code]
>
> Curiously, the GNU Fortran compiler gets this wrong (at least as far as
> my understanding of F77 goes) and generates an endless loop.
>
> <cut>
>
>> what would be the correct way of a for-loop
>> with the complete range of an integral type?
>
> One solution is to use a wider type:
>
> for (int_fast32_t i = INT16_MIN; i <= INT16_MAX; i++) ...
>
> but that is not always possible. The general solution is to test at the
> end, after the increment:
>
> short i = SHRT_MIN;
> do sum += i; while (i++ < SHRT_MAX);
>
> but this is not portable to implementations where (a) short is as wide
> as int (in which case the increment is undefined behaviour), or (b)
> implementations that raise a signal when converting an out-of-range
> value to short.
>
> A portable solution must increment only when i < SHRT_MAX:
>
> do sum += i; while (i < SHRT_MAX && i++ | 1);
Another way to achieve the same effect:
do sum += i; while (i < SHRT_MAX && i++ < SHRT_MAX);
(It seems likely that optimization will omit the redundant
comparison.)
[toc] | [prev] | [next] | [standalone]
| From | Richard Damon <Richard@Damon-Family.org> |
|---|---|
| Date | 2020-01-04 16:21 -0500 |
| Message-ID | <Hl7QF.26306$gQ2.20665@fx25.iad> |
| In reply to | #148702 |
I will point that there is a fundamental limitation in the for loop,
that when running on cycling the value of a variable, there MUST be some
value that won't be used in the loop, to use for the exit case. Since
the test clause is run BEFORE each loop, if it is testing the value of
the loop variable, there needs to be a value that the loop won't run on
to test for and exit the loop.
I know of two options here, one is to just use a wide variable for the
loop, so if you want all value of an int to be used, then you need to
choose a type for the loop counter that is bigger than an int.
A second option is to switch from a for loop to a do while of the form:
var = start value for loop
do {
// Code for loop
if(var == max value for loop) break
var++
} while (1);
IF (and only if) the compiler promises not to optimize on the undefined
behavior, and the actual undefined behavior of increment is benign, then
(and only then) you can combine the test and the increment into the
while clause, to get something like:
var = start value for loop
do {
// Code for loop
} while(var++ != max value for loop);
Note, by checking the value before the increment we can test for the
last value, but because the increment will still happen, the undefined
behavior of the overflow does happen, so it must be benign and not
optimized against.
[toc] | [prev] | [next] | [standalone]
| From | Ben Bacarisse <ben.usenet@bsb.me.uk> |
|---|---|
| Date | 2020-01-04 22:17 +0000 |
| Message-ID | <87v9pqn9xy.fsf@bsb.me.uk> |
| In reply to | #148770 |
Richard Damon <Richard@Damon-Family.org> writes:
> I will point that there is a fundamental limitation in the for loop,
> that when running on cycling the value of a variable, there MUST be
> some value that won't be used in the loop, to use for the exit
> case. Since the test clause is run BEFORE each loop, if it is testing
> the value of the loop variable, there needs to be a value that the
> loop won't run on to test for and exit the loop.
>
> I know of two options here, one is to just use a wide variable for the
> loop, so if you want all value of an int to be used, then you need to
> choose a type for the loop counter that is bigger than an int.
>
> A second option is to switch from a for loop to a do while of the form:
>
> var = start value for loop
> do {
> // Code for loop
> if(var == max value for loop) break
> var++
> } while (1);
There is a "tricksy" partial for-based solution as well. If the loop
body is made up of expression statements, or you can re-write it as a
function, you can write
for (T i = min-value-of-T; f(... i ...), i < max-value-of-T; i++);
In the case in question one can write:
long sum = 0;
for (short i = SHRT_MIN; sum += i, i < SHRT_MAX; i++);
printf("%ld\n", sum);
The idea cones form Algol 68 where every expression can be a
value-yielding block. This gave one a way to do exit in the middle
loops without break by writing part of the loop body in the while
condition.
If you have block expressions (as gcc provides) this is in fact a
general solution, though it probably still rates as yucky for normal
programmers.
> IF (and only if) the compiler promises not to optimize on the
> undefined behavior, and the actual undefined behavior of increment is
> benign, then (and only then) you can combine the test and the
> increment into the while clause, to get something like:
>
> var = start value for loop
> do {
> // Code for loop
> } while(var++ != max value for loop);
>
> Note, by checking the value before the increment we can test for the
> last value, but because the increment will still happen, the undefined
> behavior of the overflow does happen, so it must be benign and not
> optimized against.
Yup, for signed types no narrower than int. As I am sure you know,
there will be no UB if var is unsigned, and if var has a type narrower
than int the behaviour is implementation defined.
--
Ben.
[toc] | [prev] | [standalone]
Page 4 of 4 — ← Prev page 1 2 3 [4]
Back to top | Article view | comp.lang.c
csiph-web