101

I am new to C++. I often see conditional statement like below:

if 
  statement_0;
else if
  statement_1;

Question:

Syntactically, shall I treat else if as a single keyword? Or is it actually an nested if statement within the outer else like below?

if 
  statement_0;
else 
  if
    statement_1;
Paul Draper
  • 78,542
  • 46
  • 206
  • 285
modeller
  • 3,770
  • 3
  • 25
  • 49
  • 7
    To your second point. Syntactically it is almost *always* written `else if` – TheNorthWes Jun 23 '14 at 18:46
  • 8
    No, as that would make the grammar still more complex: a word is a word without space. Other languages though have keywords like `elseif` and `ELIF`. In fact only (?) the programming language Algol68 allows a space in an identifier; nice too: `PROC walk through tree ()` – Joop Eggen Jun 23 '14 at 18:48
  • @JoopEggen indeed, I thought about this but I don't have any good references handy. – Shafik Yaghmour Jun 23 '14 at 19:05
  • Fortran (at least up through F77) allowed spaces, and removed them before doing any syntactical processing. You could write `GOTO` or `GO TO`. I never tried it, but presumably you could embed spaces in a variable name too. – Phil Perry Jun 23 '14 at 20:12
  • 3
    Fortran (at least the fixed form versions), and all standardized versions of Algol allow spaces anywhere. One story has it that apparently punch card punchers were prone to adding spaces when typing in code; another simply that allowing spaces in variable names would let programmers use better names and the problems weren't foreseen. – prosfilaes Jun 24 '14 at 07:52
  • @JoopEggen Historic BASIC dialects allowed `GO TO` as alternative to `GOTO`. – glglgl Jun 24 '14 at 14:06
  • 1
    The `elseif` keyword exists in VB and PHP. – Salman A Jun 25 '14 at 07:08
  • 3
    Nitpick: although C++ _officially_ doesn't have keywords with spaces in them, it does have constructs like for all intents and purposes work that way. For instance, `long double`, you have to write that in that way. `longdouble` is incorrect. – Mr Lister Jun 25 '14 at 09:12
  • @MrLister If you want multiple situations to trigger the same behavior. – TylerH Jun 25 '14 at 13:18
  • @MrLister, Agreed. But this may relate to the language design philosophy. I think the way C++ simplify things makes it elegant, while these language introduce extra keywords less elegant. – modeller Jun 25 '14 at 18:02
  • Scala also *kind of* allows for spaces in identifiers but you have to use the `backtick syntax`. – corazza Jun 30 '14 at 22:31
  • @MrLister That is not in any way an example of a keyword with spaces in it. It is a case of two adjacent token identifiers requiring a space to separate them. – user207421 Nov 13 '19 at 00:18
  • @user207421 That's what I said. Or, what I tried to say. Maybe I could word my comment differently, but it's past the 5-minute edit limit now. – Mr Lister Nov 13 '19 at 07:12

8 Answers8

136

They are not a single keyword if we go to the draft C++ standard section 2.12 Keywords table 4 lists both if and else separately and there is no else if keyword. We can find a more accessible list of C++ keywords by going to cppreferences section on keywords.

The grammar in section 6.4 also makes this clear:

selection-statement:
 if ( condition ) statement
 if ( condition ) statement else statement

The if in else if is a statement following the else term. The section also says:

[...]The substatement in a selection-statement (each substatement, in the else form of the if statement) implicitly defines a block scope (3.3). If the substatement in a selection-statement is a single statement and not a compound-statement, it is as if it was rewritten to be a compound-statement containing the original substatement.

and provides the following example:

if (x)
 int i;

can be equivalently rewritten as

if (x) {  
  int i;
}

So how is your slightly extended example parsed?

if 
  statement_0;
else 
  if
    statement_1;
  else
    if
      statement_2 ;

will be parsed like this:

if 
{
  statement_0;
}
else
{ 
    if
    {
      statement_1;
    }
    else
    {
        if
        {
         statement_2 ;
        }
    }
}

