Groups | Search | Server Info | Keyboard shortcuts | Login | Register [http] [https] [nntp] [nntps]


Groups > comp.lang.c > #148702 > unrolled thread

for-loop mutates to an endless-loop

Started by"Walter H." <Walter.H-Nntp@mathemainzel.info>
First post2020-01-03 13:27 +0100
Last post2020-01-04 22:17 +0000
Articles 20 on this page of 68 — 17 participants

Back to article view | Back to comp.lang.c


Contents

  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 1 of 4  [1] 2 3 4  Next page →


#148702 — for-loop mutates to an endless-loop

From"Walter H." <Walter.H-Nntp@mathemainzel.info>
Date2020-01-03 13:27 +0100
Subjectfor-loop mutates to an endless-loop
Message-ID<h78q9lF3mhkU1@mid.individual.net>
Hello,

I built a VM with DOS and Turbo Pascal for a mate of mine;

[code]
Program SumDemo;
Var
   nIter : Integer;
   lSum : LongInt;
Begin
   lSum := 0;
   For nIter := -32768 to 32767 Do
     lSum := lSum + nIter;
   WriteLn( 'sum: ', lSum );
End.
[/code]

there I tested above programme; and it worked as exprected; as my 
hardware is new the result came within a second

[output]
sum: -32768
[/output]

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;
     long lSum = 0;
     for ( nIter = -32768; nIter <= 32767; nIter++ )
         lSum += nIter;
     printf( "sum: %ld\n", lSum );
     return 0;
}
[/code]

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]

where is the mistake in C?

this modified C-programme works as expected,
but looks weired

[code]
#include <stdio.h>
int main( int argc, char* argv[ ] )
{
     short int nIter = -32768;
     long lSum = 0;
     do
     {
         lSum += nIter++;
     }
     while ( nIter > -32768 );
     printf( "sum: %ld\n", lSum );
     return 0;
}
[/code]

what would be the correct way of a for-loop
with the complete range of an integral type?

by the way also with unsigned it is the same ...

[code]
#include <stdio.h>
int main( int argc, char* argv[ ] )
{
     unsigned short int nIter;
     unsigned long lSum = 0;
     for ( nIter = 0; nIter <= 65535; nIter++ )
         lSum += nIter;
     printf( "sum: %lu\n", lSum );
     return 0;
}
[/code]

this strange behaviour also exists with 32-bit or 64-bit like this

[code]
long int i32Iter;
for ( i32Iter = -2147483648; i32Iter <= 2147483647; i32Iter++ )
// ...
[/code]

bzw.

[code]
long long int i64Iter;
for ( i64Iter = -9223372036854775808; i64Iter <= 9223372036854775807; 
i64Iter++ )
// ...
[/code]

with C++ it is the identical problem;

Thanks,
Walter

[toc] | [next] | [standalone]


#148703

FromDavid Brown <david.brown@hesbynett.no>
Date2020-01-03 14:01 +0100
Message-ID<qundvi$921$1@dont-email.me>
In reply to#148702
On 03/01/2020 13:27, Walter H. wrote:
> Hello,
> 
> I built a VM with DOS and Turbo Pascal for a mate of mine;
> 
> [code]
> Program SumDemo;
> Var
>   nIter : Integer;
>   lSum : LongInt;
> Begin
>   lSum := 0;
>   For nIter := -32768 to 32767 Do
>     lSum := lSum + nIter;
>   WriteLn( 'sum: ', lSum );
> End.
> [/code]
> 
> there I tested above programme; and it worked as exprected; as my
> hardware is new the result came within a second
> 
> [output]
> sum: -32768
> [/output]
> 
> 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;
>     long lSum = 0;
>     for ( nIter = -32768; nIter <= 32767; nIter++ )
>         lSum += nIter;
>     printf( "sum: %ld\n", lSum );
>     return 0;
> }
> [/code]
> 
> where is the mistake in C?
> 
> this modified C-programme works as expected,
> but looks weired
> 
> [code]
> #include <stdio.h>
> int main( int argc, char* argv[ ] )
> {
>     short int nIter = -32768;
>     long lSum = 0;
>     do
>     {
>         lSum += nIter++;
>     }
>     while ( nIter > -32768 );
>     printf( "sum: %ld\n", lSum );
>     return 0;
> }
> [/code]
> 
> what would be the correct way of a for-loop
> with the complete range of an integral type?

C "for" loops are not the same as "for" loops in Pascal or Fortran (or
several other languages).  They don't just handle an incrementing
variable, but general expressions.  However, that means the test is done
before the loop runs, making it inconvenient to run it over the entire
range of the type.  For that, you want a test that is done after the
loop contents, such as you have in your do/while loop.

The reason your loops don't exit is that you have a check "nIter <=
32767" for "short int" (on a machine where "short int" is 16-bit).  This
condition is always true, since nIter can't have a value greater than
32767.  So the loop never exits.

The simple fix here is to use "int" rather than "short int" - it will be
32-bit, and big enough to run the calculation.

A good idea when writing C code is to have warnings enabled in your
compiler, and also some optimisation (as well as giving much better
code, it improves the warnings).  For gcc, use "-O2 -Wall" as a general
starting point.  It is also useful to add "-Wextra" for more checking -
this will probably give more warnings than you like, but in this example
it will give you the clue you needed to see the problem.

[toc] | [prev] | [next] | [standalone]


#148704

