[c++] GCC / G ++ 컴파일러에서 -pedantic을 사용하는 목적은 무엇입니까?

이 메모 는 다음과 같이 말합니다.

-ansi: 컴파일러에게 ANSI 언어 옵션을 구현하도록 지시합니다. 이것은 ANSI 표준과 호환되지 않는 GCC의 특정 “기능”을 끕니다.

-pedantic:와 함께 사용 -ansi하면 컴파일러는 ANSI 표준을 엄격하게 준수하고 호환되지 않는 코드는 거부합니다.

먼저 첫 번째 것들:

  • GCC / G ++ 컴파일러 의 목적 -pedantic-ansi옵션은 무엇입니까 (위의 설명을 이해할 수 없었습니다)?
  • 누구 든지이 두 가지 옵션을 사용하기에 적합한 환경을 말해 줄 수 있습니까?
  • 언제 사용해야합니까?
  • 그들이 중요합니까?


답변

GCC 컴파일러는 가능한 경우 프로그램을 항상 컴파일하려고 시도합니다. 그러나 경우에 따라 C 및 C ++ 표준은 특정 확장이 금지되도록 지정합니다. gcc 또는 g ++와 같은 호환 컴파일러는 이러한 확장이 발견되면 진단을 발행해야합니다. 예를 들어, gcc 컴파일러의 -pedantic 옵션은 이러한 경우 gcc가 경고를 발행하게합니다. stricter -pedantic-errors옵션을 사용하면 이러한 진단 경고를 오류로 변환 하여 해당
시점에서 컴파일이 실패하게됩니다. 적합한 컴파일러에서 플래그를 지정해야하는 비 ISO 구성 만 경고 또는 오류를 생성합니다.


답변

코딩에서 항상 사용합니다.

-ansi플래그는 동일합니다 -std=c89. 언급했듯이 GCC의 일부 확장 기능을 끕니다. 추가하면 -pedantic더 많은 확장이 해제되고 더 많은 경고가 생성됩니다. 예를 들어, 문자열 리터럴이 509자를 -pedantic초과하면 C89 표준에 필요한 최소 한계를 초과하므로 경고합니다. 즉, 모든 C89 컴파일러는 길이가 509 인 문자열을 허용해야합니다. 그것들은 더 오래 받아 들일 수 있지만, 만약 당신이 pedantic이라면 컴파일러가 더 긴 문자열을 받아 들일 수 있고, pedantic 경고없이 GCC가 그것들을 받아들 일지라도 더 긴 문자열을 사용하는 것은 이식성이 없습니다.


답변

-ansi30 살에 따라 컴파일하는 컴파일러를 요구하는 사용되지 않는 스위치입니다 C 표준의 오래된 개정 , 1990 : ISO / IEC 9899 , 기본적으로 ANSI 표준의 브랜딩입니다 언어 C 프로그래밍 X3.159-1989는 “ . 더 이상 사용되지 않는 이유 ISO에서 C90을 게시 한 후에는 ISO가 C 표준화를 담당 하고 C90에 대한 모든 기술 코드 가 ISO에 의해 게시되었으므로을 사용하는 것이 더 적합합니다 -std=c90.

이 스위치가 없으면 최신 GCC C 컴파일러는 ISO / IEC 9899 : 2011 또는 최신 2018 개정판 에서 표준화 된 C 언어를 준수합니다 .

불행히도 구식의 표준 개정판을 고수 할 수 있다고 믿는 일부 게으른 컴파일러 공급 업체가 있습니다. 표준 개정판은 표준 본문에서도 사용할 수 없습니다.

스위치를 사용하면 코드가 이러한 오래된 컴파일러에서 컴파일되어야합니다.


-pedantic흥미로운 하나입니다. 가 없으면 -pedantic특정 표준이 요청 된 경우에도 GCC는 C 표준에서 허용되지 않는 일부 확장을 허용합니다. 예를 들어 프로그램을 고려하십시오

struct test {
    int zero_size_array[0];
};

C11 초안 n1570 단락 6.7.6.2p1는 말한다 :

