auto 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-language로 되어 있는 코드가 사실인가요?
auto
는 "로컬 스코프"를 의미하는 오래된 C 키워드입니다. auto a
와 같다auto int a
로컬 스코프가 함수 내부에서 선언된 변수의 기본값이기 때문에 로컬 스코프는int a
를 참조해 주세요.
이 키워드는 실제로는 C의 이전 B에서 가져온 것입니다.여기서는 베이스 타입이 존재하지 않습니다.모든 것은int
, 포인터int
, 배열int
(*) 선언은 다음 중 하나입니다.auto
또는extrn
[sic] C는 '모든 것이'라는 것을 물려받았다.int
디폴트 룰로서 다음과 같이 정수를 선언할 수 있습니다.
auto a;
extern b;
static c;
ISO C는 이 기능을 없앴지만 많은 컴파일러는 하위 호환성을 위해 여전히 이 기능을 사용하고 있습니다.낯선 것 같으면 관련 규칙이 적용되고 있음을 깨달아야 합니다.
unsigned d; // actually unsigned int
현대 코드에서는 여전히 일반적입니다.
C++11은 C++ 프로그래머가 원래 의미를 가지고 사용하는 키워드를 유형 추론을 위해 재사용했습니다.이것은 대부분 안전합니다. 왜냐하면 "모든 것이"int
C로부터의 규칙은 C++98에서 이미 삭제되어 있습니다.단, 깨지는 것은auto T a
(어쨌든 아무도 사용하지 않았다.) (Stroustrup은 이 언어의 역사에 대한 그의 논문 어딘가에 이것을 언급하고 있지만, 나는 지금 정확한 언급을 찾을 수 없다.)
(*) B의 문자열 처리는 흥미로웠다:int
멤버별로 여러 글자를 채워줍니다.B는 실제로는 구문이 다른 BCPL이었습니다.
이것은 1999년 이후 법적 C가 아니라는 것에 대한 답변이자 확장된 코멘트입니다. 이것을 가능하게 하는 현대의 C 컴파일러는 없습니다.
네.auto a=1;
C1999(및 C2011)에서는 불법입니다.이것이 현재 불법이라고 해서 현대의 C 컴파일러가 그러한 구조를 포함하는 코드를 거부해야 한다는 것을 의미하지는 않습니다.나는 현대판 C 컴파일러가 여전히 이것을 허용해야 한다고 정확히 반대한다.
clang과 gcc는 모두 1999년 또는 2011년 버전의 표준에 대한 질문의 샘플 코드를 컴파일할 때 그렇게 합니다.양쪽 컴파일러가 진단 프로그램을 발행한 후 마치 부적절한 스테이트먼트를 실행한 것처럼 계속 진행합니다.auto int a=1;
.
제 생각에는 이것이 제대로 된 컴파일러가 해야 할 일입니다.진단을 발행함으로써 clang과 gcc는 표준에 완전히 준거합니다.표준에서는 컴파일러가 부정한 코드를 거부해야 한다고 되어 있지 않습니다.표준에서는 변환 유닛에 구문 규칙 또는 제약 조건(5.1.1.3) 위반이 포함되어 있는 경우 적합 실장이 적어도1개의 진단 메시지를 생성해야 한다고만 기술되어 있습니다.
부정한 컨스트럭트를 포함한 코드를 지정하면, 모든 괜찮은 컴파일러는 부정한 코드를 이해하려고 하기 때문에, 컴파일러가 코드내의 다음의 에러를 찾아낼 수 있습니다.첫 번째 오류로 정지하는 컴파일러는 그다지 좋은 컴파일러가 아닙니다.이치에 맞는 방법이 있다auto a=1
즉, "internal int" 규칙을 적용합니다.이 규칙에 따라 컴파일러가 강제로 해석합니다.auto a=1
마치 그런 것처럼auto int a=1
컴파일러가 C90 또는 K&R 모드로 사용되는 경우.
대부분의 컴파일러는 일반적으로 잘못된 구문을 포함하는 거부 코드(거부: 개체 파일 또는 실행 파일 생성 거부)를 수행합니다.이것은 컴파일러 작성자가 컴파일 실패가 최선의 선택이 아니라고 판단한 경우입니다.가장 좋은 방법은 진단 프로그램을 발행하고 코드를 수정한 후 계속 진행하는 것입니다.다음과 같은 구성 요소가 너무 많은 레거시 코드가 있습니다.register a=1;
컴파일러는 이 코드를 C99 또는 C11 모드로 컴파일할 수 있을 것입니다(물론 Diagnostics를 사용합니다).
auto
에 의미가 있다C
그리고.C++
(2011년 기준 이전.이는 변수에 자동 수명, 즉 스코프에 의해 결정되는 수명이 있음을 의미합니다.이것은 예를 들어,static
lifetime. 여기서 변수는 범위에 관계없이 "확장" 상태로 유지됩니다. auto
는 디폴트 라이프 타임으로, 거의 명시적으로 기술되어 있지 않습니다.그래서 에서 의미를 바꾸는 것이 안전했던 것이다.C++
.
자, 들어가겠습니다.C
99 Standard 이전 버전에서는 변수 유형을 지정하지 않으면 기본값이int
.
그래서...auto a = 1;
선언(및 정의)하고 있다.int
variable, 라이프 타임이 스코프에 의해 결정됩니다.
("수명"은 "스토리지 기간"이라고 부르는 것이 더 적절하지만, 저는 이것이 더 명확하지 않다고 생각합니다.)
C와 C++의 역사적 사투리에서는auto
키워드입니다.a
자동 저장 장치가 있습니다.디폴트로는 자동인 로컬 변수에만 적용할 수 있기 때문에 C++는 이 키워드를 사용하지 않습니다.
지금까지 C는 유형 지정자를 지정하지 않고 변수 선언을 허용했습니다.기본값은 입니다.int
따라서 이 선언은 다음과 같습니다.
int a=1;
이것은 현대의 C에서는 권장되지 않는 것 같습니다(아마도 금지되어 있을 것입니다).그러나 일부 인기 있는 컴파일러는 디폴트로 C90으로 설정되어 있습니다(제 생각에 허용되어 있습니다).또, 귀찮게도, 유저가 특별히 경고를 요구하는 경우에만 경고를 유효하게 합니다.GCC를 사용한 컴파일 및 C99 지정 중 하나-std=c99
또는 를 사용하여 경고를 활성화합니다.-Wall
또는-Wimplicit-int
에 경고가 표시됩니다.
warning: type defaults to ‘int’ in declaration of ‘a’
주식회사,auto
같은 의미이다register
Does in C++11: 변수에 자동 저장 기간이 있음을 의미합니다.
C99 이전 C에서는 (및 Microsoft 컴파일러는 C99와 C11 중 어느 것도 지원하지 않지만) 많은 경우 유형을 생략할 수 있습니다.이 경우 기본 설정은 다음과 같습니다.int
.
이니셜라이저의 타입은 전혀 취득되지 않습니다.마침 호환성이 있는 이니셜라이저를 골랐습니다.
Visual Studio 컴파일 유형은 다음 사이트에서 구할 수 있습니다.right click on file -> Properties -> C/C++ -> Advanced -> Compile As
C force로 컴파일 되어 있는지 확인한다./TC
선택.그리고 이 경우, 그것은 라즈먼이 말한 것입니다(올드 C).auto
키워드를 지정합니다.모르는 사이에 C++로 컴파일 될 수 있습니다.
스토리지 클래스는 C 프로그램 내 변수 및/또는 함수의 범위(가시성)와 수명을 정의합니다.
C 프로그램에서 사용할 수 있는 스토리지 클래스는 다음과 같습니다.
auto
register
static
extern
auto
는 모든 로컬 변수의 기본 스토리지 클래스입니다.
{
int Count;
auto int Month;
}
위의 예에서는 스토리지 클래스가 동일한 두 변수를 정의하고 있습니다.auto는 기능(예: 로컬 변수) 내에서만 사용할 수 있습니다.
int
디폴트 타입입니다.auto
아래 코드:
auto Month;
/* Equals to */
int Month;
아래 코드도 합법입니다.
/* Default-int */
main()
{
reurn 0;
}
언급URL : https://stackoverflow.com/questions/23406212/why-does-auto-a-1-compile-in-c
'programing' 카테고리의 다른 글
Vuej로 인해 콘텐츠에 새 행을 추가할 수 없음 (0) | 2022.07.31 |
---|---|
"static" 기능과 "static inline" 기능의 차이점은 무엇입니까? (0) | 2022.07.31 |
Vue JS의 어레이에서 항목 설명 편집 (0) | 2022.07.31 |
Java에서 ByteBuffer의 용도는 무엇입니까? (0) | 2022.07.31 |
Spring Boot + JPA : 열 이름 주석이 무시되었습니다. (0) | 2022.07.31 |