25

When can I omit curly braces in C? I've seen brace-less return statements before, such as

if (condition)
  return 5;

But this doesn't always seem to work for all statements, i.e., when declaring a method.

Are the rules for brace omission the same as in Java?

Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
ucarion
  • 751
  • 2
  • 8
  • 15
  • 5
    Well, it works every time the language expects a "stament-or-block"... – Kerrek SB Feb 15 '13 at 19:27
  • You can even write >>if (condition) return 5;<< all in one line –  Feb 15 '13 at 19:27
  • 3
    The code in your question is fine. Try to show us something that you don't understand. – David Heffernan Feb 15 '13 at 19:27
  • 7
    It is a very good idea to put those braces in even if they are not need at that precise moment of time. People do add to code and having them it makes it less likely that the extra code is put in the right place. What is the harm of pressing a few extra buttons - lot easier than a Friday afternoon trying to figure out why a bit of code is not working as expected! – Ed Heal Feb 15 '13 at 19:28
  • 3
    @EdHeal I have to agree, wholeheartedly. I cannot think of a single situation in which it is better to omit the curly braces – Dan F Feb 15 '13 at 19:33
  • @DanF and EdHeal: me too. I'm a big fan of Linus Torvalds and I always advice people to adapt the Kernel coding style, and I use it myself - with one exception: I never omit curly brackets. –  Feb 15 '13 at 19:39
  • 2
    By "declaring a method", I think you mean "defining a function". – Keith Thompson Feb 15 '13 at 19:50

10 Answers10

26

The only places you can omit brackets are for the bodies of if-else, for, while, do-while, or switch statements if the body consists of a single statement:

if (cond)
  do_something();

for (;;)
  do_something();

while(condition)
  do_something();

do 
  do_something();
while(condition);

However, note that each of the above examples counts as single statement according to the grammar; that means you can write something like

if (cond1)
  if (cond2)
    do_something();

This is perfectly legal; if (cond2) do_something(); reduces to a single statement. So, for that matter, does if (cond1) if (cond2) do_something();, so you could descend further into madness with something like

for (i=0; i < N; i++)
  if (cond1)
    if (cond2)
      while (cond3)
        for (j=0; j < M; j++)
          do_something(); 

Don't do that.

Eric Postpischil
  • 195,579
  • 13
  • 168
  • 312
John Bode
  • 119,563
  • 19
  • 122
  • 198
15

If you look at the C syntax, there are a number of contexts that require a statement, a term that's defined by the grammar itself.

In any of those contexts, one of the forms of statement you can use is a compound-statement, which consists of an opening brace {, a sequence of zero or more declarations and/or statements, and a closing brace }. (In C89, all declarations in a compound-statement must precede all statements; C99 removed that restriction.)

A function-definition specifically requires a compound-statement, not just any kind of statement. (I'm fairly sure that's the only case where a compound-statement is the only kind of statement you can use). If not for that restriction, you'd be able to write:

void say_hello(void) printf("Hello, World!\n");

But since most function definitions contain multiple declarations and/or statements, there wouldn't be much advantage in permitting that.

There's a separate question: when should you omit braces. In my personal opinion, the answer is "hardly ever". This:

if (condition)
     statement;

is perfectly legal, but this:

if (condition) {
    statement;
}

IMHO reads better and is easier to maintain (if I want to add a second statement, the braces are already there). It's a habit I picked up from Perl, which requires braces in all such cases.

The only time I'll omit the braces is when an entire if statement or something similar fits on a single line, and doing so makes the code easier to read, and I'm unlikely to want to add more statements to each if:

if (cond1) puts("cond1");
if (cond2) puts("cond2");
if (cond3) puts("cond3");
/* ... */

I find such cases are fairly rare. And even then, I'd still consider adding the braces anyway:

if (cond1) { puts("cond1"); }
if (cond2) { puts("cond2"); }
if (cond3) { puts("cond3"); }
/* ... */
Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
Keith Thompson
  • 254,901
  • 44
  • 429
  • 631
  • 4
    +1, as a side note some coding standards always require the `{}` for all iteration statements (`if`, `for`, etc.) even if there is only a single statement. MISRA-C is an example. – ouah Feb 15 '13 at 20:23
  • Rightly so! Having braces already there means (a) you don't have to remember them later, (b) you don't risk catastrophic results if you forget to remember them later (which is presumably a large part of MISRA's angle), and (c) your VCS isn't deluged with diff noise if your coding style says not to use braces when 'unnecessary', puts them on the same line as the initial statement, and you go between single-/multi- line bodies (and remember to add/remove braces...) – underscore_d Sep 12 '18 at 11:34
3

But this doesn't always seem to work for all statements.

Specifically? When a single statement is expected, then it's perfectly valid. Loops, the if statement, etc. all expect a statement and that's either a block, or, well, a single statement without being enclosed in a block.

3

An example:

int a[2][2] = {{1, 2}, {3, 4}};

you can use the valid equivalent form:

int a[2][2] = {1, 2, 3, 4};

Some verbose compilers may warn, but it is valid.

Note that for the if statement (same for the while, the for statement, ...) the {} are not omitted. They are just not requested. The if statement has this syntax:

if (expression) statement

If you want a multiple statement instead of a single statement you can use a compound statement which is surrounded {}.

ouah
  • 142,963
  • 15
  • 272
  • 331
3

You mainly need curly braces when you want to combine multiple statements or expressions into one, e.g.:

{
  x = 1;
  y = 2;
}

So if you put the above under if or else the whole thing in the braces will be executed as a whole, whereas if you omit the braces, only the first one (x = 1; in this case) will be used as part of if or else.

You also typically use them with switch():

switch (x)
{
case 1:
  // Do something
  break;
case 2:
  // Do something else
  break;
}

You typically need them with the do-while statement:

do
{
  printf("%d\n", x);
  x++;
} while (x < 10);

You need them with C89 compilers when you want to define and use a temporary variable in the middle of the code:

int main(void)
{
  puts("Hello, World!");
  {
    int x;
    for (x = 0; x < 10; x++)
      printf("%d\n", x);
  }
  return 0;
}

You use them to begin and end the body of a function, a structure/union definition, an enumeration definition, initialization of a structure/union/array, e.g.:

void blah(void)
{
}

enum e
{
  e1 = 1,
  e2 = 2
};

struct s
{
  int foo;
  int bar;
} s = { 1, 2 };

int a[3] = { 1, 2, 3 };

You may omit them sometimes in initializations, e.g.:

char str2[] = { "abc" };
char str1[] = "abc";
Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
Alexey Frunze
  • 61,140
  • 12
  • 83
  • 180
  • Yes, it is also valid. But as for the string literal example, it is not that the braces can be omitted, but the initializer can be optionally surrounded by `{}` in these particular cases.. – ouah Feb 15 '13 at 19:47
2

You can omit them when there's a single statement you're executing:

for(...)
  printf("brackets can be omitted here");

if(...)
  printf("brackets can be omitted here");
else
  printf("brackets can be omitted here too");

etc.. You can always add them in. It never hurts and help to clarify the scope, but you're pretty safe. The only "catch" I can think of is if you attempt to make a declaration in that scope (which is useless by the way):

if(...)
  int a = 5;

This will cause an error, but that's because you can perform a single statement without curly brackets, not a declaration. It is an important distinction.

Technically speaking, you can even do more than one operation without brackets if they're concatenated with the , operator... not that I advice doing it, but it is just worthy of note:

if(...)
    value++, printf("updated value with brackets");

And to your second part, you can see in the Java specification that the rules are the same. I linked specifically to the if section, but you can see after the if it's expected a statement, thus you can skip the curly brackets.

Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
Mike
  • 47,263
  • 29
  • 113
  • 177
2

Anytime there is a block with more than one line (counting lines as a single statement with a ; )

Examples:

for (i = 0; i < j; i++ ) 
   foo(i);

while (1) 
   foo();

if( bool )
   foo();

void cheese()
   printf("CHEESE");

Everything after the ; in the above lines does not count as 'inside' the block as if there were { }.

dan
  • 155
  • 8
  • In case of function declaration, it doesnt work! It needs braces. When i tried i am getting like as below- _braces.c: In function ‘foo’: braces.c:4: error: expected declaration specifiers before ‘printf’ braces.c:7: error: expected ‘=’, ‘,’, ‘;’, ‘asm’ or ‘__attribute__’ before ‘{’ token braces.c:9: error: expected ‘{’ at end of input_ – Darshan L Aug 10 '18 at 06:03
  • 1
    Yes, the example claiming that braces can be omitted around the body in a function definition is simply wrong. – underscore_d Sep 12 '18 at 11:38
2

If in doubt, use braces. They don't "cost" any extra (unless you absolutely use them incorrectly).

A fairly basic rule is "if you have more than one semicolon at the same indentation, you should have braces". It's not entirely that simple, but as a "one sentence with no ifs, buts or other complications" it will have to do.

And yes, Java being based on C-syntax has the same fundamental rules - there are possibly some weirdness where Java is different from C or C++, but that's unusual/strange things, not something you'd normally hit when writing typical code (I haven't done much Java, so I can't say I've found any of them, but I'm pretty sure there are some differences - they are different languages, after all).

Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
Mats Petersson
  • 126,704
  • 14
  • 140
  • 227
0

The following seems a little tricky:

if (...)

        printf("I'm conditional\n");

I guess the C preprocessor takes care of empty lines, so this statement is fine. Very bad practice of course.

merge
  • 36
  • 3
  • Surplus whitespace is simply not significant in C++ at all; the preprocessor will most likely remove anything beyond the minimum required (spaces between keywords, identifiers, etc.), and in any case the compiler will not pay any attention to it. The next statement or block after the `if` is used as its body, even if it's separated by 20 empty lines and then not indented properly. Misleading indentation is another problem, but compilers are getting good at warning about it finally. Basically, put braces around everything, and stop thinking about it! And definitely don't think of C as Python... – underscore_d Sep 12 '18 at 11:42
  • Can you explain your answer, please? From [the Help Center](https://stackoverflow.com/help/promotion): *"...always explain why the solution you're presenting is appropriate and how it works"*. Please respond by [editing (changing) your answer](https://stackoverflow.com/posts/47531901/edit), not here in comments (***without*** "Edit:", "Update:", or similar - the answer should appear as if it was written today). – Peter Mortensen May 27 '22 at 19:55
0

One could obviously use a for loop without curly braces, and without actually leaving the parentheses!

#include <stdio.h>

int main(){
    for(int i=0; i<10;i++, printf("%d ", i), printf("%d\n", i));
    return 0;
}

1 ... 10

1 ... 10

I copied my own answer from another post I answered.

Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
William Martens
  • 753
  • 1
  • 8
  • 27
  • The other question is probably *[What does a 'for' loop without curly braces do?](https://stackoverflow.com/questions/26289546/)*. – Peter Mortensen May 27 '22 at 20:47