FromDan Purgert <dan@djph.net>
Date2020-01-03 13:18 +0000
Message-ID<slrnr0ufpc.221.dan@djph.net>
In reply to#148702
-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA256

Walter H. wrote:
> [code]
> #include <stdio.h>
> int main( int argc, char* argv[ ] )
> {
>      short int nIter;
>      long lSum = 0;
>      for ( nIter = -32768; nIter <= 32767; nIter++ )
>          lSum += nIter;
>      printf( "sum: %ld\n", lSum );
>      return 0;
> }
> [/code]
>
> where is the mistake in C?

Your stop condition -- "nIter <=32767" -- is incorrect.  When
the iterator is 32767, it is still true, and so you add "1".  This
causes it to roll over to -32768, and keep counting.

Changing the line to:

    for (nIter = -32768; nIter < 32767; nIter++)

should fix it for you.

HTH :)


-----BEGIN PGP SIGNATURE-----

iQEzBAEBCAAdFiEEBcqaUD8uEzVNxUrujhHd8xJ5ooEFAl4PPywACgkQjhHd8xJ5
ooFYhQgAgr2HMTGt7G8XLCtLBAG3T4kSXExmrm/RE/EYAe46EH6YtxG7gjLUQbnN
wQRc8Nf9JWkFcCjnyv/prmKfPq0TNYo1RDc4pKKJcPQOFLA8iYrA7xLtM6WgjqIe
OP3za4G8gbUIq2KKce0pl2JQYGaGWH/0lKXBZSWPfWTgqSn7TBijCAT8Ws+sCdv0
7w0QXPARoYtNefnFOA7s6cgC61mTxnQSMcWOMi0iUI/T4vEmwT7HHsGGvrm8O+Hc
siSxE10BZoT+N/w7aGG+1Q2uWpUcb1I5/XHfIPbTZTItQ5KKuiimvVVib8Lb4SlT
+DVCwQ/tQNmpqYyES+k7f5CR1EddPg==
=DuLw
-----END PGP SIGNATURE-----

-- 
|_|O|_| 
|_|_|O| Github: https://github.com/dpurgert
|O|O|O| PGP: 05CA 9A50 3F2E 1335 4DC5  4AEE 8E11 DDF3 1279 A281

[toc] | [prev] | [next] | [standalone]


#148706

FromJames Kuyper <jameskuyper@alumni.caltech.edu>
Date2020-01-03 08:28 -0500
Message-ID<qunfh7$gce$2@dont-email.me>
In reply to#148704
On 1/3/20 8:18 AM, Dan Purgert wrote:
> -----BEGIN PGP SIGNED MESSAGE-----
> Hash: SHA256
> 
> Walter H. wrote:
>> [code]
>> #include <stdio.h>
>> int main( int argc, char* argv[ ] )
>> {
>>      short int nIter;
>>      long lSum = 0;
>>      for ( nIter = -32768; nIter <= 32767; nIter++ )
>>          lSum += nIter;
>>      printf( "sum: %ld\n", lSum );
>>      return 0;
>> }
>> [/code]
>>
>> where is the mistake in C?
> 
> Your stop condition -- "nIter <=32767" -- is incorrect.  When
> the iterator is 32767, it is still true, and so you add "1".  This
> causes it to roll over to -32768, and keep counting.
> 
> Changing the line to:
> 
>     for (nIter = -32768; nIter < 32767; nIter++)
> 
> should fix it for you.

With that change, the loop body will never get executed with
nIter==32767. It's supposed to be executed for every possible value of
nIter.

[toc] | [prev] | [next] | [standalone]


#148707

FromDan Purgert <dan@djph.net>
Date2020-01-03 13:33 +0000
Message-ID<slrnr0ugkd.221.dan@djph.net>
In reply to#148706
-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA256

James Kuyper wrote:
> On 1/3/20 8:18 AM, Dan Purgert wrote:
>> [...]
>> Changing the line to:
>> 
>>     for (nIter = -32768; nIter < 32767; nIter++)
>> 
>> should fix it for you.
>
> With that change, the loop body will never get executed with
> nIter==32767. It's supposed to be executed for every possible value of
> nIter.

Bah, must've missed the bit where he said that part (not to mention
probably misreading everything else).

This is why I should just read and learn in here :).


-----BEGIN PGP SIGNATURE-----

iQEzBAEBCAAdFiEEBcqaUD8uEzVNxUrujhHd8xJ5ooEFAl4PQowACgkQjhHd8xJ5
ooF9+ggAle2WUN45jzYgwJa1GzwaO/DL97BDzETby8G76pX3zwmF3YhF14u5a6Vp
nKvqLsze0LWGsPEhKCNpN60q9p0ENdISoHJvgMhCu/f/m7uXwB4k4UdmMe6AnZy/
cBYED0uNWmx2HwNQ4xs1yyPSs0m2sOGkcbvxv4a5Lji4MUnBKzIi0hajSDQRUI/Y
IbvYV8jqZqqNJgUinLOYCB+3ruzAAwDJ4w2qu9Kx4MaSnEyS/ccWvLEFWRoSIfyW
r3I/ClJJP/xRMxnHXamqfIRYf2sUjcm/8UQk18LSpW4tDMzlMC72Runfdt3sInmE
NSo6F5ft65bNNInlEyFgwV4vZHVcZA==
=UBSV
-----END PGP SIGNATURE-----

