Path: csiph.com!eternal-september.org!feeder.eternal-september.org!reader01.eternal-september.org!.POSTED!not-for-mail From: Keith Thompson Newsgroups: comp.lang.c Subject: Re: for-loop mutates to an endless-loop Date: Sat, 04 Jan 2020 14:08:06 -0800 Organization: None to speak of Lines: 102 Message-ID: <877e26ooxl.fsf@nosuchdomain.example.com> References: Mime-Version: 1.0 Content-Type: text/plain Injection-Info: reader02.eternal-september.org; posting-host="ae6c07825fe602dea7ed53b20475ec70"; logging-data="23288"; mail-complaints-to="abuse@eternal-september.org"; posting-account="U2FsdGVkX1+AnGkFbYRpaCCC8324x1Dq" User-Agent: Gnus/5.13 (Gnus v5.13) Emacs/26.3 (gnu/linux) Cancel-Lock: sha1:ef34tIyFekjdwLnJ3QooeJKObwE= sha1:SGlRWe3UPOUIcyLyQI21fTagvl8= Xref: csiph.com comp.lang.c:148773 "Walter H." 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. > > 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 */