Note

We can also determine that else if can not be one keyword by realizing that keywords are identifiers and we can see from the grammar for an identifier in my answer to Can you start a class name with a numeric digit? that spaces are not allowed in identifiers and so therefore else if can not be a single keyword but must be two separate keywords.

Community
  • 1
  • 1
Shafik Yaghmour
  • 154,301
  • 39
  • 440
  • 740
  • 1
    You could deduce this without the standard? In ASM its: `jeq` (`if` | `else if`), `jne` (`if` | `else if`), `jmp` (`else`). Based on that, I'd have said it was a single keyword.. probably not syntactically but instruction-wise. – Brandon Jun 23 '14 at 23:02
  • 19
    @Brandon I highly doubt you could reliably go from assembly language to high level constructs without intimate knowledge of the grammar being used and the compiler itself. – Shafik Yaghmour Jun 24 '14 at 13:52
  • Though do note that this definition potentially leads to the wonderful "dangling else" ambiguous syntax tree problem when defining the grammar in the parser... – Linear Jun 24 '14 at 16:15
  • @Brandon the ASM is more related to the BASIC "IF .. GOTO" (without "THEN") – Mr Lister Jun 25 '14 at 09:19
  • 2
    Some languages don't support `else if`, but instead `elsif`. In those languages, `else if` is truly one keyword. However, C-based languages generally do not, as this answer states. – sfdcfox Jun 25 '14 at 14:15
  • 1
    I think @Krumia wanted to see a final `else` statement. I would appreciate this, too. – Matthias Jul 15 '14 at 20:11
  • @Brandon What you've proven is that you *can't* deduce it from the assembly language, as you've drawn the wrong conclusion from it. – user207421 Nov 13 '19 at 00:20
  • @user207421; Hmm.. My comment was literally 5 years ago and a question.. I think I understood when the guy writing this post got 17 upvotes lol. But thanks :) – Brandon Nov 13 '19 at 02:57
78

Syntactically, it's not a single keyword; keywords cannot contain white space. Logically, when writing lists of else if, it's probably better if you see it as a single keyword, and write:

if ( c1 ) {
    //  ...
} else if ( c2 ) {
    //  ...
} else if ( c3 ) {
    //  ...
} else if ( c4 ) {
    //  ...
} // ...

The compiler literally sees this as:

if ( c1 ) {
    //  ...
} else {
    if ( c2 ) {
        //  ...
    } else {
        if ( c3 ) {
            //  ...
        } else {
            if ( c4 ) {
                //  ...
            } // ...
        }
    }
}

but both forms come out to the same thing, and the first is far more readable.

James Kanze
  • 150,581
  • 18
  • 184
  • 329
  • 1
    Actually, the compiler didn't see literally `else` followed by a `compound-statement`. After an `else`, It look for `statement` (which might be like `return;` or `f()`) or a `compound-statement`... – The Mask Jun 23 '14 at 19:08
  • @TheMask: Per Shafik Yaghmour's answer above, the compiler literally sees a single statement, but *pretends* it saw a compound-statement. – Ilmari Karonen Jun 24 '14 at 08:45
  • This answer dictates that how parser extract tokens. Good. – haccks Jun 26 '14 at 09:12
24

No, it is not.
They are two keywords and, moreover, the second "if" is a substatement "inside" the scope determined by the first "else" statement.

pablo1977
  • 4,281
  • 1
  • 15
  • 41
  • 2
    Though that this well describes what's going on, you may want to add some references for the actual language definitions to prove better what you are saying. – πάντα ῥεῖ Jun 23 '14 at 19:00
  • 2
    @πάνταῥεῖ: You are right about the references, but this work has been well done yet by Shafik Yaghmour. His answer was the accepted one and I have voted up, also. My job is finished here. – pablo1977 Jun 23 '14 at 19:03
16

You can see the scope by using curly braces:

if(X) {
  statement_0;
}
else {
  if(Y) {
    statement_1;
  }  
}