-- 
|_|O|_| 
|_|_|O| Github: https://github.com/dpurgert
|O|O|O| PGP: 05CA 9A50 3F2E 1335 4DC5  4AEE 8E11 DDF3 1279 A281

[toc] | [prev] | [next] | [standalone]


#148734

FromJames Kuyper <jameskuyper@alumni.caltech.edu>
Date2020-01-03 21:10 -0500
Message-ID<quos66$k5v$2@dont-email.me>
In reply to#148707
On 1/3/20 8:33 AM, Dan Purgert wrote:
> -----BEGIN PGP SIGNED MESSAGE-----
> Hash: SHA256
> 
> James Kuyper wrote:
>> On 1/3/20 8:18 AM, Dan Purgert wrote:
>>> [...]
>>> Changing the line to:
>>>
>>>     for (nIter = -32768; nIter < 32767; nIter++)
>>>
>>> should fix it for you.
>>
>> With that change, the loop body will never get executed with
>> nIter==32767. It's supposed to be executed for every possible value of
>> nIter.
> 
> Bah, must've missed the bit where he said that part (not to mention
> probably misreading everything else).

He didn't say it explicitly. However, the  Turbo Pascal code that he
provided, saying that he wanted to translate it to C, does cover every
value fro m-32768 to 32767.

[toc] | [prev] | [next] | [standalone]


#148711

FromDavid Brown <david.brown@hesbynett.no>
Date2020-01-03 15:34 +0100
Message-ID<qunjct$8vk$1@dont-email.me>
In reply to#148704
> Walter H. wrote:
>> [code]
>> #include <stdio.h>
>> int main( int argc, char* argv[ ] )
>> {
>>      short int nIter;
>>      long lSum = 0;
>>      for ( nIter = -32768; nIter <= 32767; nIter++ )
>>          lSum += nIter;
>>      printf( "sum: %ld\n", lSum );
>>      return 0;
>> }
>> [/code]
> 
>> where is the mistake in C?
> 
> Your stop condition -- "nIter <=32767" -- is incorrect.  When
> the iterator is 32767, it is still true, and so you add "1".  This
> causes it to roll over to -32768, and keep counting.

There is no guarantee that it will "roll over".  /Maybe/ it will roll
over and keep counting.  Maybe the compiler just notes that nIter can
never be greater than 32767, and realises that the loop will never end,
and then it can generate whatever code it likes - gcc with optimisation
generates a tight loop without any arithmetic at all, but it could have
generated an error message instead.

(With the sizes of "int" and "short" on these platforms, overflowing
"short" here will be implementation dependant behaviour which will
almost certainly be wrapping - but that is up to the compiler.
Overflowing "int" is undefined behaviour and is often /not/ wrapping.
Please do not give the impression that wrapping is normal or standard
behaviour - it will lead language newcomers to make mistakes.)

> 
> Changing the line to:
> 
>     for (nIter = -32768; nIter < 32767; nIter++)
> 
> should fix it for you.

It will cause the loop to terminate, but not with the expected answer.

> 
> HTH :)
> 
> 
> 

[toc] | [prev] | [next] | [standalone]


#148705

FromJames Kuyper <jameskuyper@alumni.caltech.edu>
Date2020-01-03 08:26 -0500
Message-ID<qunfda$gce$1@dont-email.me>
In reply to#148702
On 1/3/20 7:27 AM, Walter H. wrote:
...
> long int i32Iter;

That name implies that you expect long int to be a 32-bit type. On many
systems it is, on other systems it is not. If it's important to you that
it be an exactly 32-bit int, use int32_t. If you want the smallest
integer type with at least 32 bits, use int_least32_t. If you want the
fastest inbteger type with at least 32 bits, use int_fast32_t. These
typedefs can all be found in <stdint.h>.
The problem with the code below comes precisely from the fact that long
int apparently is a 32-bit type. In order to write code this way, you
need a type bigger than 32 bits:

> for ( i32Iter = -2147483648; i32Iter <= 2147483647; i32Iter++ )

The condition expression for that loop is "i32Iter <= 2147483647". A C
for loop terminates when the specified condition becomes false. For what
value of i32iter do you expect that condition to be false?

If long int is 32 bits, then when i32Iter == 2147483647, the expression
i32Iter++ has undefined behavior. On some implementations, that will
cause your program to abort. On others, it will wrap around to
-2147483648, and that appears to be what happened in your case.

> // ...
> [/code]
> 
> bzw.
> 
> [code]
> long long int i64Iter;
> for ( i64Iter = -9223372036854775808; i64Iter <= 9223372036854775807; 
> i64Iter++ )

Similar comments apply here.

[toc] | [prev] | [next] | [standalone]


#148750

From"Walter H." <Walter.H-Nntp@mathemainzel.info>
Date2020-01-04 16:15 +0100
Message-ID<h7bogeFmh2bU1@mid.individual.net>
In reply to#148705
On 03.01.2020 14:26, James Kuyper wrote:
> On 1/3/20 7:27 AM, Walter H. wrote:
> ...
>> long int i32Iter;
>
> That name implies that you expect long int to be a 32-bit type.

 > On many systems it is, on other systems it is not.

have you an example of a system where it is not?
(I have never heard of this)

the only thing it type int
maybe it is 16-bit (on 16-bit systems like DOS)
or it is 32-bit (on 32-bit systems like OS/2, WinNT x86, Linux, ...)

