왜 컴파일러 경고를 비활성화해야합니까?


26

이 답변여기에 추가 된 주석은 #pragma지시문을 사용하여 여러 컴파일러 경고를 비활성화하는 방법을 보여줍니다 .

왜 그렇게하고 싶습니까? 일반적으로 경고는 이유가 있으므로 항상 좋은 이유라고 생각했습니다. 경고를 비활성화해야하는 "유효한 사례"가 있습니까? 지금은 아무것도 생각할 수 없지만 아마도 나뿐 일 것입니다.


4
왜 누군가가 이것을 가까운 것으로 표시했는지 확실하지 않습니다. 저에게 상당히 합리적인 질문 인 것 같습니다. +1

@Alastair Pitts : 프로그래머로의 마이그레이션을 제안했습니다. 나는 나중에 내 실수를 깨달았다.
Tugrul Ates

3
경고 메시지는 이유가 있습니다. 그러나 오류 메시지 가 아닌 이유도 있습니다 .
솔로몬 느린

2
@jameslarge 귀하의 의견은 상황을 멋지게 요약합니다. 경고는 상황이 있음을 알려주는 컴파일러 잘못 그럴듯하게 의미있는 가능성이 바로 . 확실히 틀렸다 면 오류 일 것입니다. 일부 경고는 오 탐지 일 수 있으므로 항상 경고를 없애도록 코드를 작성하는 방법이 있어야합니다. 불행히도, 때로는 가장 실용적인 방법은 pragma를 통하는 것입니다. 따라서 이름.
Eric Lippert

비활성화되지 않고 숨어 있습니다. 문제는 여전히 존재하지 않는 것입니다.
Sisir

답변:


11

경고를 비활성화 한 상황은 하나뿐입니다. 경고 오류를 고려하여 일반적으로 경고와 함께 해제되지 않습니다. 그러나 고객에서 API를 개발하는 동안 한 응용 프로그램에서 마이그레이션 단계에 필요했으며 다른 응용 프로그램을 라이브러리에 포함해서는 안되는 문제가 발생했습니다.

API의 모든 사용자에게이 메소드를 호출해서는 안된다고 알리는 가장 좋은 방법은 사용하지 않는 것으로 표시하는 것입니다. 그러나 하나의 유효한 유스 케이스는 컴파일 경고로 표시되었습니다.

Eric Lippert는 컴파일러 팀이 경고에 대해 어떻게 생각하는지에 대한 정보를 찾을 수있는 경고에 대한 몇 가지 게시물을 작성했습니다.

내부 유형의 내부 필드

사용하지 않는 지시문은 경고로 표시되지 않습니다


10

다음은 설명서에서 경고를 비활성화하려는 이유를 설명하는 몇 가지 경고입니다.

다른 예에는 여전히 이전 방법을 사용하거나 로컬에서 읽히지 않고 대신 리플렉션을 사용하는 개인 구성원을 사용하려는 경우 감가 상각 방법 사용에 대한 경고가 포함됩니다.

내 경험상 C #은 C ++과 같은 다른 언어보다 경고를 비활성화 할 필요가 없습니다. 에릭 리퍼 트는 자신의 블로그 에서 "코드가 깨지거나 오해의 소지가 있거나 쓸모가 없다"고 거의 확실하게 말할 수있는 상황에 대해서만 경고를 보려고하기 때문이다.


3
좋은. 첫 번째는 매우 구체적인 사례 정당성을 제공하기 때문에 가장 명확하다고 생각합니다 (예를 들어, 세 번째는 내 팀에서 검토를 통과하지 못하는 코드를 보여줍니다). 이 질문 은 더 이상 사용되지 않거나 사용되지 않는 경고에 대해 설명합니다. 기본적으로 레거시 코드에는 여전히 필요하지만 새 코드를 사용하지 않는 것이 좋습니다. 레거시 코드에는 경고가 표시되지 않아야합니다.
Greg Jackson

나는 엑셀에서 많은 매크로 프로그래밍을 해왔고 자동 저장, 자동 종료, 알림 등과 같은 여러 가지 이유로 경고를 비활성화해야했습니다. 물론 이러한 경고에 대해 나타나지 않을 수도 있습니다 ...
Dave Mess

@ ICR Java에서 컴파일러 경고를 비활성화하는 것을 전혀 기억하지 못합니다. 더 이상 사용되지 않는 방법은 사용하지 않는 것입니다.
Mahmoud Hossam

@Mahmoud 나는 제네릭과 원격으로 복잡한 것을 할 때 "확인되지 않은"경고를 감수 해야하는 경우가 종종 있습니다. 그러나 어리석은 경고에 Java를 C ++로 묶는 것은 불공평합니다. 내 대답을 편집했습니다.
ICR

@ICR Java는 컬렉션에서 형식 안전성을 제공하기 위해 제네릭을 사용하도록 강요하지만 일부는 이것을 제약 조건으로 생각하지만 기능으로 생각하고 코드 작성이 약간 고통 스럽지만 생명을 구하고 C ++ 컴파일러 출력을 절약합니다. STL 또는 템플릿이있는 경우 다소 무섭습니다.
Mahmoud Hossam

8

정기적으로 변형이 발생하는 C의 예 :

int doSomething(int argument1)
{
#ifdef HARDWARE_TYPE_A
    performAction(argument1);
#else
    displayNotSupportedMessage();
#endif
}

인수는 일부 플랫폼에서만 관련이 있지만 관련이없는 플랫폼에서는 컴파일러가 불평 할 것이며 경고로 오류를 변환했기 때문에 빌드를 방해합니다.

