Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How are if statements in C syntactically unambiguous?

I don't know a whole lot about C, but I understand the basics and as far as I can tell:

int main() {
  if (1 == 1) printf("Hello World!\n");
  return 0;
}

and

int main() {
  if (1 == 1) 
    printf("Hello World!\n");
  return 0;
}

and

int main() {
  if (1 == 1) {
    printf("Hello World!\n");
  }
  return 0;
}

are all precisely syntactically equivalent. The statement is true; the string is printed; the braces are (apparently) optional.

Sometimes, especially here on SO, I see something like the following:

int main() {
  if (1 == 1)
    printf("one is one\n");
  printf("is this inside the if statement??/who kn0WS\n");
  return 0;
}

By the power vested in CodeGolf, I have been led to believe that C is whitespace-agnostic; the lexical analyser breaks the tokens up into their component parts and strips whitespace outside strings.

(I mean, the whole reason for the semicolons-on-every-statement-thing is so the parser can strip \n, \t, literal spaces and still know where each statement ends, right??)

So how is it possible to unambiguously parse the previous bit of code (or perhaps someone can come up with a better example of what I mean), if whitespace is to be disregarded?

If C programmers want to write in whitespace-dependent Pythonic syntax, why do they write C, and why is it taught wherever C is taught that it's okay to write lexically ambiguous (both to me, a programmer, and the computer) statements like this?

like image 291
cat Avatar asked Jan 16 '16 20:01

cat


1 Answers

if (1 == 1)
  printf("one is one\n");
printf("is this inside the if statement??/who kn0WS\n");

The second printf() should never execute inside the if statement.

The reason being that the previous line ends with a semicolon, which indicates the end of the if-block to execute.

(I mean, the whole reason for the semicolons-on-every-statement-thing is so the parser can strip \n, \t, literal spaces and still know where each statement ends, right??)

So how is it possible to unambiguously parse the previous bit of code (or perhaps someone can come up with a better example of what I mean), if whitespace is to be disregarded?

Parsing example:

if (1 == 1) // if - ( and ) - statements (or block) follow, skip all whitespace

// no { found -> single statement, scan until ; (outside quotes / comments)

printf("one is one\n"); // ; encountered, end of if-block

Without braces, only one statement belongs to the if-block.

But, as said already, it's a good habit to use braces. If you later add a statement (a quick temporary printf() for example), it will always be inside the block.

Special case:

int i = 0;
while(i++ < 10);
    printf("%d", i);

Here printf() will only execute once. Mark the ; at the end of while().

In case of an empty statement, it's better to use:

while(i++ < 10)
    ;

to make the intention clear (or, as an alternative, an empty block {} can be used as well).

like image 126
Danny_ds Avatar answered Sep 28 '22 00:09

Danny_ds