> If it's important to you that
> it be an exactly 32-bit int, use int32_t.

mostly there are other types either #define or typedef's like
DWORD, BYTE, WORD, ...

a problem of C and C++ too;
there must not be a system dependence of how many bits an integral type has;
I saw C/C++ compilers, where wchar_t was 32-bit ...
on others this was just 16-bit ...

> These typedefs can all be found in<stdint.h>.

of course, from the view of Turbo C this is future ;-)

> The problem with the code below comes precisely from the fact that long
> int apparently is a 32-bit type. In order to write code this way, you
> need a type bigger than 32 bits:

this must be a mistake; the loop must go through the whole range of the 
integral type;

>> for ( i32Iter = -2147483648; i32Iter<= 2147483647; i32Iter++ )
>
> The condition expression for that loop is "i32Iter<= 2147483647". A C
> for loop terminates when the specified condition becomes false. For what
> value of i32iter do you expect that condition to be false?

already understood; in other words: the language that is nearest to the 
system can't handle the most primitive 'structures'; why?

[toc] | [prev] | [next] | [standalone]


#148754

FromDavid Brown <david.brown@hesbynett.no>
Date2020-01-04 17:17 +0100
Message-ID<quqdr8$6jr$1@dont-email.me>
In reply to#148750
On 04/01/2020 16:15, Walter H. wrote:
> On 03.01.2020 14:26, James Kuyper wrote:
>> On 1/3/20 7:27 AM, Walter H. wrote:
>> ...
>>> long int i32Iter;
>>
>> That name implies that you expect long int to be a 32-bit type.
> 
>  > On many systems it is, on other systems it is not.
> 
> have you an example of a system where it is not?
> (I have never heard of this)

Yes - "long int" is 64-bit on 64-bit Linux systems (and probably all 
64-bit OS's other than Windows).

> 
> the only thing it type int
> maybe it is 16-bit (on 16-bit systems like DOS)
> or it is 32-bit (on 32-bit systems like OS/2, WinNT x86, Linux, ...)

There are many systems where "int" is neither 16-bit nor 32-bit, but 
these are mostly quite specialised.  On some Cray systems, "int" is 
64-bit.  On some DSP's, it is 24-bit.  And so on.

The C standards give minimum requirements - "int" must be at least 
16-bit, and "long int" must be at least 32-bit.  But those are not fixed 
limits.

> 
>> If it's important to you that
>> it be an exactly 32-bit int, use int32_t.
> 
> mostly there are other types either #define or typedef's like
> DWORD, BYTE, WORD, ...
> 

These kind of names are long outdated as being ambiguous and 
non-portable.  With C99, a standard and unambiguous system of naming was 
introduced.  I would strongly recommend you use the <stdint.h> types for 
specific sizes, such as "uint16_t" for unsigned 16-bit, "int64_t" for 
signed 64-bit, etc.

> a problem of C and C++ too;
> there must not be a system dependence of how many bits an integral type 
> has;
> I saw C/C++ compilers, where wchar_t was 32-bit ...
> on others this was just 16-bit ...

*nix systems usually have 32-bit wchar_t, while Windows has 16-bit 
wchar_t.  There is no fixed pattern for wchar_t sizes on embedded systems.

> 
>> These typedefs can all be found in<stdint.h>.
> 
> of course, from the view of Turbo C this is future ;-)

If you insist on using a tool that was outdated 25 years ago, you will 
have to make some compromises.  I suggest that you write your own header 
for it, called "stdint.h", containing typedefs for the modern C99 sized 
types.  Then you can write code that is portable to modern tools and 
your old Turbo C.

Or you could use something like this:

<https://github.com/chokkan/cdbpp/blob/master/win32/stdint.h>

> 
>> The problem with the code below comes precisely from the fact that long
>> int apparently is a 32-bit type. In order to write code this way, you
>> need a type bigger than 32 bits:
> 
> this must be a mistake; the loop must go through the whole range of the 
> integral type;

No mistake.

> 
>>> for ( i32Iter = -2147483648; i32Iter<= 2147483647; i32Iter++ )
>>
>> The condition expression for that loop is "i32Iter<= 2147483647". A C
>> for loop terminates when the specified condition becomes false. For what
>> value of i32iter do you expect that condition to be false?
> 
> already understood; in other words: the language that is nearest to the 
> system can't handle the most primitive 'structures'; why?
> 

Perhaps it is because you don't need to write code like this very often? 
  And when you do, you can use a while loop, or bigger types, and let 
the compiler figure out the optimal code.

No language is ever going to be the simplest or most compact for all code.

[toc] | [prev] | [next] | [standalone]


#148755

FromBen Bacarisse <ben.usenet@bsb.me.uk>
Date2020-01-04 16:20 +0000
Message-ID<87d0bznqh9.fsf@bsb.me.uk>
In reply to#148750
"Walter H." <Walter.H-Nntp@mathemainzel.info> writes:

> On 03.01.2020 14:26, James Kuyper wrote:
>> On 1/3/20 7:27 AM, Walter H. wrote:
>> ...
>>> long int i32Iter;
>>
>> That name implies that you expect long int to be a 32-bit type.
>
>> On many systems it is, on other systems it is not.
>
> have you an example of a system where it is not?

The laptop I am on at the moment running Linux.

> (I have never heard of this)
>
> the only thing it type int
> maybe it is 16-bit (on 16-bit systems like DOS)
> or it is 32-bit (on 32-bit systems like OS/2, WinNT x86, Linux, ...)

