programing

C 및 C++의 문으로서의 선언/정의

padding 2023. 6. 12. 21:11
반응형

C 및 C++의 문으로서의 선언/정의

이것이 C:에서 컴파일되지 않을 때 혼란스러웠습니다.

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

    return 0;
}

저는 이것이 컴파일될 C++에 익숙합니다.저는 C와 C++에서 서로 다른 것들이 어떻게 "문"으로 간주되는지에 대한 여기 SO에 대한 대답을 기억할 때까지 잠시 동안 어안이 벙벙했습니다.이것은 스위치 문에 관한 것이었습니다.for 루프 브래킷 뒤의 "문"은 C와 C++ 모두에 있어야 합니다.이 작업은 세미콜론을 추가하거나 {}개의 꼬불꼬불한 브래킷 블록을 생성하는 데 모두 사용할 수 있습니다.

C++에서 "inta = 7;"은 선언, 정의 및 초기화로 간주됩니다.C에서는 이 모든 것으로 간주되지만, C에서는 "성명"으로 간주되지 않습니다.

C++에서는 왜 이것이 진술이 아닌 것인지 누군가가 정확히 설명할 수 있습니까?이것은 진술이 무엇인지에 대한 저의 개념을 혼란스럽게 합니다. 한 언어는 진술이라고 하고 다른 언어는 진술이 아니라고 하기 때문입니다. 그래서 저는 약간 혼란스럽습니다.

C++는 반복 문의 "부분 문장"이 암시적으로 복합 문([stmt.iter])임을 허용했습니다.

반복 진술서의 대체 진술이 복합 진술서가 아닌 단일 진술서인 경우, 원래 진술서를 포함하는 복합 진술서로 다시 작성된 것과 같습니다.예:

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

와 동등하게 다시 작성할 수 있습니다.

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

C 표준에는 이 언어가 없습니다.

또한 C++에서 선언문을 포함하도록 문의 정의가 변경되었으므로 위의 변경이 이루어지지 않더라도 여전히 합법적일 것입니다.


중괄호를 추가하면 작동하는 이유는 이제 선언이 선언을 포함할 수 있는 복합 진술이 되기 때문입니다.

대괄호 없이 루프 본문에 식별자를 둘 수 있으므로 대신 다음 작업을 수행할 수 있습니다.

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

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

...

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 ;

...

선언문 문법 목록은 몇 페이지 동안 계속됩니다.


C에서 문장은 (C11 표준 초안)

excerpt from Statements and blocks

statement:
    labeled-statement
    compound-statement
    expression-statement
    selection-statement
    iteration-statement
    jump-statement

C에는 문인 선언이 없습니다.


그래서, 진술의 의미는 언어마다 분명히 다릅니다.C++의 문장은 C의 문장보다 더 넓은 의미를 가지고 있습니다.

cpp 선호도에 따르면, C++은 다음의 유형을 포함합니다.statements:

  1. 표현식 진술;
  2. 복합 진술;
  3. 선택 문;
  4. 반복 진술;
  5. 점프 문;
  6. 선언문;
  7. 블록을 시도합니다.
  8. 원자 및 동기화된 블록

C가 다음 유형을 고려하는 동안statements:

  1. 복합 진술
  2. 식문
  3. 선택문
  4. 반복문
  5. 과장된 진술

보시다시피, 선언은 고려되지 않습니다.statementsC에서는 C++에서는 그렇지 않지만, 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

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

C++에서 선언문은 문이고 C에서 선언문은 문이 아닙니다.그래서 이 루프에 대한 C 문법에 따르면.

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

in a = 5; 루프의 대체자여야 합니다.하지만 그것은 선언입니다.

예를 들어 복합 문을 사용하여 C로 컴파일할 코드를 만들 수 있습니다.

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

비록 컴파일러가 변수를 말하는 진단 메시지를 발행할 수 있지만.a사용되지 않습니다.

C 선언에서 한 가지 더 결과는 진술이 아닙니다.C에서는 선언 앞에 레이블을 배치할 수 없습니다.예를 들어 이 프로그램은

#include <stdio.h>

int main(void) 
{
    int n = 2;

    L1:
    int x = n;

    printf( "x == %d\n", x );

    if ( --n ) goto L1; 

    return 0;
}

C++ 프로그램으로 컴파일되지만 C로 컴파일되지 않습니다.그러나 레이블 뒤에 null 문을 배치하면 프로그램이 컴파일됩니다.

#include <stdio.h>

int main(void) 
{
    int n = 2;

    L1:;
    int x = n;

    printf( "x == %d\n", x );

    if ( --n ) goto L1; 

    return 0;
}

언급URL : https://stackoverflow.com/questions/49861965/declarations-definitions-as-statements-in-c-and-c

반응형