4

Adding true; / false; is clearly valid C++ code. It compiles and runs just fine.

Similarly, this is the same for statements like int;, void;, {}(no ()), 1+1;, 1 == 1;, or even just 1; ... why? (I'm using Visual C++)

Accumulator
  • 873
  • 1
  • 13
  • 34
  • Because there is no reason why they would not run. But, just having a keyword or some of the other examples you mentioned will do nothing. – Donald Jul 29 '15 at 04:56
  • the reason i ask is because stuff like that doesn't work in java and, probably doesn't work in most languages. – Accumulator Jul 29 '15 at 04:58
  • 1
    `int;` and `void;` are not valid. – M.M Jul 29 '15 at 05:01
  • 1
    Any expression followed by semicolon is a valid statement. Expressions without side effects are kind of pointless as statements, but valid nonetheless. This accounts for `true;`, `false;`, `1+1;`, `1==1;` and `1;`. `{}` is a compound statement that happens to be empty - pretty common as a body of a function or a loop. 'int;' doesn't appear to be valid, and shouldn't compile (gcc rejects it). – Igor Tandetnik Jul 29 '15 at 05:07
  • @MattMcNabb Hmm, why does my compiler allow it :( – Emil Laine Jul 29 '15 at 05:11
  • @zenith maybe an extension, although it should give a diagnostic if you are invoking in conforming mode. I think [dcl.dcl]/3 is the right reference. ("the optional *init-declarator-list* can be omitted only when declaring a class or enumeration") – M.M Jul 29 '15 at 05:11
  • @MattMcNabb Oh yeah, `-pedantic-errors` makes it emit an error, thanks! – Emil Laine Jul 29 '15 at 05:18

5 Answers5

4

Why not? The language specification clearly states that expression statement in C++ looks as follows

<expression>;

This is exactly what you have in your examples like true; or 1 == 1; or 1;.

The {} is just an empty compound statement.

Meanwhile, int; is ill-formed. If the compiler accepts it quietly, it must be some sort of compiler-specific quirk/bug/extension.

AnT stands with Russia
  • 312,472
  • 42
  • 525
  • 765
1

false; and true; are valid statements. They evaluate to false and true respectively and have no side effects.

However, int; is not a valid statement. If VS allows it, that is a bug in VS.

{}; is an empty compound or block statement {} and an empty statemet ;. Both are legal constructs.

1 == 1; is a legal statement. It evaluates to true and has no side effects.

1; is a legal statement. It evaluates to 1 and has no side effects.

R Sahu
  • 204,454
  • 14
  • 159
  • 270
1

Those are valid lines of code because there is no reason for them not to be - infact, it would have taken extra effort to program them not to be, and the language designers did not want to go through that extra effort. (However, in some languages such as C#, many of these are not valid).

C++ defines a "statement" (something terminated by a semicolon at the end of the line) to be a few particular statements, such as return x or throw y, or any expression. Expressions must be allowed so that statements such as foo(); are valid. The language designers could have explicitly defined a statement to include function calls and several other things instead of including just any expression, but it was easier to just say any expression. This covers true;, false;, 1+1;, 1==1;, 1;, etc.

In the case of curly braces, it is actually permissible (and sometimes useful) to make curly braces that don't have an associated if/while/for/etc. They declare a new scope. For example, the following prints 2:

void foo() {
    int x = 2;
    {
        int x = 3;
    }
    cout<<x<<endl; //prints 2
}

The language specification can be expressed (approximately) as something called a context-free grammar, and you can find more information about this on Wikipedia.

IanPudney
  • 5,941
  • 1
  • 24
  • 39
  • 2
    C++'s grammar is definitely not context-free. – T.C. Jul 29 '15 at 06:22
  • The C++ grammar is context-free, but whether a program is valid is Turing-complete. Specifically, you could implement a compiler that could *parse* C++ code using a CFG, but fail at *semantic analysis* (which includes things such as type checking). For example, `void x() { x++; } is valid according to the grammar, but is still semantically invalid because you cannot increment a function. – IanPudney Jul 29 '15 at 06:35
  • See http://stackoverflow.com/questions/14589346/is-c-context-free-or-context-sensitive – T.C. Jul 29 '15 at 06:41
  • I've read it :) That's a great example of how the validity of the program is Turing-complete. Take a look at the second answer, though - jpalecek explains the context-free-grammatical nature of the syntax fairly well. – IanPudney Jul 29 '15 at 06:44
  • Well, if you define "the C++ grammar" as "the thing in annex A of the standard", sure, it's context-free. – T.C. Jul 29 '15 at 06:48
  • And IIRC `std::vector>` (no space between `>>`) is't handled by annex A. That's quite obviously context-sensitive. – MSalters Jul 29 '15 at 07:38
  • 1
    @IanPudney The C++ grammar is absolutely not context-free. The classic example: `A * B;` could grammatically be a declaration or an expression statement, depending on whether name lookup determines `A` to refer to a type or to a variable. One cannot determine which grammatical production to apply without considering the context in which the construct appears. – Igor Tandetnik Jul 29 '15 at 13:30
1

void;, int; are ill formed as stated before (lets get these out of the way).

Static analyzers and code checking tools will inform you on the rest of the expressions being pointless or potentially erroneous. Some C++ compilers will even issue a warning.

The reason C++ accepts such things is because the C syntax accepted them as well and this legacy was carried on. On 'why did C accept them then?' the answer is simply that the language had many parts that were "compiler driven" ie made to ease the work of the compiler writer.

There is a great example in the book 'Deep C secrets' titled "the 20million dollars bug" which turned out to be a line:

x == 2; 

A totally pointless statement which should have been an assignment; no warnings no error (and no money until they found the bug)

Nikos Athanasiou
  • 29,616
  • 15
  • 87
  • 153
0

If your function return value 0 or 1 (any number basically ) (true / false ) or expression can be evaluated then it will result into true or false:

for example if you write :

int func() {
    return true;
}
while ( func() ) {
    ...
}

it will use true.

Cereal_Killer
  • 304
  • 2
  • 13