Most (all?) 64-bit Linux systems have 64-bit long.

>> If it's important to you that
>> it be an exactly 32-bit int, use int32_t.
>
> mostly there are other types either #define or typedef's like
> DWORD, BYTE, WORD, ...

What do you mean by mostly?  Those are provided by non-standard header
files.  int32_t and it's friends int_least32_t and int_fast32_t are
standard types defined (in stdint.h) by the C language.

<cut>
>> The problem with the code below comes precisely from the fact that long
>> int apparently is a 32-bit type. In order to write code this way, you
>> need a type bigger than 32 bits:
>
> this must be a mistake; the loop must go through the whole range of
> the integral type;

From what you wrote below, I think you mean this is a mistake in C.  You
appear to agree with James that the code:

>>> for ( i32Iter = -2147483648; i32Iter<= 2147483647; i32Iter++ )

is wrong.

>> The condition expression for that loop is "i32Iter<= 2147483647". A C
>> for loop terminates when the specified condition becomes false. For what
>> value of i32iter do you expect that condition to be false?
>
> already understood; in other words: the language that is nearest to
> the system can't handle the most primitive 'structures'; why?

It can.  Several ways to do this have been posted.

-- 
Ben.

[toc] | [prev] | [next] | [standalone]


#148765

From"Walter H." <Walter.H-Nntp@mathemainzel.info>
Date2020-01-04 18:43 +0100
Message-ID<h7c15uFobghU1@mid.individual.net>
In reply to#148755
On 04.01.2020 17:20, Ben Bacarisse wrote:
> "Walter H."<Walter.H-Nntp@mathemainzel.info>  writes:
>
> Most (all?) 64-bit Linux systems have 64-bit long.

I see, and this fact reduces the portability to a minimum;
64-bit Windows systems have 32-bit long.

>>> If it's important to you that
>>> it be an exactly 32-bit int, use int32_t.
>>
>> mostly there are other types either #define or typedef's like
>> DWORD, BYTE, WORD, ...
>
> What do you mean by mostly?

most times

programmes are not only standard C, they use APIs of 3rd party
like Win32 API, ...

> Those are provided by non-standard header files.
of course;
if we were using only standard header files there wouldn't be any 
programme having a graphical interface ...
just to think about this;

> From what you wrote below, I think you mean this is a mistake in C.
yes

>>> The condition expression for that loop is "i32Iter<= 2147483647". A C
>>> for loop terminates when the specified condition becomes false. For what
>>> value of i32iter do you expect that condition to be false?
>>
>> already understood; in other words: the language that is nearest to
>> the system can't handle the most primitive 'structures'; why?
>
> It can.  Several ways to do this have been posted.

yes but they look weired as I found one myself at the OP;

this one looks weired too
[code]
#include <stdio.h>
#define ANYVALUE 0x0815
int main( int argc, char* argv[ ] )
{
     short int nIter = ANYVALUE;
     long lSum = 0;
     while ( ++nIter != ANYVALUE )
         lSum += nIter;
     printf( "sum: %ld\n", lSum );
     return 0;
}
[/code]
and the result of 'sum: -34837' needs an explanation;
to rely on an overrun is a bit obfuscated, I'd say;

[toc] | [prev] | [next] | [standalone]


#148766

FromDavid Brown <david.brown@hesbynett.no>
Date2020-01-04 19:28 +0100
Message-ID<quqlg0$mc0$1@dont-email.me>
In reply to#148765
On 04/01/2020 18:43, Walter H. wrote:
> On 04.01.2020 17:20, Ben Bacarisse wrote:
>> "Walter H."<Walter.H-Nntp@mathemainzel.info>  writes:
>>
>> Most (all?) 64-bit Linux systems have 64-bit long.
> 
> I see, and this fact reduces the portability to a minimum;
> 64-bit Windows systems have 32-bit long.

I think you have that backwards - the fact that MS decided to make 
"long" on 64-bit Windows merely 32-bit, when the rest of the 64-bit 
world had 64-bit long, reduced portability.

But it is still a very long way from being a "minimum" of portability.

The C standard says that "long int" must be a /minimum/ of 32-bit, but 
places no upper limits.  It also says "long long int" must be a minimum 
of 64-bit, and I have not heard of any C99 implementations with anything 
other than 64-bit for "long long".

When you want portability of exact sizes, use the <stdint.h> types - 
that is what they are for.

> 
>>>> If it's important to you that
>>>> it be an exactly 32-bit int, use int32_t.
>>>
>>> mostly there are other types either #define or typedef's like
>>> DWORD, BYTE, WORD, ...
>>
>> What do you mean by mostly?
> 
> most times

That is not any better.  On most systems, these types are not defined at 
all.  And on systems where they are defined, "WORD" might reasonably be 
16-bit or 32-bit.  (It could be anything else, but those are the common 
choices.)  The term "byte" is defined in the C standards as the minimum 
size of data that can be addressed - on some devices, this is bigger 
than 8-bit (I've used C on devices with 16-bit "bytes" and 32-bit 
"bytes").  In common usage, "byte" is always 8 bits - but that might not 
apply in the context of C programming.

I have also see types with those kinds of names as both signed integer 
types and unsigned integer types.

So while those names might be reasonable enough in a very specific 
context - such as non-portable Windows programming - they are hopeless 
for general coding or portable coding.

