문맥 상, 저는 Google에서 일하는 Clang 개발자입니다. Google에서는 Clang의 진단 기능을 모든 C ++ 개발자에게 제공했으며 Clang의 경고도 오류로 취급합니다. Clang 개발자와 Clang 진단의 더 큰 사용자 중 하나로서 나는이 플래그들과 그것들이 어떻게 사용될 수 있는지에 대해 밝힐 것이다. 내가 설명하는 모든 것은 Clang에 일반적으로 적용되며 C, C ++ 또는 Objective-C에만 해당되지 않습니다.
TL; DR 버전 : 사용하십시오 -Wall
및 -Werror
개발중인 새로운 코드에 대한 최소한. 우리 (컴파일러 개발자)는 여기에 좋은 이유로 경고를 추가합니다 : 버그를 찾습니다. 버그를 잡는 경고를 발견하면 켜십시오. 보십시오 -Wextra
여기 좋은 후보의 무리에 대해. 그중 하나가 너무 시끄럽게 사용하기에 너무 시끄럽다 면 버그를 신고하십시오 . "명백한"버그가 포함 된 코드를 작성했지만 컴파일러가 경고하지 않은 경우 버그를 신고하십시오.
이제 긴 버전입니다. 먼저 경고 플래그 그룹화에 대한 배경 지식이 있습니다. Clang에는 많은 경고 그룹이 있으며 GCC에는 제한이 있습니다. 이 토론과 관련된 일부 :
- 기본적으로 :이 경고는 명시 적으로 비활성화하지 않으면 항상 켜져 있습니다.
-Wall
: 다음은 개발자가 경고이며 높은 가치와 낮은 위양성률 모두에 대한 신뢰를.
-Wextra
: 이것은 귀중하고 건전한 것으로 여겨지는 경고입니다 (즉, 버그가 없음).
-Weverything
: 말 그대로
Clang의 모든 경고를 활성화하는 미친 그룹입니다 . 코드에서 이것을 사용하지 마십시오. Clang 개발자를 위해 또는 어떤 경고가 있는지 탐색하기위한 것 입니다.
위에서 언급 한 두 가지 주요 기준은 Clang에서 경고가 발생하는 위치를 안내하고 이것이 실제로 무엇을 의미하는지 명확히하겠습니다. 첫 번째는 특정 경고 발생의 잠재적 인
값 입니다. 이는 경고가 발생하고
코드 문제를 올바르게 식별 할 때 사용자 (개발자)에게 기대되는 이점 입니다.
두 번째 기준은 위양성 보고서에 대한 아이디어입니다 . 이러한 상황은 코드에서 경고가 발생하지만 실제로 발생할 수있는 문제는 상황이나 프로그램의 다른 제약 조건으로 인해 발생하지 않습니다. 경고 코드는 실제로 올바르게 작동합니다. 경고는 해당 코드 패턴에서 경고를 발생시키지 않았을 때 특히 나쁩니다. 대신, 경고 구현에 결함이있어 경고를 발생시킵니다.
Clang 경고의 경우 값 은 스타일, 취향 또는 코딩 규칙이 아닌 정확성 측면에 있어야합니다 . 이것은 문장 {}
의 본문 주위에서 s를 사용하지 않을 때마다 경고와 같이 자주 요청되는 경고를 제외하고 사용 가능한 경고 세트를 제한합니다 if
. Clang은 또한 위양성에 매우 관대 합니다. 대부분의 다른 컴파일러와 달리, 구성의 정확한 철자, 추가 '()', 캐스트 또는 전 처리기 매크로의 존재 또는 부재를 포함하여 잘못된 정보를 제거하기 위해 엄청나게 다양한 정보 소스를 사용합니다!
이제 Clang의 실제 예제 경고를 살펴보고 어떻게 분류되는지 살펴 보겠습니다. 먼저 기본 경고 :
% nl x.cc
1 class C { const int x; };
% clang -fsyntax-only x.cc
x.cc:1:7: warning: class 'C' does not declare any constructor to initialize its non-modifiable members
class C { const int x; };
^
x.cc:1:21: note: const member 'x' will never be initialized
class C { const int x; };
^
1 warning generated.
이 경고를 표시하는 데 플래그가 필요하지 않았습니다. 근거는이 코드가 경고 높은주는 정말 올바른 결코 있다는 것이다 값을 , 그리고 경고 연타가 그것을 제로주고,이 버킷에 폭포를 증명할 수있는 코드 만 화재 위양성 비율.
% nl x2.cc
1 int f(int x_) {
2 int x = x;
3 return x;
4 }
% clang -fsyntax-only -Wall x2.cc
x2.cc:2:11: warning: variable 'x' is uninitialized when used within its own initialization [-Wuninitialized]
int x = x;
~ ^
1 warning generated.
Clang에는 -Wall
이 경고에 대한 플래그 가 필요합니다 . 그 이유는 의도 하지 않은 값 을 의도적으로 생성하기 위해 경고하는 코드 패턴을 사용하는 사소한 양의 코드가 있기 때문입니다 . 철학적으로, 나는 이것에 아무런 의미가 없지만 많은 사람들이 동의하지 않으며이 의견의 차이의 현실은 -Wall
깃발 아래 경고를
일으키는 것입니다. 여전히 가치가 높고 오 탐지율이 낮지
만 일부 코드베이스에서는 스타터가 아닙니다.
% nl x3.cc
1 void g(int x);
2 void f(int arr[], unsigned int size) {
3 for (int i = 0; i < size; ++i)
4 g(arr[i]);
5 }
% clang -fsyntax-only -Wextra x3.cc
x3.cc:3:21: warning: comparison of integers of different signs: 'int' and 'unsigned int' [-Wsign-compare]
for (int i = 0; i < size; ++i)
~ ^ ~~~~
1 warning generated.
이 경고에는 -Wextra
플래그 가 필요합니다 .
일치하지 않는 사인온 비교가 매우 일반적인 코드베이스 가 매우 크기 때문입니다 . 이 경고는 몇 가지 버그를 발견하지만 사용자가 작성할 때 코드가 버그 일 확률은 평균적으로 매우 낮습니다. 결과는 매우 높은 오 탐지율 입니다. 그러나 이상한 승격 규칙으로 인해 프로그램 에 버그 가 있는 경우 버그 가 상대적으로 높은 값을 표시 할 때이 경고를 만드는 것은 매우 미묘
합니다 . 결과적으로 Clang은이를 제공하고이를 플래그 아래에 노출시킵니다.
일반적으로 경고는 -Wextra
깃발 밖에서 오래 살지 않습니다 . Clang은 정기적으로 사용하고 테스트하지 않는 경고를 구현하지 않으려 고 노력합니다. 추가 경고 -Weverything
는 일반적으로 활성 개발 중이거나 활성 버그가있는 경고입니다. 그것들은 고정되어 적절한 깃발 아래에 놓이거나 제거되어야합니다.
이제 Clang에서 이러한 기능이 어떻게 작동하는지 이해 했으므로 원래 질문으로 돌아가 보겠습니다. 개발시 어떤 경고를 설정해야합니까? 불행히도 그 대답은 달려 있습니다. 상황에 가장 적합한 경고를 결정하려면 다음 질문을 고려하십시오.
- 모든 코드를 제어 할 수 있습니까, 아니면 외부 코드입니까?
- 당신의 목표는 무엇입니까? 버그 잡기 또는 더 나은 코드 작성?
- 당신의 위양성은 무엇입니까? 정기적으로 경고를 끄는 추가 코드를 작성 하시겠습니까?
우선, 코드를 제어하지 않으면 추가 경고를 설정하지 마십시오. 전원을 끌 준비를하십시오. 세계에는 잘못된 코드가 많이 있으며 모든 코드를 수정하지 못할 수도 있습니다. 괜찮습니다. 코드에 노력 집중하는 방법을 찾는 작업 이 제어합니다.
다음으로, 경고에서 원하는 것을 파악하십시오. 이것은 사람들마다 다릅니다. Clang은 엄청나게 많은 버그 나 버그 패턴이 매우 높다는 것을 나타내는 과거의 선례가 지난 코드 패턴에 대한 옵션없이 경고를 시도 할 것입니다. 가능하면 -Wall
당신은 연타 개발자들이 C ++ 코드에서 관찰 한 가장 일반적인 실수를 잡기를 대상으로 경고 훨씬 더 공격적인 세트를받을거야. 그러나이 두 가지 모두에 대해
위양성 비율은 상당히 낮아야합니다.
마지막으로, 매 턴마다 가양 성 (false-positive) 을 완전히 침묵 시키려고한다면 가십시오 -Wextra
. 실제 버그가 많이 발생하지만 어리 석거나 무의미한 오 탐지가있는 경고가 표시되면 버그를 신고하십시오. 우리는 지속적으로 더 버그-찾는 로직을 더 가져다에서 제시하는 방법을 찾기 위해 노력하고 있습니다 -Wextra
로 -Wall
우리는 가양를 피할 수있는 곳입니다.
많은 사람들이 이러한 옵션 중 어느 것도 그들에게 딱 맞는 것은 아니라는 것을 알게 될 것입니다. Google -Wall
은 경고를 위반 한 기존 코드가 많아 경고를 표시하지 않았습니다. 또한 Google -Wall
에서 특히 높은 가치를 지니고 있기 때문에에 의해 활성화되지 않은 경우에도 명시 적으로 일부 경고를 설정했습니다 . 마일리지는 다를 수 있지만 비슷한 방식으로 다를 수 있습니다. 모든 것보다는 몇 가지 주요 경고를 활성화하는 것이 종종 더 나을 수 있습니다
-Wextra
.
모든 사람 이 -Wall
기존 코드가 아닌 코드를 사용 하도록 권장 합니다. 새 코드의 경우 경고는 거의 항상 가치가 있으며 실제로 코드 개발 경험을 향상시킵니다. 반대로, 나는 모든 사람들이를 넘어서는 플래그를 사용 하지 않도록 권장합니다
-Wextra
. 당신이 연타 경고 찾아내는 경우에 -Wextra
포함되지 않지만 증명하는 모든 가치있는 당신을 단순히 버그를 제출하고 우리는 가능성이 아래를 넣을 수 있습니다 -Wextra
. 경고의 일부 하위 집합을 명시 적으로 활성화할지 여부 -Wextra
는 코드, 코딩 스타일 및이 목록을 유지 관리하는 것이로 밝혀진 모든 항목을 수정하는 것보다 쉬운 지 여부에 크게 좌우됩니다 -Wextra
.
OP의 경고 목록 ( -Wall
및 모두 포함 -Wextra
)에서 다음 경고 만 해당 두 그룹에서 다루지 않습니다 (또는 기본적으로 켜져 있음). 첫 번째 그룹은 강조하는 이유 이상 의존 나쁜 될 수 있습니다 명시 적 경고 플래그에 : 이들 중 어느 것도도 있습니다 구현되지 연타에! GCC 호환성을 위해서만 명령 행에 허용됩니다.
-Wbad-function-cast
-Wdeclaration-after-statement
-Wmissing-format-attribute
-Wmissing-noreturn
-Wnested-externs
-Wnewline-eof
-Wold-style-definition
-Wredundant-decls
-Wsequence-point
-Wstrict-prototypes
-Wswitch-default
원래 목록에서 불필요한 경고의 다음 버킷은 해당 목록의 다른 경고와 중복되는 경고입니다.
-Wformat-nonliteral
-서브셋 -Wformat=2
-Wshorten-64-to-32
-서브셋 -Wconversion
-Wsign-conversion
-서브셋 -Wconversion
범주별로 다른 경고도 선택할 수 있습니다. 이들은 버그가 있거나 버그가없는 코드가 아닌 언어 방언 변형을 처리합니다. 를 제외 -Wwrite-strings
하고 Clang에서 제공하는 언어 확장에 대한 경고입니다. Clang이 사용에 대해 경고하는지 여부는 확장의 보급에 따라 다릅니다. Clang은 GCC 호환성을 목표로하므로 많은 경우 암시 적 언어 확장을 통해이를 쉽게 사용할 수 있습니다. -Wwrite-strings
는 OP에 대해 언급 한 바와 같이 실제로 프로그램 의미를 변경하는 GCC의 호환성 플래그입니다. 나는이 깃발을 깊이 후회하지만, 우리는 지금 가지고있는 유산 때문에 그것을지지해야합니다.
-Wfour-char-constants
-Wpointer-arith
-Wwrite-strings
실제로 잠재적으로 흥미로운 경고를 활성화하는 나머지 옵션은 다음과 같습니다.
-Wcast-align
-Wconversion
-Wfloat-equal
-Wformat=2
-Wimplicit-atomic-properties
-Wmissing-declarations
-Wmissing-prototypes
-Woverlength-strings
-Wshadow
-Wstrict-selector-match
-Wundeclared-selector
-Wunreachable-code
이들에없는 이유 -Wall
또는 -Wextra
항상 명확하지 않다. 이들 중 많은, 그들은 실제로 GCC 경고 (을 기반으로 -Wconversion
,
-Wshadow
등)와 같은 연타는 GCC의 동작을 모방하려고한다. 우리는이 중 일부를 서서히 세밀하고 유용한 경고로 세분화하고 있습니다. 그런 다음 최상위 경고 그룹 중 하나로 만들 확률이 높습니다. 즉, 하나의 경고를 선택하는 -Wconversion
것이 너무 광범위하여 예측 가능한 미래를위한 자체 "최상위"범주로 남아있을 것입니다. GCC는 가지고 있지만 몇 가지 다른 경고는 낮은 값이 및 높은 위양성 비율이 비슷한 더 살지 않는 땅으로 강등 할 수있다.
이것들이 더 큰 버킷 중 하나에없는 다른 이유는 간단한 버그, 매우 심각한 오 탐지 문제 및 개발 중 경고를 포함합니다. 식별 할 수있는 버그에 대한 버그를 조사하겠습니다. 결국 모두 적절한 대형 버킷 플래그로 마이그레이션하거나 Clang에서 제거해야합니다.
이것이 Clang의 경고 상황을 분명히하고 사용 또는 회사 사용에 대한 경고 세트를 선택하려는 사람들에게 통찰력을 제공하기를 바랍니다.