선택적 유형 한정자 및 키워드 static 외에도 [및]는 표현식 또는 *를 구분할 수 있습니다. 배열의 크기를 지정하는 표현식을 구분하면 표현식은 정수 유형이어야합니다. 표현식이 상수 표현식 인 경우 0보다 큰 값을 가져야합니다. […]

C 표준에서는 배열 길이가 0보다 커야합니다. 이 단락은 제약 조건에 있습니다 . 표준은 다음 5.1.1.3p1을 말합니다 .

전처리 번역 단위 또는 번역 단위가 구문 규칙 또는 제약 조건의 위반을 포함하는 경우, 행동이 명시 적으로 정의되지 않았거나 구현으로 명시되어 있더라도, 적합한 구현은 적어도 하나의 진단 메시지 (구현 정의 방식으로 식별)를 생성해야한다. 한정된. 다른 상황에서는 진단 메시지를 작성할 필요가 없습니다 .9)

그러나로 프로그램을 컴파일하면 gcc -c -std=c90 pedantic_test.c경고가 생성되지 않습니다.

-pedantic컴파일러가 실제로 C 표준을 준수하게합니다 . 이제 표준에 따라 진단 메시지가 생성됩니다.

gcc -c -pedantic -std=c90 pedantic_test.c
pedantic_test.c:2:9: warning: ISO C forbids zero-size array zero_size_array [-Wpedantic]
     int zero_size_array[0];
         ^~~~~~~~~~~~~~~

따라서 최대한의 이식성을 위해 표준 개정을 지정하는 것만으로는 충분하지 않습니다. 또한 GCC가 실제로 표준 서한을 준수하도록하기 위해 -pedantic(또는 -pedantic-errors)를 사용해야합니다 .


질문의 마지막 부분은 사용에 대한였다 -ansiC ++ . ANSI는 C ++ 언어를 표준화하지 않고 ISO에서만 채택하므로 “프랑스에서 표준화 한 영어”라고 말하는 것만 큼 의미가 있습니다. 그러나 GCC는 여전히 멍청한 것처럼 C ++에서도 그것을 받아들이는 것 같습니다.


답변

기본적으로 ANSI 표준을 구현하는 다른 컴파일러와 다른 운영 체제 / 플랫폼에서 사용하는 라이브러리 / API 호출에주의를 기울이면 코드를 훨씬 쉽게 컴파일 할 수 있습니다.

첫 번째는 GCC의 특정 기능을 끕니다. (-ansi) 두 번째는 표준을 준수하지 않는 GCC의 특정 기능뿐만 아니라 구성 요소에 대해서도 전혀 불평하지 않습니다.


답변

코드를 이식 가능 해야하는 경우 gcc 확장 또는 기타 비표준 기능없이 컴파일되는지 테스트 할 수 있습니다. 코드 -pedantic -ansi가 이론적으로 컴파일되면 다른 ANSI 표준 컴파일러로 컴파일해야합니다.


답변

예상 한 코드를 작성하는 경우 다양한 컴파일러를 사용하여 다양한 플랫폼에서 컴파일하려는 경우이 플래그를 직접 사용하면 GCC에서만 컴파일되는 코드를 생성하지 않아도됩니다.


답변

다른 사람들은 충분히 대답했습니다. 빈번한 확장의 몇 가지 예를 추가하고 싶습니다.

main반환 하는 함수 void입니다. 이것은 표준에 의해 정의되지 않았으므로 일부 컴파일러 (GCC 포함)에서만 작동하지만 다른 컴파일러에서는 작동하지 않습니다. 그런데, int main()int main(int, char**)표준 정의 않는 두 개의 서명이 있습니다.

널리 사용되는 또 다른 확장은 다른 함수 내에서 함수를 선언하고 정의 할 수 있다는 것입니다.

void f()
{
    void g()
    {
       // ...
    }

    // ...
    g();
    // ...
}

이것은 비표준입니다. 이런 종류의 행동을 원한다면 C ++ 11 람다를 확인하십시오.