> 
> programmes are not only standard C, they use APIs of 3rd party
> like Win32 API, ...
> 

Of course - most C code is at least somewhat limited in its portability, 
and there is not problem with that (as long as you are aware of the 
fact).  But you should not use type names, or make assumptions, that 
pointlessly limit portability and make code harder to understand for others.

>> Those are provided by non-standard header files.
> of course;
> if we were using only standard header files there wouldn't be any 
> programme having a graphical interface ...
> just to think about this;
> 
>> From what you wrote below, I think you mean this is a mistake in C.
> yes
> 
>>>> The condition expression for that loop is "i32Iter<= 2147483647". A C
>>>> for loop terminates when the specified condition becomes false. For 
>>>> what
>>>> value of i32iter do you expect that condition to be false?
>>>
>>> already understood; in other words: the language that is nearest to
>>> the system can't handle the most primitive 'structures'; why?
>>
>> It can.  Several ways to do this have been posted.
> 
> yes but they look weired as I found one myself at the OP;
> 
> this one looks weired too
> [code]
> #include <stdio.h>
> #define ANYVALUE 0x0815
> int main( int argc, char* argv[ ] )
> {
>      short int nIter = ANYVALUE;
>      long lSum = 0;
>      while ( ++nIter != ANYVALUE )
>          lSum += nIter;
>      printf( "sum: %ld\n", lSum );
>      return 0;
> }
> [/code]

