[c] 왜 자동 a = 1입니까? C로 컴파일?

코드:

int main(void)
{
    auto a=1;
    return 0;
}

파일의 확장명이 .c 인 경우 MS Visual Studio 2012 컴파일러에서 오류없이 컴파일됩니다. 나는 항상 .c 확장자를 사용할 때 컴파일은 C ++이 아닌 C 구문을 따라야한다고 생각했습니다. 또한, 내가 아는 한 유형이없는 auto는 C ++ 11 이후 C ++ 에서만 허용 됩니다 .이 유형은 초기화 프로그램에서 유형이 추론됨을 의미합니다.

내 컴파일러가 C를 고수하지 않거나 코드가 실제로 C 언어로 정확합니까?



답변

auto“로컬 범위”를 의미하는 이전 C 키워드입니다. auto aauto int a함수와 동일하며 함수 내에 선언 된 변수의 기본값은 로컬 범위이므로이 int a예제 와 동일 합니다.

이 키워드는 실제로 어떤 기본 유형 없었다 C의 전신 B,에서 남은입니다 : 모든했다 int포인터, int배열, int(*) 선언 중 하나가 될 것입니다. auto또는 extrn[원문]. C는 “모든 것이 int“를 기본 규칙으로 상속 했으므로 다음과 같이 정수를 선언 할 수 있습니다

auto a;
extern b;
static c;

ISO C는 이것을 제거했지만 많은 컴파일러는 여전히 이전 버전과의 호환성을 위해 그것을 승인합니다. 익숙하지 않은 경우 관련 규칙이 적용되고 있음을 알아야합니다.

unsigned d;  // actually unsigned int

현대 코드에서 여전히 일반적입니다.

C ++ 11은 키워드를 재사용했는데 C ++ 프로그래머가 형식 유추를 위해 원래의 의미로 사용하는 경우는 거의 없었습니다. intC 의 “모든 것 “규칙이 C ++ 98에서 이미 삭제 되었기 때문에 이것은 대부분 안전합니다 . 깨는 유일한 것은 auto T a어쨌든 아무도 사용하지 않은 것입니다. ( 언어의 역사에 관한 그의 논문 어딘가에 Stroustrup은 이것에 대해 언급하고 있지만 지금은 정확한 참고 문헌을 찾을 수 없습니다.)

(*) B에서의 문자열 처리는 흥미로웠다. int각 멤버에 여러 문자 배열을 사용하고 묶을 것이다 . B는 실제로 다른 구문을 가진 BCPL 이었습니다 .


답변

이것은 No에 대한 답변이자 확장 된 주석입니다 . 1999 년 이래로 합법적 인 C가 아닙니다.

예, auto a=1;C1999 (및 C2011)에서는 불법입니다. 이것이 현재 불법이라고해서 현대 C 컴파일러가 그러한 구성을 포함하는 코드를 거부해야한다는 의미는 아닙니다. 괜찮은 현대 C 컴파일러가 여전히 이것을 허용해야한다고 정확히 반대 주장합니다.

clang과 gcc는 모두 1999 또는 2011 버전의 표준에 대해 문제의 샘플 코드를 컴파일 할 때 그렇게합니다. 두 컴파일러 모두 진단을 실행 한 후 불쾌감을주는 것처럼 진행되었습니다 auto int a=1;.

제 생각에는 괜찮은 컴파일러가해야 할 일입니다. clang과 gcc는 진단을 통해 표준을 완벽하게 준수합니다. 표준은 컴파일러가 불법 코드를 거부해야한다고 말하지 않습니다. 표준은 단지 번역 단위에 구문 규칙이나 제약 조건 (5.1.1.3)을 위반 한 경우 적합한 구현이 적어도 하나의 진단 메시지를 생성해야한다고 말합니다.

잘못된 구문이 포함 된 코드가 있으면 적절한 컴파일러는 잘못된 코드를 이해하여 컴파일러가 코드에서 다음 오류를 찾을 수 있도록합니다. 첫 번째 오류에서 멈추는 컴파일러는 그리 좋은 컴파일러가 아닙니다. auto a=1“implicit int”규칙을 적용 하는 방법이 있습니다 . 이 규칙은 컴파일러가 C90 또는 K & R 모드에서 사용될 때 auto a=1와 같이 컴파일러가 해석하도록 auto int a=1합니다.

