Hacker News new | past | comments | ask | show | jobs | submit login

> for (firsttime = 1; ; firsttime = 0) {

does this line predate the while loop?

or boolean values in C?




>does this line predate the while loop?

It's the other way around. Very early C didn't have a for loop. It seems it was introduced in Unix V5: http://minnie.tuhs.org/cgi-bin/utree.pl?file=V5/usr/c/c00.c

And a for loop is basically just a while one, but they are sometimes used in different ways than the usual `for (size_t i = 0; i < len; ++i)`. One of my favorites is http://git.musl-libc.org/cgit/musl/tree/src/internal/floatsc....

>or boolean values in C?

1 and 0 are boolean values in C. But C didn't have a boolean type until C99 (called _Bool or bool after including <stdbool.h>).


What does that loop even do?


  > What does that loop even do?

  for (i=0; i<8 && (c|32)=="infinity"[i]; i++)
    if (i<7) c = shgetc(f);
It's a pattern matching loop. The 'c' variable is a character which is read from FILE * f. In this case, it's attempting to match the string "infinity" which has a length of 8. With ASCII, uppercase letters start from hex value 0x41 for the letter 'A'. Lowercase letters start from hex value 0x61 for the letter 'a'. Thus the difference between lowercase and uppercase is 0x20 which is 32 decimal or 100000 in binary. Thus, if you or the value of 'c' with 32 (0x20 or 00010000), you're setting the 2^5 bit of the character which converts uppercase to lowercase and leaves lowercase unchanged since all lowercase characters already have that bit set.

I'm sure you can figure out the rest. As long as the character matches the corresponding index position in the character array "infinity", the for loop keeps matching characters. Eventually, a successful match results in a return value of sign * INFINITY from the function.


Woe to the developer trying to parse 0x13a0ce!


The whole function is trying to parse a float value, that loop is looking for the string "Infinity".

c|32 will do a bitwise downcase of an ascii character so, "INFINITY", "infinity", "INfinITy" will all be accepted. In any of those cases i == 8 at the end of the loop and is still in scope, so the following if statement will ultimately return + or - Infinity.


ASCII case-insensitive comparison of up to 8 characters from a stream with "infinity".


It's not a while loop... well, maybe a "while 1 {}" loop.

It's closer to an iterator over argv.

First, it sets the firsttime=1 flag, then it tries to open the first argument (file). After the first arg, it sets firsttime=0. It only breaks out of the loop once argv is exhausted.


What's the common way of doing this in C? Is it normally something like this?:

  firsttime=True
  while (True) {
  ..
  ..
  ..
  firsttime=False
  }


Depends on the person. There likely is a correlation on what century you learned programming, but certainly one whether you have experience with pascal-ish languages.

People educated in the Wirth way would say "that's not a for loop; there is no way to tell how often it will iterate when it is first entered" and write it as a while loop.

Old-school C programmers seem to think one iteration construct is enough for everybody and like to write any iteration as a for loop, ideally with a few commas and no actual statements, as in the classic strcpy:

  char *strcpy(char *dst, CONST char *src)
  {
    char *save = dst; 
    for (; (*dst = *src) != '\0'; ++src, ++dst);
    return save;
  }
(from http://www.ethernut.de/api/strcpy_8c_source.html)

Programmers with soe Wirth-style training do at least something like

  char *
  strcpy(char *s1, const char *s2)
  {
    char *s = s1;
    while ((*s++ = *s2++) != 0)
	;
    return (s1);
  }
(from http://www.opensource.apple.com/source/Libc/Libc-167/gen.sub...)

[If you google, you can find way more variations on this. for example, http://fossies.org/dox/glibc-2.20/string_2strcpy_8c_source.h... does a do {...} while(....) that I am not even sure is legal C; it uses offsets into the source to write into the destination]

From your example I guess you are definitely in the Wirth (Pascalish) camp, beyond even that second state. Classic C programmers would either use 0 and 1 for booleans or #define macros FALSE and TRUE (modern C has true booleans, but that extra #include to get it increases compilation time, so why do it?

I am in te Pascal-ish camp. I like to say C doesn't have a for loop because its 'for' is just syntactic sugar for a while loop.


I find the for loop easier to read.


That's probably the cleaner way to do it, but honestly, the hacked for-loop feels pretty clean too. And it ensures that your firsttime flag is properly set, regardless of how you break out of the loop (a 'continue' in the middle of your example would fail to set the flag properly).


C99 introduced the boolean stdlib, so yes it predates that.

Also, as the other guy said, that code has while loops.


There are no booleans in C, just ints. I think c99 added a 'bool' type, but it's just typedef'd to being an int.


That is not correct. In C99, _Bool (and the typedef bool) are special, because when any value is converted to _Bool, the result is 0 or 1 (!!x). Although the standard does not explicitly say that _Bool can only hold anything other than 0 and 1 (only that it is capable of representing these values), this seems to be the case, effectively.


It's a bit more, the bool type can only hold two values, 0 and 1. (6.3.1.2 Boolean type #1) "When any scalar value is converted to _Bool, the result is 0 if the value compares equal to 0; otherwise, the result is 1."


while loop right above the for loop:

> while ((ch = getopt(argc, argv, "n:")) != -1) {

bool was introduced in C99




Guidelines | FAQ | Lists | API | Security | Legal | Apply to YC | Contact

Search: