Why semicolon is not required after a curled bracket?
Asked Answered
I

12

13

I know that a semicolon is required after a statement (I'm talking about Java, C++, and similar languages), but is not required after a curled bracket. Why so?

if (a > b) 
  printf("hello!"); // semicolon is mandatory

if (a > b) {
  printf("hello!");
} // semicolon is not required

What is the reason? I mean, what is the theory behind this?

Injudicious answered 6/4, 2011 at 5:29 Comment(2)
What does Kaivosukeltaja's sentence mean? I cannot comprehend.Idiomorphic
Frustratingly, they are required in IE9, or you'll get weird non-sensical errors like "Array is undefined" or "Invalid pointer".Bohn
B
8

Because curly brackets are used for grouping statements, but they are not statements themselves.

Ber answered 6/4, 2011 at 5:31 Comment(13)
If that is so, then why semi-colon is required after curly bracket of a class definition?Corsetti
@Nawaz: Technically its not. But to maintain compatibility with C that was inherited from the same section (the declaration part of the grammer) where structs are terminated with ';'Demisemiquaver
@Martin: If its required for whatever reason, then what does "technically its not" mean?Corsetti
this seems to me precise and sufficient answerLatent
@Nawaz: It means it is not required to make the parsing easy. You could drop the the ';' after a class statement and the parser would not have any more difficulty in parsing the language.Demisemiquaver
@Martin: But that is required by the Language!Corsetti
@Nawaz, the semicolon is not required after class definition. It is required after (possibly empty) list of variable definitions that follow the class definition :-)Decemvirate
@Tadeusz: That makes perfect sense to me. ThanksCorsetti
@Tadeusz: also to indicate the non-existence of the name, prototype and optionally definition of the function of which the class is the return type :-)Consecrate
The answer is incorrect. According to the C++ standard { _statement-seq_[opt] } is a compound-statement; a type of statement. The reason they don't require a ; is because the grammar doesn't require it, purely and simply.Haas
@James: We weren't talking about C++ alone.Ber
@Ber But all of the other languages I know use the same basic rule. They define a compound statement production. And those that use a ; terminator and { ... } for the compound statement all omit the ; terminator in the production for the compound statement (probably because the } is unambiguously the end of the statement).Haas
Compound statements can appear everywhere where a statement is expected. Therefore, they are statements.Zoller
D
8

Because the language is defined as:

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

labeled-statement:
    identifier : statement
    case constant-expression : statement
    default : statement

expression-statement:
    expressionopt ; 

compound-statement:
    { statement-seqopt } 

statement-seq:
    statement
    statement-seq statement

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

condition:
    expression
    type-specifier-seq declarator = assignment-expression

iteration-statement:
    while ( condition ) statement
    do statement while ( expression ) ; 
    for ( for-init-statement conditionopt ; expressionopt ) statement

for-init-statement:
    expression-statement
    simple-declaration

jump-statement:
    break ;
    continue ;
    return expressionopt ; 
    goto identifier ; 

declaration-statement:
    block-declaration 

All normal control statements are built recursively from each other. The real work is done by the expression-statement. If you notice the expression-statement is always terminate by the ;. The other statements to watch are the jump-statement.

But the main reason is that they are not needed after the {} block to allow the easy parsing of a statement.

Demisemiquaver answered 6/4, 2011 at 5:45 Comment(5)
I don't think it makes parsing easier or more difficult. I suspect that the main reason they aren't required after a compound statement is because it's easy to determine the end of a compound statement otherwise. (The same logic would apply to a goto as far as the compiler is concerned, but human readers could easily be confused.)Haas
You are write about break/continue/goto its superfluous, there only to make things consistent for the user. But I would love to take take the time to bison the C++ grammer with and without the ';' at the end of the expression-statment to see the increase in conflicts generated.Demisemiquaver
@James: Using this removed the ';' after init_declaration(s) went from 0 to 288 shift/reduce conflicts. (The expression-statement had been replaced by the init_declarations(s) in this grammer file (the comments in the file explain the details))Demisemiquaver
the ; after a declaration is clearly necessary, since a } in a declaration doesn't necessarily signal the end. The same thing isn't true for a compound-statement. Off hand, compound, goto, break and continue statements are the only statements I can think of which would have an unambiguous end without the ;. I suspect that the designers of the language wanted every statement to end with a punctuator, so only dropped the ; from compound statements.Haas
@James: Thanks for the obvious. I was careful which ';' I removed. My original statement holds. Without the ';' after the expressionstatement makes it harder to parse.Demisemiquaver
G
5

The philosphical reasoning aside, down under the hood it's essential that the compiler knows where to separate each command from the next. A bracket is in and of itself a separator, so a semi-colon is unnecessary.

Galop answered 6/4, 2011 at 5:33 Comment(1)
Just a nit, but in C++, the } and the ; aren't separators, but terminators. But you're fundamentally right: the reason a ; isn't necessary is because the } unambiguously tells the compiler where the compound statement ends.Haas
R
3