대부분의 컴파일러는 일반적으로 잘못된 구문이 포함 된 거부 코드 (거부 : 개체 파일 또는 실행 파일 생성 거부)를 수행합니다. 컴파일러 작성자가 컴파일 실패가 최선의 선택이 아니라고 결정한 경우입니다. 가장 좋은 방법은 진단을 실행하고 코드를 수정 한 다음 수행하는 것입니다. 과 같은 구문으로 가득 찬 레거시 코드가 너무 많습니다 register a=1;. 컴파일러는 C99 또는 C11 모드에서 진단 코드를 사용하여 해당 코드를 컴파일 할 수 있어야합니다.


답변

auto2011 표준 C과 그 C++이전에 의미가 있습니다. 변수에 자동 수명, 즉 scope에 의해 결정된 수명이 있음을 의미합니다 . 예를 들어 static수명과 는 달리 범위에 관계없이 변수가 “영구적으로”지속됩니다. auto기본 수명이며 명시 적으로 철자가 거의 없습니다. 이것이의 의미를 바꾸는 것이 안전한 이유입니다 C++.

이제 C99 표준 이전의 변수 유형을 지정하지 않으면 기본값은 int입니다.

따라서 범위에 따라 수명이 결정되는 변수를 auto a = 1;선언하고 정의 int합니다.

( “수명”은 “보존 기간”이라고하는 것이 더 적절하지만 덜 명확하다고 생각합니다).


답변

C와 C ++의 역사적 방언 은 자동 저장 기능 auto이있는 키워드 의미입니다 a. 기본적으로 자동 인 로컬 변수에만 적용 할 수 있으므로 아무도 사용하지 않습니다. 이것이 바로 C ++이 키워드의 용도를 변경 한 이유입니다.

역사적으로 C는 형식 지정자가없는 변수 선언을 허용했습니다. 유형은 기본적으로 int입니다. 따라서이 선언은

int a=1;

나는 이것이 현대 C에서 더 이상 사용되지 않으며 (아마도 금지되어 있다고 생각한다); 그러나 일부 인기있는 컴파일러는 기본적으로 C90으로 설정되어 있으며 (필자가 생각하는 경우), 특별히 요청하면 경고 만 활성화합니다. 와 C99를 지정하거나 GCC로 컴파일하고 -std=c99, 또는 함께 경고를 활성화 -Wall또는 -Wimplicit-int경고를 제공합니다 :

warning: type defaults to int in declaration of a


답변

C에서는 C ++ 11에서 auto와 동일한 기능을 register수행합니다. 즉, 변수에 자동 저장 기간이 있음을 의미합니다.

그리고 C99 이전의 C에서 (그리고 Microsoft 컴파일러는 C99 또는 C11을 지원하지 않지만 일부를 지원할 수는 있지만) 유형은 많은 경우 생략 될 수 있으며 기본값은로 설정됩니다 int.

이니셜 라이저에서 유형을 전혀 사용하지 않습니다. 호환되는 이니셜 라이저를 선택했습니다.


답변

Visual Studio 컴파일 유형은에서 사용할 수 있습니다 right click on file -> Properties -> C/C++ -> Advanced -> Compile As. C 강제 /TC옵션 으로 컴파일되었는지 확인하려면 이 경우 larsmans가 말한 것입니다 (오래된 C auto키워드). 몰라도 C ++로 컴파일 될 수 있습니다.


답변

스토리지 클래스는 C 프로그램 내 변수 및 / 또는 기능의 범위 (가시성) 및 수명을 정의합니다.

C 프로그램에서 사용할 수있는 스토리지 클래스는 다음과 같습니다.

auto
register
static
extern

auto 모든 로컬 변수의 기본 스토리지 클래스입니다.

{
        int Count;
        auto int Month;
}

위의 예제는 스토리지 클래스가 동일한 두 변수를 정의합니다. auto는 함수 내에서만 사용할 수 있습니다 (예 : 로컬 변수).

intauto아래 코드에서 기본 유형입니다 .

auto Month;
/* Equals to */
int Month;

아래 코드도 합법적입니다.

/* Default-int */
main()
{
    reurn 0;
}