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


136

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

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

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

먼저 첫 번째 것들:

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

답변:


84

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


3
ISO C 및 C ++ 표준은 확장 프로그램이 해당 프로그램의 동작을 변경해서는 안된다는 점에서 "확장 금지"만 해당됩니다. 컴파일러는 확장을 사용하는 프로그램을 거부하지 않습니다.
MM

@MM : 일부 컴파일러는 유용한 구문을 받아들이고 다른 컴파일러는이를 거부 할 때위원회의 "타협"은 적합한 구현이 프로그래머가 무시할 수있는 진단을 발행해야하므로위원회의 요구를 피해야한다는 점에 유의해야합니다. 구조물을 지시하거나 금지합니다.
슈퍼 캣

105

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

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


-ansi는 GCC의 일부 확장자를 끄고 -pedantic은 더 많은 확장자를 끕니다. -ansi가 첫 번째 규칙 인 것처럼 보이며 -pedantic이 더 제한적인 규칙입니다. 이 두 가지 옵션을 제거하면 Microsoft와 같은 다른 컴파일러와 더 호환되는 코드를 만들 수 있습니까?
huahsin68

4
@ huahsin68 : 글쎄요. MSVC는 대부분의 다른 컴파일러와는 다른 컴파일러로 특정 생태계에 더 적합하며 외부에서는 사용할 수 없습니다. 표준과 동일하지 않은 많은 방식으로 자체 방식을 수행합니다. 그럼에도 불구하고 표준 헤더 등을 유지하면 MSVC와 GCC는 상당히 유사합니다. 그러나 사용 -std=c89 -pedantic한다는 것은 다른 플랫폼의 다른 컴파일러간에 더 쉽게 이동할 수 있음을 의미합니다. 을 사용하자마자 <windows.h>다른 시스템과의 호환성에 문제가 생깁니다.
Jonathan Leffler

2
@slf : GNU가 컴파일러를 현금으로 판매하지는 않지만 다른 모든 공급 업체와 마찬가지로 독점 기능을 사용 하시겠습니까? 또는 더 일반적으로 확장 기능이 유용하다고 생각하고 기본적으로 사용하도록 설정해야한다고 생각하기 때문입니다.
Jonathan Leffler

1
무엇 이건 그것은 가치이며, JFTR은 , 내가 주로 사용을 중단했습니다 -pedantic,하지만 난 그것을 (명시 적으로 사용하고 있었다하지 않은 하나 개의 프로그램을 다시 사용하도록 설정하면 내 코드의 대부분은 아직 확인을 컴파일 __int128유형 이다 pedantically 잘못을). 나는 GCC가 너무 마음에 들지 않을 때 개입하는 단계가 있다고 생각 -pedantic합니다. 방금 약 300 개의 소스 파일 (일부 라이브러리 코드, 명령, 일부 SO 테스트 프로그램)을 테스트했으며 예상 할 수없는 문제가있었습니다. 현재 Mac OS X 10.9.2에서 GCC 4.8.2를 사용하고 있습니다.
Jonathan Leffler

1
@JonathanLeffler, 예, 실제로 작동하지 않는 실제 컴파일러의 이름이 무엇인지 쿼리하고 있습니까? 그러한 컴파일러도 하나 있습니까?
Pacerier

23

-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 ++에서도 그것을 받아들이는 것 같습니다.


4
언어 표준이 추가로 개정되었습니다. 오늘은 일반적으로로 컴파일합니다 -std=c11 -Wall -Wextra -Wpedantic -Wconversion.
Davislor

14

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

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


6

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


4
-pedantic모든 확장 기능을 끄지 않고 이중 밑줄로 표시됩니다. 따라서 코드 -pedantic -ansi가로 컴파일되고 다른 구현에서 컴파일되는 것처럼 그럴듯하게 보인다면 컴파일됩니다.
Steve Jessop

3
이중 밑줄을 언급하면 ​​흥미로운 소리입니다. 정확히 무엇을 말하는가?
huahsin68

예를 들어 gcc에는 "__asm ​​__ ()"인라인 어셈블리 코드가 있지만 gcc에는 적합하지만 컴파일러가 표준을 준수하더라도 Windows 컴파일러에서는 이중 밑줄이 작동하지 않을 수 있습니다.

3

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


2
일부 버전의 GCC에서!
Mohamed Amjad LASRI

1

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

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

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

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

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

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


0

Pedantic은 gcc 컴파일러가 ANSI와 호환되는 확장 기능뿐만 아니라 모든 GNU C 확장을 거부하도록합니다.


1
이것은 너무 interesing입니다. GNU C 확장을 언급했으며 이러한 확장은 ANSI 표준 일 수도 있고 아닐 수도 있습니다. 이것에 대해 더 많은 정보를 얻을 수 있습니까? 적절한 리소스를 어디서 구할 수 있습니까?
huahsin68
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.