경고를 오류로 변환하려면 "이것이 아니라 컴파일러보다 더 잘 알고 있습니다"라는 탈출구가 필요합니다.


6

안전하지 않은 타입 캐스트가 필요 없도록 많은 필수 Java 라이브러리가 업데이트 된 적이 없습니다. 다른 더 중요한 경고를보고 수정하려면 해당 경고를 억제해야합니다.


5

나는 임베디드 작업을하고 컴파일러에 쓸모없는 것처럼 보였지만 실제로 하드웨어에 실제로 영향을 미쳤 기 때문에 경고를 비활성화했을 때 한두 시간을 기억하는 것 같습니다.

다른 시간은 바이트 배열을 나타내는 방법 (예 : char 또는 unsigned char?)과 같은 일부 데이터 구조에 대한 아이디어가 다른 코드베이스에서 작업하는 경우입니다. 이 경우 대안으로 코드를 통과하고 한 부분을 수정하거나 수백 개의 캐스트를 작성하는 것이기 때문에 경고를 비활성화 할 수 있습니다.


3

모범 사례를 위해 노력하는 프로젝트의 경우에도 컴파일러 경고를 선택적으로 비활성화해야하는 몇 가지 이유가 있습니다.

  • 다른 컴파일러 (또는 동일한 컴파일러의 다른 버전) :
    컴파일러는 미묘한 방식으로 경고를 처리합니다. 다른 컴파일러에 영향을 미치지 않는 오 탐지 경고 제공. 이 경우 특정 컴파일러, 특히 어쨌든 지원되지 않는 구형 컴파일러에만 영향을 미치는 위양성 경고를 없애기 위해 유효한 코드를 편집하는 대신 해당 컴파일러에 대해 경고를 비활성화하는 것이 좋습니다.
  • 생성 된 코드 :
    코드 위생과 관련된 일부 경고 (데드 코드, 조건 문의 중복 본문, 유형 제한을 초과하는 비교)는 무해하고 컴파일러가이를 최적화하므로 안전하게 무시할 수 있습니다.
    이러한 무해한 경고를 발생시키지 않는 코드를 생성하는 것도 물론 선택 사항이지만 그보다 가치가있을 수 있습니다.
  • 외부 코드에 대한 경고 :
    아마도 프로젝트에 포함 된 잘 알려진 qsort 또는 md5 체크섬 구현을 사용하고있을 것입니다. 이 코드는 많은 프로젝트에서 사용되며 잘 작동하는 것으로 알려져 있지만 일반적으로 자신의 코드에 맞도록 까다로운 경고가있을 수 있습니다.
    외부 코드는하지만, 그냥 (그 확실히 가정 경고를 해제 덜 번거 로움이 될 수 있다 무해).
  • 시스템 헤더로 인한 경고 :
    지원 -isystem과 같은 GCC / Clang에도 불구 하고 시스템 헤더의 차이로 인해 무시 될 수있는 경고가 발생하는 경우가있을 수 있습니다 (어쩌면 함수는 시스템간에 부호있는 리턴 값을 가지지 만) -Wsign-compare.
    또 다른 경우는 시스템 헤더에 정의 된 매크로 일 수 있습니다. 매크로를 수정하기 위해 매크로를 복사하여 붙여 넣을 수는 있지만 타사 라이브러리의 매크로를 유지 관리하는 것에 대해 걱정할 필요가없는 모든 것이 좋습니다. ( -Wsign-conversion예를 들어 , 매크로에 캐스트가 누락 된 경우) 경고를 끄십시오 .
  • 스텁 코드에서 사용되지 않은 경고 :
    스텁 기능 만 포함 된 단일 파일에서 전체 라이브러리를 스텁 할 때 사용하지 않는 매개 변수에 대해 경고 할 수 있습니다 (void)arg1; (void)arg2; (void)arg3; .... 모든 스텁 함수의 본문에 강제 적용하는 것은 도움이되지 않습니다 . 이 경우에는
    억제 -Wunused-parameter하는 것이 좋습니다.

이러한 모든 예에, 그것의 경고를 해제하는 것은 실제 버그를 숨길하지 않을 것으로 가정하는 것을 참고, 예를 들면 : -Wredundant-decls, -Wunused-parameter, -Wdouble-promotion, 아마 -Wpedantic... 그리고 당신이 무슨 일을하는지 알고!


2

유효하거나 그렇지 않은 경우, 때때로 빌드 서버에서 "경고를 오류로 처리"지시문을 무시하기 위해 수행됩니다.

그 외에는 어느 것도 생각할 수 없습니다. 비활성화 된 경고는 일반적으로 "못생긴 hax"의 표시입니다 ...


2

마지막으로 특정 경고를 비활성화했을 때 인턴이 잘못된 코드를 남겼 기 때문입니다. 우연한 데이터 표현을 대체하는 명확한 변환 경계를 사용하여 훨씬 잘 작동했습니다.

그동안 컴파일해야했고 "경고는 오류입니다"옵션을 원했기 때문에 일부 경고는 표시하지 않았습니다.


2

현재 내가 무시하는 유일한 경고는

  warning C4290: C++ exception specification ignored except to indicate a function is not __declspec(nothrow)  

Microsoft는 C ++ 사양을 구현하지 않으며 (문서는 그렇지 않다고 말합니다!) 함수가 특정 던지기를 선언하도록 허용하고 모든 함수는 throw () 또는 throw (...) 중 하나만 던질 수 있습니다.

HelpViewer 1.1에서 :

 A function is declared using exception specification, which Visual C++ accepts but does not implement. Code with exception specifications that are ignored during compilation may need to be recompiled and linked to be reused in future versions supporting exception specifications. 
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.