Declarations/definitions as statements in C and C++

后端 未结 4 1971
遇见更好的自我
遇见更好的自我 2021-02-03 18:28

I was confused when this wouldn\'t compile in C:

int main()
{
    for (int i = 0; i < 4; ++i)
        int a = 5; // A dependent statement may not be declarati         


        
相关标签:
4条回答
  • 2021-02-03 18:43

    In C++, a statement is (C++17 standard draft)

    excerpt from [gram.stmt]
    
    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
    
    init-statement:
        expression-statement
        simple-declaration
    
    declaration-statement:
        block-declaration
    
    ...
    

    Note that there are declaration statements in C++, which are declarations, and are statements. Similarly, simple declarations are init statements. Not all declarations are statements though. The grammar of declarations contains things that are not in the list of statements:

    excerpt from [gram.dcl]
    
    declaration:
        block-declaration
        nodeclspec-function-declaration
        function-definition
        template-declaration
        deduction-guide
        explicit-instantiation
        explicit-specialization
        linkage-specification
        namespace-definition
        empty-declaration
        attribute-declaration
    
    block-declaration:
        simple-declaration
        asm-definition
        namespace-alias-definition
        using-declaration
        using-directive
        static_assert-declaration
        alias-declaration
        opaque-enum-declaration
    
    simple-declaration:
        decl-specifier-seq init-declarator-listopt ;
        attribute-specifier-seq decl-specifier-seq init-declarator-list ;
        attribute-specifier-seqopt decl-specifier-seq ref-qualifieropt [ identifier-list ] initializer ;
    
    ...
    

    The list of declaration grammars continues on for a few pages.


    In C, a statement is (C11 standard draft)

    excerpt from Statements and blocks
    
    statement:
        labeled-statement
        compound-statement
        expression-statement
        selection-statement
        iteration-statement
        jump-statement
    

    Note that there are no declarations that are statements in C.


    So, the meaning of statement is clearly different in the languages. Statement in C++ appears to have a broader meaning than statement in C.

    0 讨论(0)
  • 2021-02-03 18:47

    C++ allowed that the "substatement" of an iteration statement was implicitly a compound statement ([stmt.iter])

    If the substatement in an iteration-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 statement. Example:

    while (--x >= 0)
       int i;
    

    can be equivalently rewritten as

    while (--x >= 0) {
       int i;
    }
    

    the C standard does not have this language.

    Additionally, the definition of a statement changed in C++ to include a declaration statement, so even if the above change wasn't made, it would still be legal.


    The reason that adding braces makes it work is because your declaration now becomes a compound-statement which can include declarations.

    You are allowed to have an identifier in a loop body without braces, so you can do this instead:

    int a = 5;
    for (int i = 0; i < 4; ++i)
        a;
    
    0 讨论(0)
  • 2021-02-03 18:50

    In C++ declarations are statements while in C declarations are not statements. So according to the C grammar in this for loop

    for (int i = 0; i < 4; ++i)
        int a = 5;
    

    int a = 5; must be a substatement of the loop. However it is a declaration.

    You could make the code to be compiled in C by using the compound statement as for example

    for (int i = 0; i < 4; ++i)
    {
        int a = 5;
    }
    

    though the compiler can issue a diagnostic message saying that the variable a is not used.

    One more consequence that in C declarations are not statements. You may not place a label before a declaration in C. For example this program

    #include <stdio.h>
    
    int main(void) 
    {
        int n = 2;
    
        L1:
        int x = n;
    
        printf( "x == %d\n", x );
    
        if ( --n ) goto L1; 
    
        return 0;
    }
    

    does not compile in C though it compiles as a C++ program. However if to place a null-statement after the label then the program does compile.

    #include <stdio.h>
    
    int main(void) 
    {
        int n = 2;
    
        L1:;
        int x = n;
    
        printf( "x == %d\n", x );
    
        if ( --n ) goto L1; 
    
        return 0;
    }
    
    0 讨论(0)
  • 2021-02-03 19:02

    According to cppreference, C++ includes following types of statements:

    1. expression statements;
    2. compound statements;
    3. selection statements;
    4. iteration statements;
    5. jump statements;
    6. declaration statements;
    7. try blocks;
    8. atomic and synchronized blocks

    While C considers following types of statements:

    1. compound statements
    2. expression statements
    3. selection statements
    4. iteration statements
    5. jump statements

    As you can notice, declarations are not considered statements in C, while it is not this case in C++.

    For C++:

    int main()
    {                                     // start of a compound statement
        int n = 1;                        // declaration statement
        n = n + 1;                        // expression statement
        std::cout << "n = " << n << '\n'; // expression statement
        return 0;                         // return statement
    }                                     // end of compound statement
    

    For C:

    int main(void)
    {                          // start of a compound statement
        int n = 1;             // declaration (not a statement)
        n = n+1;               // expression statement
        printf("n = %d\n", n); // expression statement
        return 0;              // return statement
    }                          // end of compound statement
    
    0 讨论(0)
提交回复
热议问题