声明/定义为C和C++中的语句

Zeb*_*ish 38 c c++ if-statement language-lawyer

当这不能在C中编译时我很困惑:

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

    return 0;
}
Run Code Online (Sandbox Code Playgroud)

我已经习惯了将要编译的C++.我只是愣了一会儿,直到我记得这里的答案是关于如何在C和C++中将不同的东西视为"陈述".这是关于switch语句的.for循环括号后面的"语句"必须同时出现在C和C++中.这可以在添加分号或创建{}波浪形支架块的情况下完成.

在C++中"int a = 7;" 被视为声明,定义和初始化.CI认为它也被认为是所有这些,但在C中它不被视为"声明".

有人可以准确地澄清为什么在C中这不是一个陈述,而在C++中它是?这让我对一个陈述的概念感到困惑,因为一种语言说的是,而另一种语言则说不是,所以我有点困惑.

And*_*dyG 16

C++允许迭代语句的"子语句"隐含为复合语句([stmt.iter])

如果iteration-statement中的子语句是单个语句而不是复合语句,则就好像它被重写为包含原始语句的复合语句一样.例:

while (--x >= 0)
   int i;
Run Code Online (Sandbox Code Playgroud)

可以等同地重写为

while (--x >= 0) {
   int i;
}
Run Code Online (Sandbox Code Playgroud)

C标准没有这种语言.

此外,语句的定义在C++中更改为包含声明语句,因此即使未进行上述更改,它仍然是合法的.


添加大括号使其工作的原因是因为您的声明现在变成了一个可以包含声明的复合语句.

您可以在没有大括号的循环体中拥有标识符,因此您可以这样做:

int a = 5;
for (int i = 0; i < 4; ++i)
    a;
Run Code Online (Sandbox Code Playgroud)


eer*_*ika 11

在C++中,一个声明是(C++ 17标准草案)

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

...
Run Code Online (Sandbox Code Playgroud)

请注意,C++中有声明语句,它们是声明,而且是语句.类似地,简单声明是init语句.但并非所有声明都是陈述.声明语法包含不在语句列表中的内容:

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 ;

...
Run Code Online (Sandbox Code Playgroud)

声明语法列表将持续几页.


在C中,声明是(C11标准草案)

excerpt from Statements and blocks

statement:
    labeled-statement
    compound-statement
    expression-statement
    selection-statement
    iteration-statement
    jump-statement
Run Code Online (Sandbox Code Playgroud)

请注意,没有声明是C中的语句.


因此,语句的含义在语言上明显不同.C++中的语句似乎比C中的语句具有更广泛的含义.


Abh*_*hri 7

根据cppreference,C++包括以下类型statements:

  1. 表达陈述;
  2. 复合语句;
  3. 选择陈述;
  4. 迭代语句;
  5. 跳转声明;
  6. 声明;
  7. 尝试块;
  8. 原子和同步块

虽然Ç考虑以下类型的statements:

  1. 复合语句
  2. 表达陈述
  3. 选择陈述
  4. 迭代语句
  5. 跳转声明

您可以注意到,statementsC 语句中不考虑声明,而C++中则不是这种情况.

对于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
Run Code Online (Sandbox Code Playgroud)

对于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
Run Code Online (Sandbox Code Playgroud)