And normally implemented with two distinct keywords, one is if and one is else.

jcklie
  • 4,054
  • 3
  • 24
  • 42
  • So I suppose those who insist that curly braces should be used wherever a compound statement is accepted should be writing all their nontrivial conditionals like this, huh? :) – dlf Jun 23 '14 at 18:54
  • 5
    I think one can overdo anything, even our all beloved curly braces. Don't Do This At Home. – jcklie Jun 23 '14 at 19:01
  • 1
    All the brace-structured languages (that I know of) that *require* curly braces around all substatements, even if composed of a single statement, have a single-token keyword with the meaning "else if". I think that's telling. – zwol Jun 24 '14 at 21:53
  • @Zack: Swift is a language that breaks your rule. It requires curly braces even for single-statement code blocks, but does not have an "else if" keyword. On the other hand, the grammar is quite different from C. An `if-statement` ends with an optional `else-clause`. An `else-clause` is _either_ `else code-block` or `else if-statement`. `code-block` includes mandatory braces. So the `else` keyword can only be followed by `{` or `if`. – GraniteRobert Jun 25 '14 at 02:05
  • @GraniteRobert Haven't had time to look at Swift much at all myself, but that's an interesting data point; I was thinking that a grammar like that was a *possibility* but had never seen it done. And you'll note that that, too, avoids making people write "`else { if ... }`". – zwol Jun 25 '14 at 02:28
  • Adding curly braces to change the syntax used doesn't prove anything about the original syntax used. – user207421 Nov 13 '19 at 00:21
10

As already answered, it isn't. They are two keywords. It's start of two statements one following each one other. To try make it a bit more clear, here's the BNF gramar which deal with if and else statements in C++ language.

 statement:      
    labeled-statement
    attribute-specifier-seqopt expression-statement
    attribute-specifier-seqopt compound-statement    
    attribute-specifier-seqopt selection-statement  
    attribute-specifier-seqopt iteration-statement    
    attribute-specifier-seqopt jump-statement  
    declaration-statement
    attribute-specifier-seqopt try-block

   selection-statement: 
         if ( condition ) statement
     if ( condition ) statement else statement

Note that statement itself include selection-statement. So, combinations like:

if (cond1)
   stat
else if(cond2)
   stat
else
   stat

are possible and valid according to C++ standard/semantics.

Note: C++ grammar take from this page.

The Mask
  • 17,007
  • 37
  • 111
  • 185
1

else and if are two different C++ keywords. An if statement can be followed by an optional else if...else statement. An if statement can have zero or more else if's and they must come before the else.

You can find syntax and example in this if...else statement tutorial

Shafik Yaghmour
  • 154,301
  • 39
  • 440
  • 740
clever_bassi
  • 2,392
  • 2
  • 24
  • 43
-1

An if statement can be followed by an optional else if...else statement, which is very useful to test various conditions using single if...else if statement.

When using if , else if , else statements there are few points to keep in mind.

An if can have zero or one else's and it must come after any else if's.

An if can have zero to many else if's and they must come before the else.

Once an else if succeeds, none of he remaining else if's or else's will be tested.

have a look if...else statement tutorial.

Shafik Yaghmour
  • 154,301
  • 39
  • 440
  • 740
KNOWME
  • 61
  • 7
  • 2
    This just doesn't correspond to the standard, and moreover, is redundant. The language has all the expressive power to simulate `else if` as if it were a keyword, so there'd be no sense in defining it explicitly. – Ruslan Jun 24 '14 at 14:18
  • 1
    This is a useful simplification for programmers. But the question isn't asking how to use if statements. – Cruncher Jun 25 '14 at 13:17
-1

I would just like to add my point of view to all these explanations. As I see it, if you can use these keywords separately, they must be TWO keywords. Maybe you can have a look at c++ grammar, from this link in stackoverflow: Is there a standard C++ grammar?

Regards

Community
  • 1
  • 1
Trouble-lling
  • 333
  • 5
  • 15