10

In the C programming language, it is possible to omit a code block in the case of a single statement, for example:

if(1) exit();

Now, does this only apply to conditionals ? Why is this not valid in the case of functions:

void f(int a) exit();
Armen Tsirunyan
  • 130,161
  • 59
  • 324
  • 434
overscore
  • 513
  • 4
  • 15
  • 4
    Because the standard says so? – Georg Fritzsche Jul 07 '11 at 14:40
  • 1
    never tried it, but I suppose that, if it is not allowed, it is just a matter of syntax, maybe legacy: once you would have written void f(a) int a; { ... }, so the { } were needed to mark the end of argument type declaration block ... maybe... – ShinTakezou Jul 07 '11 at 14:42
  • thanks, I knew of the old function syntax, but this also means compilers are able to correctly parse this then.. – overscore Jul 07 '11 at 14:48
  • compilers are able to correctly parse that (at least, gcc can). – ShinTakezou Jul 07 '11 at 14:59
  • See this related question, asking the same question about C#: http://stackoverflow.com/questions/6016654/why-do-methods-with-only-one-statement-need-braces/6019199#6019199 – Eric Lippert Jul 07 '11 at 16:29

3 Answers3

20

It's a feature of C syntax. In BNF, a function definition is something like

FUNC_DEF ::= TYPE IDENTIFIER "(" PARAM_LIST ")" BLOCK

while a statement is

STATEMENT ::= (EXPRESSION | DECLARATION | CONTROL | ) ";" | BLOCK
BLOCK ::= "{" STATEMENT* "}"

(simplifying to allow intermixed declarations and statements, which C++ allows but C doesn't), and an if statement is

CONDITIONAL ::= "if" "(" EXPRESSION ")" STATEMENT

omitting the else part for now.

The reason for this is that otherwise, you could write the function

void no_op() {}

as

void no_op();

but the latter syntax is already in use to denote a declaration.

Fred Foo
  • 355,277
  • 75
  • 744
  • 836
  • I think it's intrasting question from the C parser point of view. Because I dont see any contradiction in the second statment for parser. But any way +1 – Fedor Skrynnikov Jul 07 '11 at 14:52
  • Thanks ! This is exactly the kind of answer I was looking for, and you remind me why I like CS ! – overscore Jul 07 '11 at 14:53
  • The `int no_op() {}` as `no_op()` looks more confusing. – Michas Jul 07 '11 at 15:24
  • Though you could forbid the `void no_op();` syntax for definitions, e.g. `FUNC_DEF ::= TYPE IDENTIFIER "(" PARAM_LIST ")" (BLOCK|STATEMENT)`. But that would be really confusing to newbies and even apprentices. – Sebastian Mach Jul 07 '11 at 15:45
  • @phresnel: I updated the `STATEMENT` rule to more accurately reflect C syntax; `;` by itself is a valid statement, so your suggestion would not work. – Fred Foo Jul 07 '11 at 16:22
  • @larsmans: My post was exactly about your `STATEMENT` ;) You could still make special kludges like `STATEMENT ::= (FOO| ) ";" | BLOCK` and then `FOO ::= EXPRESSION | DECLARATION | CONTROL`, but as said, I would find it too confusing for the language. – Sebastian Mach Jul 08 '11 at 07:07
4
  • The syntax of a conditional statement is this:

    if(expression) statement
    
  • A compound statement is a statement.

  • A compound statement is defined as

    { zero or more statements }
    
  • The syntax of a function definition is this

     function_declaration compound_statement
    
  • So, by definition a function body must be a compound statement and have {}

  • QED :)

Armen Tsirunyan
  • 130,161
  • 59
  • 324
  • 434
1

There is a very old dialect of C, the K&R C. In this dialect the function declaration may look like this:

fun_a(a,b)
char a;
float b;
{
        fun_b(b,a);
}

I think it would be too hard to parse it without { and }.

Michas
  • 8,534
  • 6
  • 38
  • 62
  • This is probably the historical reason, +1, but there's also a reason why the syntax hasn't changed in ANSI C. – Fred Foo Jul 07 '11 at 15:20