That is not a good way to write the code - precisely because relying on 
wrapping (or "overrun") is obfuscated, as well as 
implementation-dependent.  (And if the platform has "int" and "short 
int" the same size, it is undefined behaviour.)

> and the result of 'sum: -34837' needs an explanation;
> to rely on an overrun is a bit obfuscated, I'd say;

[toc] | [prev] | [next] | [standalone]


#148767

FromBart <bc@freeuk.com>
Date2020-01-04 18:59 +0000
Message-ID<ag5QF.710364$o8x.498556@fx15.am4>
In reply to#148766
On 04/01/2020 18:28, David Brown wrote:
> On 04/01/2020 18:43, Walter H. wrote:
>> On 04.01.2020 17:20, Ben Bacarisse wrote:
>>> "Walter H."<Walter.H-Nntp@mathemainzel.info>  writes:
>>>
>>> Most (all?) 64-bit Linux systems have 64-bit long.
>>
>> I see, and this fact reduces the portability to a minimum;
>> 64-bit Windows systems have 32-bit long.
> 
> I think you have that backwards - the fact that MS decided to make 
> "long" on 64-bit Windows merely 32-bit, when the rest of the 64-bit 
> world had 64-bit long, reduced portability.


I think /you/ have that backwards.

In Windows, having a 'long' that is always 32 bits is going to be more 
portable than a 'long' that is sometimes 32 bits, and sometimes 64 bits, 
which you don't know when you are writing the program.

[toc] | [prev] | [next] | [standalone]


#148790

FromDavid Brown <david.brown@hesbynett.no>
Date2020-01-05 14:24 +0100
Message-ID<quso1q$rff$1@dont-email.me>
In reply to#148767
On 04/01/2020 19:59, Bart wrote:
> On 04/01/2020 18:28, David Brown wrote:
>> On 04/01/2020 18:43, Walter H. wrote:
>>> On 04.01.2020 17:20, Ben Bacarisse wrote:
>>>> "Walter H."<Walter.H-Nntp@mathemainzel.info>  writes:
>>>>
>>>> Most (all?) 64-bit Linux systems have 64-bit long.
>>>
>>> I see, and this fact reduces the portability to a minimum;
>>> 64-bit Windows systems have 32-bit long.
>>
>> I think you have that backwards - the fact that MS decided to make 
>> "long" on 64-bit Windows merely 32-bit, when the rest of the 64-bit 
>> world had 64-bit long, reduced portability.
> 
> 
> I think /you/ have that backwards.
> 

I was referring to the timing.  In the 64-bit world, "long" was 64-bit - 
simple, consistent and somewhat portable.  Then MS came along and messed 
up that portability for 64-bit Windows.

"Portability", or "compatibility", is always a relative term - code 
cannot be "portable" in absolute terms, but portable between two or more 
different systems.  64-bit "long" in 64-bit OS's means improved 
portability between different 64-bit systems.  32-bit "long" in 64-bit 
Windows means improved portability between different Windows systems. 
Which one is most important is highly subjective.

The timing, however, is not subjective.

> In Windows, having a 'long' that is always 32 bits is going to be more 
> portable than a 'long' that is sometimes 32 bits, and sometimes 64 bits, 
> which you don't know when you are writing the program.
> 

[toc] | [prev] | [next] | [standalone]


#148772

FromKeith Thompson <Keith.S.Thompson+u@gmail.com>
Date2020-01-04 13:47 -0800
Message-ID<87blriopvq.fsf@nosuchdomain.example.com>
In reply to#148766
David Brown <david.brown@hesbynett.no> writes:

> On 04/01/2020 18:43, Walter H. wrote:
>> On 04.01.2020 17:20, Ben Bacarisse wrote:
>>> "Walter H."<Walter.H-Nntp@mathemainzel.info>  writes:
>>>
>>> Most (all?) 64-bit Linux systems have 64-bit long.
>>
>> I see, and this fact reduces the portability to a minimum;
>> 64-bit Windows systems have 32-bit long.
>
> I think you have that backwards - the fact that MS decided to make
> "long" on 64-bit Windows merely 32-bit, when the rest of the 64-bit
> world had 64-bit long, reduced portability.
[...]

Yes and no.

Making long 32 bits while most other 64-bit platforms make it 64
bits limits the portability of code that assumes that long is 64
bits, or that pointers are the same size as long.

Making long 64 bits would limit the portability of code that assumes
that long is 32 bits -- and apparently there's a lot of code like
that on Windows.

Either choice is perfectly valid, and does not hurt the portability
of well-written code that doesn't assume a particular size for
type long.  Microsoft had a choice between possibly breaking code
written for other platforms, and possibly breaking code written
for earlier versions of Windows.  I find it difficult to argue that
they made the wrong choice.

-- 
Keith Thompson (The_Other_Keith) Keith.S.Thompson+u@gmail.com
    [Note updated email address]
Working, but not speaking, for Philips Healthcare
void Void(void) { Void(); } /* The recursive call of the void */

[toc] | [prev] | [next] | [standalone]


#148791

FromDavid Brown <david.brown@hesbynett.no>
Date2020-01-05 14:26 +0100
Message-ID<quso58$rff$2@dont-email.me>
In reply to#148772
On 04/01/2020 22:47, Keith Thompson wrote:
> David Brown <david.brown@hesbynett.no> writes:
> 
>> On 04/01/2020 18:43, Walter H. wrote:
>>> On 04.01.2020 17:20, Ben Bacarisse wrote:
>>>> "Walter H."<Walter.H-Nntp@mathemainzel.info>  writes:
>>>>
>>>> Most (all?) 64-bit Linux systems have 64-bit long.
>>>
>>> I see, and this fact reduces the portability to a minimum;
>>> 64-bit Windows systems have 32-bit long.
>>
>> I think you have that backwards - the fact that MS decided to make
>> "long" on 64-bit Windows merely 32-bit, when the rest of the 64-bit
>> world had 64-bit long, reduced portability.
> [...]
> 
> Yes and no.
> 
> Making long 32 bits while most other 64-bit platforms make it 64
> bits limits the portability of code that assumes that long is 64
> bits, or that pointers are the same size as long.
> 
> Making long 64 bits would limit the portability of code that assumes
> that long is 32 bits -- and apparently there's a lot of code like
> that on Windows.
> 
> Either choice is perfectly valid, and does not hurt the portability
> of well-written code that doesn't assume a particular size for
> type long.  Microsoft had a choice between possibly breaking code
> written for other platforms, and possibly breaking code written
> for earlier versions of Windows.  I find it difficult to argue that
> they made the wrong choice.
> 

I was not arguing that MS made the wrong choice - I understand why they 
did it.  (Even then, it can't have been an easy choice - they stayed 
compatible with Windows programmers who thought "long means 32-bit", but 
they would have trouble with Windows programmers who thought "long means 
the same size as a pointer".)

[toc] | [prev] | [next] | [standalone]


#148804

From"Walter H." <Walter.H-Nntp@mathemainzel.info>
Date2020-01-06 20:31 +0100
Message-ID<h7hg9fFss3uU1@mid.individual.net>
In reply to#148772
On 04.01.2020 22:47, Keith Thompson wrote:
> David Brown<david.brown@hesbynett.no>  writes:
>
>> On 04/01/2020 18:43, Walter H. wrote:
>>> On 04.01.2020 17:20, Ben Bacarisse wrote:
>>>> "Walter H."<Walter.H-Nntp@mathemainzel.info>   writes:
>>>>
>>>> Most (all?) 64-bit Linux systems have 64-bit long.
>>>
>>> I see, and this fact reduces the portability to a minimum;
>>> 64-bit Windows systems have 32-bit long.
>>
>> I think you have that backwards - the fact that MS decided to make
>> "long" on 64-bit Windows merely 32-bit, when the rest of the 64-bit
>> world had 64-bit long, reduced portability.
> [...]
>
> Yes and no.
>
> Making long 32 bits while most other 64-bit platforms make it 64
> bits limits the portability of code that assumes that long is 64
> bits, or that pointers are the same size as long.
>
> Making long 64 bits would limit the portability of code that assumes
> that long is 32 bits -- and apparently there's a lot of code like
> that on Windows.
>
> [MS's decision for type long]
>
just to add here which - I think bad decision was made by MS in 1990s 
when the first WinNTs came onto the market ...

the intel x86 architecture was 32-bit and had the following 3 different 
floating point
float - 32-bit, single precision
double - 64-bit, double precision
long double - 80-bit, extended precision that was identical to the FPx87 
floating point unit registers

but with WinNT, the long double was cancelled with this hint:
you have source code compatibility between Alpha, MIPS, PPC and X86
other C/C++ compilers even for WinNT or later had an 80-bit long double,
but sizeof(long double) wasn't 10 as expected it was 12 or 16 for better
alignment to 32-bit


[toc] | [prev] | [next] | [standalone]


#148775

FromBen Bacarisse <ben.usenet@bsb.me.uk>
Date2020-01-04 22:25 +0000
Message-ID<87pnfyn9kx.fsf@bsb.me.uk>
In reply to#148765
"Walter H." <Walter.H-Nntp@mathemainzel.info> writes:

> On 04.01.2020 17:20, Ben Bacarisse wrote:
>> "Walter H."<Walter.H-Nntp@mathemainzel.info>  writes:
<attrubtion lost>
>>>> The condition expression for that loop is "i32Iter<= 2147483647". A C
>>>> for loop terminates when the specified condition becomes false. For what
>>>> value of i32iter do you expect that condition to be false?
>>>
>>> already understood; in other words: the language that is nearest to
>>> the system can't handle the most primitive 'structures'; why?
>>
>> It can.  Several ways to do this have been posted.
>
> yes but they look weired as I found one myself at the OP;
>
> this one looks weired too
> [code]
> #include <stdio.h>
> #define ANYVALUE 0x0815
> int main( int argc, char* argv[ ] )
> {
>     short int nIter = ANYVALUE;
>     long lSum = 0;
>     while ( ++nIter != ANYVALUE )
>         lSum += nIter;
>     printf( "sum: %ld\n", lSum );
>     return 0;
> }
> [/code]
> and the result of 'sum: -34837' needs an explanation;
> to rely on an overrun is a bit obfuscated, I'd say;

Yes, obfuscated and wrong!  To support your case that C has a problem
here you need to consider the best /correct/ solutions and point out how
and why they are all "weird".

-- 
Ben.

[toc] | [prev] | [next] | [standalone]


#148773

FromKeith Thompson <Keith.S.Thompson+u@gmail.com>
Date2020-01-04 14:08 -0800
Message-ID<877e26ooxl.fsf@nosuchdomain.example.com>
In reply to#148750
"Walter H." <Walter.H-Nntp@mathemainzel.info> writes:
> On 03.01.2020 14:26, James Kuyper wrote:
>> On 1/3/20 7:27 AM, Walter H. wrote:
>> ...
>>> long int i32Iter;
>>
>> That name implies that you expect long int to be a 32-bit type.
>
>> On many systems it is, on other systems it is not.
>
> have you an example of a system where it is not?
> (I have never heard of this)

Plenty, including the system I'm typing this on.

> the only thing it type int
> maybe it is 16-bit (on 16-bit systems like DOS)
> or it is 32-bit (on 32-bit systems like OS/2, WinNT x86, Linux, ...)

DOS, OS/2, and WinNT x86 are largely obsolete.  32-bit Linux is
increasingly rare in desktop systems, but common for embedded systems.

>> If it's important to you that
>> it be an exactly 32-bit int, use int32_t.
>
> mostly there are other types either #define or typedef's like
> DWORD, BYTE, WORD, ...

I believe those are specific to MS Windows (or DOS).

> a problem of C and C++ too;
> there must not be a system dependence of how many bits an integral type has;
> I saw C/C++ compilers, where wchar_t was 32-bit ...
> on others this was just 16-bit ...

Typically wchar_t is 32 bits on Linux-based systems (because you need
more than 16 bits to represent all Unicode characters) and 16 bits on
Windows (because Microsoft started adopting Unicode when it still fit in
16 bits, and has been unable to make a clean transition to modern
character sets).

>> These typedefs can all be found in<stdint.h>.
>
> of course, from the view of Turbo C this is future ;-)

Why on Earth would you use Turbo C?

>> The problem with the code below comes precisely from the fact that long
>> int apparently is a 32-bit type. In order to write code this way, you
>> need a type bigger than 32 bits:
>
> this must be a mistake; the loop must go through the whole range of
> the integral type;
>
>>> for ( i32Iter = -2147483648; i32Iter<= 2147483647; i32Iter++ )
>>
>> The condition expression for that loop is "i32Iter<= 2147483647". A C
>> for loop terminates when the specified condition becomes false. For what
>> value of i32iter do you expect that condition to be false?
>
> already understood; in other words: the language that is nearest to
> the system can't handle the most primitive 'structures'; why?

It depends on what you mean by "primitive structures".  C's for loop is
quite different from Pascal's, for example.  Using a Pascal compiler
with 16-bit integer, this loop:

    for I := 32760 to 32767 do ...

will execute "..." for each value from 32760 to 32767, inclusive.
If it's more difficult to do that correctly for a range that includes
the upper bound of the type, the compiler has to generate whatever
code is needed to do the right thing.

A C for loop, on the other hand, specifies a different abstraction
at a lower level.  It's a general iteration facility, not defined
in terms of ranges of integer values.  You can build iteration of
a range of integers, and there are very common idioms to do that:

    for (int i = 32760; i <= 32767; i ++) ...

but you have to handle corner cases yourself.  If int is 16 bits,
then the comparison i <= 32767 is always true.  Because the for
loop doesn't specify a range of integer values, the compiler has
no special-case handling for a for loop, but C's for loop is much
more flexible.  For example, it can iterate over a linked list:

    for (node *p = head; p != NULL; p = p->next) ...

Try doing that with a Pascal for loop.  (Of course you can use a
Pascal while loop, but then you don't get the special handing for
corner cases if you're iterating over a range of integer values.)

I'm not saying that either Pascal's for loops or C's for loops are
*better*, just that they're defined on somewhat different semantic
levels.

-- 
Keith Thompson (The_Other_Keith) Keith.S.Thompson+u@gmail.com
    [Note updated email address]
Working, but not speaking, for Philips Healthcare
void Void(void) { Void(); } /* The recursive call of the void */

[toc] | [prev] | [next] | [standalone]


Page 1 of 4  [1] 2 3 4  Next page →

Back to top | Article view | comp.lang.c


csiph-web