Most people think of statements as being a simple command, often with a keyword, and some parameters, such as "goto x", "a=y+2", etc. There has to be some indication of where one statement ends and another begins, much like English sentences need to end with a period. Traditionally the grammars of most langauges require semicolons after such statement as such indication.

A { ... } "curly brace pair" is a block, which is a special kind of a statement, but the semicolon isn't needed because the curly braces make the boundaries clear.

Many language also allow ";" by itself, to represent the empty statement. Why would you need one? For the same reason the natural number system requires "zero" instead of "one", and sets can be empty.

But it means you can write:

{ ... } ;

and most langauge compilers accept it without remark. But you should think of it as:

{  ... }
;

and generally there's no good reason to write that.

As a practical matter, languages that accept {} (e.g., "empty brackets") don't need the empty-statement ;, because these are semantically identical. But language designers seem stuck on tradition; have you noticed how every "modern" language seems to be a bad syntactic copy of C?

Rockbound answered 6/4, 2011 at 5:30 Comment(4)
A block is a statement, according to the C++ standard. (But this is true for all other languages I know that have blocks as well.)Haas
@James Kanze: My answer was intended to appeal to programmer's intution (few of them would call a block a statement). You are technically right in that grammars must integrate "blocks" into the category of "statement", to allow blocks where statements in the intuitive sense are allowed. I've revised the answer slightly.Rockbound
I'm not sure what you mean by "programmer's intuition". I would expect that most programmers would think of a block the way that they were taught it. And I can't imagine teaching it as anything other than a compound statement.Haas
@James Kanze: Witness the OP's question, and notice the number of "good question" ticks it has. He/They clearly didn't have the understanding you would have taught.Rockbound
I
1

This is a fair question. A block is a statement. It is natural to desire uniformity, and wonder why all statements are not terminated the same. There is no technical problem if we do require a ; after a block. But we are also lazy, since } can unambiguously mark the end of a statement, we don't want to have to type another marker.

A related observation: in C++, you must end class declaration with a ;

class A
{
    ...
}; // the semicolon is mandatory!

That annoys the heck of a lot of people. The semicolon is required because the language allows some other stuff after } so the } is not a reliable end marker.

In Java, that's not the case. The } ends the class declaration and that is it. So ; is not needed.

Idiomorphic answered 6/4, 2011 at 8:17 Comment(0)
S
0

Putting a semicolon in is the same effect as

if (a > b) {
 printf("hello!");
}printf("Goodbye");

and leaving the printf("Goodbye") part out.

Signora answered 6/4, 2011 at 5:33 Comment(0)
C
0

If you are using the object initialization syntax in C# 3+ a semicolon comes after the bracket

var foo = new Foo
  {
    Bar = "Fizzbuzz"
  };
Crabbe answered 6/4, 2011 at 5:35 Comment(0)
F
0

In this case curly brackets are defining a block of statements. Like any other block. while you are about to declare and initialize the array you must provide the ; because in this case you are writing a statement.

Forespeak answered 6/4, 2011 at 5:35 Comment(0)
C
0

Note : this answer is specific to the C++ language, not Java.

I would say that the semicolon is not required by the language grammar (2003). This is how the language defines the grammar.

The code which you've written is called Compound statement or block and the language specification (2003) defines the grammar of compound statement in the section §6.3/1 as,

So that several statements can be used where one is expected, the compound statement (also, and equivalently, called “block”) is provided.

compound-statement:  
             { statement-seqopt }

statement-seq:  
            statement
            statement-seq statement

Do you see any semi-colon in the grammar shown above? No. That's why the semi-colon is not required after the curly bracket in your code.

Corsetti answered 6/4, 2011 at 5:47 Comment(0)
D
0

The only place you will need a semi-colon after a close curly bracket is after an array initialization as you could continue the line e.g.

int[] i= { 1,2,3}, j= {1};

The semi-colon is required because the '}' here doesn't tell the compiler where the end of the line is.

Similarly

Runnable r = new Runnable() {
   public void run() {
   }
}, r2 = new Runnable() {
   public void run() {
   }
}; // required as you could define another Runnable or an array of Runnable.
Duggan answered 6/4, 2011 at 6:25 Comment(0)
C
-1

Because curly is not the statement it is used to group the statements. It does not need a terminator.

Creeps answered 6/4, 2011 at 5:32 Comment(0)
F
-1

When you use curly braces to enclose a block of code, you don't need semicolon:

namespace Some
{
  void fun(int i)
  { 
    while(i != 0)
    {
      cout<<"i = "<<i<<endl;
      i --;
    }  // semicolon not needed
  }  // semicolon not needed
} // semicolon not needed

In other cases, you need semicolon (like initialization, declaration etc.):

struct A {
// ... declare members
}; // declaration; put semicolon
int a[] = {0, 1, 2};  // initialization; put semicolon
Fitful answered 6/4, 2011 at 6:5 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.