컴파일러 경고를 항상 활성화해야 하는 이유는 무엇입니까?
C 및 C++ 프로그램을 컴파일할 때 "항상 컴파일러 경고를 활성화해야 한다"는 말을 자주 듣습니다.왜 이것이 필요한가?그걸 어떻게 하는 거죠?
경고를 오류로 취급해야 한다는 말도 가끔 듣습니다.그럴까?그걸 어떻게 하는 거죠?
경고를 활성화해야 하는 이유는 무엇입니까?
C 컴파일러와 C++ 컴파일러는 디폴트로 다음과 같은 일반적인 프로그래머 오류를 보고하는 데 서투르기로 악명이 높습니다.
- 변수 초기화를 잊어버리다
- 잊다
return
함수의 값 - 의 논거
printf
그리고.scanf
형식 문자열과 일치하지 않는 패밀리 - 함수는 사전에 선언되지 않고 사용됩니다(C만 해당).
이러한 기능은 보통 디폴트로는 검출 및 보고할 수 없습니다.이 기능은 컴파일러 옵션을 통해 명시적으로 요구되어야 합니다.
경고를 활성화하려면 어떻게 해야 합니까?
이것은, 사용의 컴파일러에 따라 다릅니다.
Microsoft C 및 C++ 컴파일러는 다음과 같은 스위치를 인식합니다./W1
,/W2
,/W3
,/W4
그리고./Wall
. 적어도 사용/W3
./W4
그리고./Wall
에서는 시스템 헤더 파일에 대해 가짜 경고가 발생할 수 있지만 프로젝트가 이러한 옵션 중 하나를 사용하여 깔끔하게 컴파일될 경우 작업을 수행하십시오.이러한 옵션은 서로 배타적입니다.
다른 컴파일러의 대부분은 , 및 등의 옵션을 이해하고 있습니다.-Wall
필수적이며 나머지는 모두 권장됩니다(이름에도 불구하고,-Wall
는 가장 중요한 경고만 유효하게 하고 모든 경고는 유효하게 하지 않습니다).이러한 옵션은 개별적으로 사용하거나 모두 함께 사용할 수 있습니다.
IDE 에서는, 유저 인터페이스로부터 이러한 기능을 유효하게 하는 방법이 있습니다.
경고를 오류로 취급해야 하는 이유는 무엇입니까?이건 경고일 뿐이야!
컴파일러 경고는 코드에 심각한 문제가 있을 수 있음을 나타냅니다.위의 문제는 거의 항상 치명적입니다.다른 문제는 치명적일 수도 있고 그렇지 않을 수도 있지만 잘못된 알람으로 판명된 경우에도 컴파일은 실패합니다.각 경고를 조사하고 근본 원인을 찾아 해결합니다.잘못된 경보가 발생할 경우 이에 대처하십시오. 즉, 경고가 더 이상 트리거되지 않도록 다른 언어 기능을 사용하거나 구성을 사용하십시오.이것이 매우 어려운 것으로 판명되었을 경우는, 케이스 바이 케이스로 특정의 경고를 무효로 합니다.
모든 것이 거짓 경보인 경우에도 경고로 남겨두면 안 됩니다.방출된 총 경고 수가 7개 미만인 매우 작은 프로젝트에는 문제가 없을 수 있습니다.그 이상, 그리고 새로운 경고는 오래된 경고의 홍수 속에서 길을 잃기 쉽습니다.허락하지 마세요.모든 프로젝트를 깔끔하게 컴파일할 수 있도록 합니다.
이는 프로그램 개발에 적용됩니다.프로젝트를 소스 형식으로 세상에 릴리스하는 경우 릴리스된 빌드 스크립트에서 제공하거나 이와 동등한 항목을 제공하지 않는 것이 좋습니다.다른 버전의 컴파일러 또는 다른 컴파일러를 사용하여 프로젝트를 빌드하려고 할 수 있습니다.이 경우 다른 경고 세트가 활성화되어 있을 수 있습니다.당신은 그들의 구축이 성공하기를 원할지도 모른다.경고 메시지를 보는 사람들이 버그 보고서 또는 패치를 보낼 수 있도록 경고를 활성화하는 것이 좋습니다.
경고를 오류로 취급하려면 어떻게 해야 합니까?
이 작업은 컴파일러 스위치로 다시 수행합니다. /WX
Microsoft 용으로, 그 외의 대부분의 경우,-Werror
어느 경우든 경고가 발생하면 컴파일은 실패합니다.
이 정도면 됐나요?
아마 아닐 거예요!최적화 레벨을 올릴수록 컴파일러는 코드를 더욱 자세히 조사하기 시작합니다.이렇게 면밀한 조사를 실시하면, 보다 많은 에러가 밝혀질 가능성이 있습니다.따라서 경고 스위치 자체에 만족하지 말고 최적화를 활성화한 상태로 컴파일할 때 항상 경고 스위치를 사용하십시오(-O2
또는-O3
, 또는/O2
MSVC 를 사용하고 있는 경우).
C는 HLL로 볼 때 다소 낮은 수준의 언어입니다.C++는 C보다 상당히 높은 수준의 언어인 것처럼 보일 수 있지만 여전히 많은 특성을 공유하고 있습니다.그 특징 중 하나는 언어는 프로그래머, 특히 자신이 무엇을 하고 있는지 알고 있는 프로그래머에 의해 설계되었다는 것입니다.
(이 답변의 나머지 부분에서는 C에 초점을 맞춥니다.제가 말하는 것의 대부분은 C++에도 해당되지만, 아마도 그렇게 강하지는 않을 것입니다.비록 Bjarne Strostrup이 말했듯이, "C는 자신의 발에 총을 쏘는 것을 쉽게 만든다; C++는 더 어렵게 만들지만, 그렇게 하면 다리 전체가 날아가 버린다."
자신이 무엇을 하고 있는지, 정말로 무엇을 하고 있는지를 알고 있는 경우, 「규칙을 어길 필요가 있다」라고 하는 경우가 있습니다.하지만 대부분의 경우, 우리 대부분은 선의의 규칙이 우리 모두를 곤경에서 벗어나게 하고, 그 규칙들을 항상 어기는 것은 나쁜 생각이라는 것에 동의할 것이다.
그러나 C와 C++에서는 "나쁜 생각"이지만 공식적으로는 "규칙에 위배되지 않는" 많은 일을 할 수 있습니다.때로는 나쁜 생각일 수도 있고(그러나 다른 때는 방어할 수도 있음), 때로는 거의 항상 나쁜 생각일 수도 있습니다.그러나 전통적으로 이러한 경고는 하지 않았습니다.왜냐하면 프로그래머는 자신이 무엇을 하고 있는지 알고 있기 때문에 정당한 이유 없이 이러한 일을 할 수 없고 불필요한 경고에 짜증이 나기 때문입니다.
하지만 물론 모든 프로그래머가 실제로 자신들이 무엇을 하고 있는지 알고 있는 것은 아닙니다.특히 모든 C프로그래머는 (아무리 경험이 있어도) 초보자 C프로그래머가 되는 단계를 거칩니다.그리고 경험이 많은 C 프로그래머들도 부주의하고 실수를 할 수 있습니다.
마지막으로, 경험은 프로그래머들이 실수를 할 뿐만 아니라 이러한 실수들이 실질적이고 심각한 결과를 가져올 수 있다는 것을 보여주었다.만약 당신이 실수를 하고 컴파일러가 당신에게 경고하지 않는다면, 그리고 어떻게 해서든 그 프로그램이 바로 크래시되거나 그로 인해 분명히 잘못된 행동을 하지 않는다면, 그 실수는 그곳에 숨어있을 수 있습니다. 때로는 몇 년 동안 숨겨져 있다가 큰 문제를 일으킬 때까지요.
결국 대부분의 경우 경고는 좋은 생각인 것으로 드러났습니다.경험이 풍부한 프로그래머도 (특히 경험이 풍부한 프로그래머가 그것을 학습했다)는 것을 알고 있습니다.결국 경고는 해가 되기보다는 득이 되는 경향이 있습니다.왜냐하면 당신이 고의로 무언가를 잘못하고 그 경고가 성가신 일이 될 때마다, 당신은 아마 실수로 실수를 한 적이 적어도 10번은 있을 것이고, 그 경고는 당신을 더 이상의 문제로부터 구해주기 때문이다.또한 대부분의 경고는 "잘못된" 작업을 수행하고자 할 때 비활성화하거나 해결할 수 있습니다.
(이러한 '실수'의 전형적인 예가 테스트입니다.if(a = b)
대부분의 경우 이는 정말 실수이기 때문에 요즘 대부분의 컴파일러가 경고하고 있습니다.디폴트로 경고하는 것도 있습니다.하지만 만약 둘 다 정말 임무를 부여하고 싶다면b
로.a
결과를 테스트하려면 다음 명령을 입력하여 경고를 비활성화할 수 있습니다.if((a = b))
.)
두 번째 질문은 왜 컴파일러에 경고를 오류로 처리하도록 요청하느냐는 것입니다.인간의 본성 때문인 것 같아요. 특히, "아, 그건 경고일 뿐이지, 그건 중요하지 않아요. 나중에 치울게요."라고 말하는 아주 쉬운 반응입니다.그러나 만약 당신이 지연자라면(나는 당신을 모르지만, 나는 세계적인 지연자) 기본적으로 필요한 정리를 영원히 미루기 쉽다.그리고 만약 당신이 경고를 무시하는 습관을 들이게 된다면, 당신이 알고 있는 중요한 경고 메시지를 알아차리지 못하고 거기에 놓치는 것은 점점 더 쉬워진다.거침없이 무시하다.
따라서 컴파일러에게 경고를 오류로 처리하도록 요구하는 것은 인간의 결함을 회피하기 위해 스스로를 속일 수 있는 작은 속임수입니다. 그렇지 않으면 프로그램이 컴파일되지 않을 수 있기 때문입니다.
개인적으로 경고를 오류처럼 취급하는 것을 고집하지 않습니다.솔직히 말하면, 「개인」프로그래밍에서는, 그 옵션을 유효하게 하고 싶지 않다고 말할 수 있습니다.하지만 스타일 가이드(제가 작성한)에서 사용을 권장하는 회사에서는 이 옵션을 사용할 수 있습니다.대부분의 전문 프로그래머들은 경고를 C의 오류로 취급하지 않는 가게가 무책임하게 행동하는 것은 일반적으로 받아들여지고 있는 업계의 베스트 프랙티스를 따르지 않는다고 생각합니다.
경고는 가장 숙련된 C++ 개발자가 응용 프로그램에 적용할 수 있는 최선의 조언으로 구성됩니다.그것들은 주변에 보관할 가치가 있다.
C++는 튜링의 완전한 언어이기 때문에 컴파일러가 단순히 당신이 무엇을 하고 있는지 알고 있다고 믿어야 하는 경우가 많습니다.다만, 컴파일러에 의해서, 당신이 쓴 것을 쓸 의도가 없었던 것을 알 수 있는 경우가 많이 있습니다.전형적인 예로는 인수와 일치하지 않는 printf() 코드 또는 printf에 전달된 std:: 문자열이 있습니다(나에게는 그런 일이 일어나지 않습니다!).이 경우 작성한 코드는 오류가 아닙니다.이것은 컴파일러가 조작할 수 있는 유효한 해석을 가진 유효한 C++ 표현입니다.하지만 컴파일러는 당신이 단순히 간과했다는 강한 예감이 있습니다. 이는 현대의 컴파일러가 쉽게 발견할 수 있는 것입니다.경고입니다.C++의 엄격한 규칙을 자유자재로 사용하여 컴파일러가 간과하고 있는 것은 명백합니다.
경고를 끄거나 무시하는 것은 당신보다 숙련된 사람들의 무료 조언을 무시하는 것과 같습니다.자만심에 대한 교훈입니다태양에 너무 가까이 날아가 날개가 녹거나기억에러가 발생했을 때 끝납니다둘 중 어느 날이라도 하늘에서 떨어지는 건 감수할 거야!
"경고를 오류로 취급"은 이 철학의 극단적인 버전입니다.여기서의 아이디어는 컴파일러가 제공하는 모든 경고를 해결한다는 것입니다. 즉, 모든 무료 조언에 귀를 기울이고 그에 따라 행동하는 것입니다.이것이 당신에게 좋은 개발 모델인지 아닌지는 팀과 어떤 종류의 제품을 만들고 있는지에 따라 달라집니다.그것은 수도승이 취할 수 있는 금욕적인 접근법이다.어떤 사람들에게는 잘 작동한다.다른 사람들에게는 그것이 타당하지 않다.
많은 어플리케이션에서는 경고를 오류로 취급하지 않습니다.이러한 특정 애플리케이션을 다양한 연령대의 컴파일러를 사용하여 여러 플랫폼에서 컴파일해야 하기 때문에 이 작업을 수행합니다.때로는 다른 플랫폼에서 경고로 바뀌지 않고는 한 쪽의 경고를 수정하는 것이 사실상 불가능할 수 있습니다.그래서 우리는 단지 조심할 뿐이다.우리는 경고를 존중하지만 경고를 위해 허리를 굽히지 않는다.
경고를 처리하면 더 나은 코드가 생성될 뿐만 아니라 더 나은 프로그래머가 됩니다.경고는 오늘날 당신에게 하찮게 보일 수 있는 것들에 대해 말해줄 것이지만, 언젠가 그 나쁜 습관이 되살아나 당신을 물게 될 것이다.
올바른 유형을 사용하여 해당 값을 반환하고 해당 반환 값을 평가하십시오.시간을 들여 "이 문맥에서 이것이 정말 올바른 유형입니까?" "이 문맥을 반환해야 합니까?"를 검토합니다.그리고 중요한 것은 "이 코드가 앞으로 10년 동안 휴대할 수 있게 될까요?"입니다.
애초에 경고 없는 코드를 작성하는 습관을 들이세요.
수정되지 않은 경고는 조만간 코드에 오류가 발생할 수 있습니다.
예를 들어 세그멘테이션 장애를 디버깅하려면 프로그래머가 장애의 근본(원인)을 추적해야 합니다.이러한 장애는 일반적으로 최종적으로 세그멘테이션 장애를 일으킨 라인보다 코드의 이전 위치에 있습니다.
일반적인 원인은 컴파일러가 경고한 행이며, 세그먼트화의 원인이 된 행은 에러를 발생시킨 행입니다.
경고를 수정하면 문제가 해결됩니다.클래식!
상기의 데먼스트레이션...다음 코드를 고려합니다.
#include <stdio.h>
int main(void) {
char* str = "Hello, World!!";
int idx;
// Colossal amount of code here, irrelevant to 'idx'
printf("%c\n", str[idx]);
return 0;
}
GCC에 전달된 "Wextra" 플래그를 사용하여 컴파일하면 다음과 같은 결과를 얻을 수 있습니다.
main.c: In function 'main':
main.c:9:21: warning: 'idx' is used uninitialized in this function [-Wuninitialized]
9 | printf("%c\n", str[idx]);
| ^
어쨌든 코드를 무시하고 실행할 수 있는...그리고 IP 에피쿠로스 교수가 말하듯이 "대형" 분할 오류를 목격할 수 있습니다.
세그멘테이션 장애
실제 시나리오에서 이를 디버깅하려면 분할 장애를 일으킨 라인부터 시작하여 무엇이 원인인지 추적합니다.그들은 이 사건에서 무슨 일이 일어났는지 찾아봐야 할 것이다.i
그리고.str
저기에 있는 엄청난 양의 암호 안에...
어느 날, 그들은 자신들이 그 사실을 알게 되는 상황에 처지가idx
는 초기화되지 않은 상태로 사용되기 때문에 가비지 값이 있습니다.그 결과, 스트링(웨이)이 그 경계를 넘어 인덱싱되어 세그먼트화 장해가 발생합니다.
만약 그들이 경고를 무시하지 않았다면, 그들은 그 벌레를 즉시 발견했을 거예요!
다른 답변들은 훌륭하고 나는 그들이 말한 것을 반복하고 싶지 않다.
"경고를 활성화하는 이유"의 또 다른 측면은 제대로 다루지 않은 것입니다.그것은 코드 유지보수에 큰 도움이 됩니다.당신이 상당한 크기의 프로그램을 작성하면, 한번에 모든 것을 머릿속에 담아두는 것은 불가능해진다.일반적으로 적극적으로 쓰고 생각하는 기능이 하나 또는 세 개 있고, 화면에 참조할 수 있는 파일이 하나 또는 세 개 있지만, 프로그램의 대부분은 백그라운드 어딘가에 존재하기 때문에 계속 작동한다는 것을 믿어야 합니다.
경고를 하고, 가능한 한 활기차고, 얼굴을 마주보는 것은, 만약 여러분이 바꿀 수 있는 것이 여러분이 볼 수 없는 것에 문제를 일으킨다면 여러분에게 경고를 주는 데 도움이 됩니다.
예를 들어 Clang warning을 예로 들겠습니다.-Wswitch-enum
이 명령어는 열거형 스위치를 사용하여 가능한 열거형 값 중 하나를 놓치면 경고를 트리거합니다.이는 거의 실수하지 않을 것으로 생각됩니다.스위치문을 쓸 때 적어도 열거값 목록을 확인했을 것입니다.스위치 옵션을 생성한 IDE가 있을 수도 있으므로 사용자가 실수할 여지가 없습니다.
이 경고는 6개월 후에 열거에 다른 가능한 항목을 추가하면 실제로 나타납니다.다시 말씀드리지만, 문제의 코드를 생각하고 있다면 아마 괜찮을 겁니다.그러나 이 열거형이 여러 목적으로 사용되며 추가 옵션이 필요한 경우 6개월 동안 사용하지 않은 파일의 스위치를 업데이트하는 것을 잊기 쉽습니다.
경고는 자동화된 테스트 케이스와 같은 방법으로 생각할 수 있습니다.이러한 경고는 코드를 처음 작성할 때 필요한 작업을 수행하는 데 도움이 됩니다.또한 경고는 코드를 작성하면서 필요한 작업을 계속 수행하도록 하는 데에도 도움이 됩니다.다른 점은 테스트 케이스는 코드의 요건에 매우 좁게 동작하며, 경고는 거의 모든 코드에 대해 합리적인 기준에 따라 광범위하게 동작하며 컴파일러를 만드는 보핀에 의해 매우 관대하게 공급된다는 것입니다.
경고를 오류로 취급하는 것은 자기 훈련의 수단일 뿐입니다.반짝 빛나는 새로운 기능을 테스트하기 위한 프로그램을 컴파일하고 있었습니다만, 허술한 부분을 수정하지 않으면 할 수 없습니다.추가 정보는 제공되지 않습니다.우선 순위를 명확하게 설정할 뿐입니다.
기존 코드의 문제를 해결할 때까지 새 코드 추가 안 함
중요한 것은 도구가 아니라 마음가짐입니다.컴파일러의 Diagnostics 출력은 도구입니다.MISRA C(임베디드 C의 경우)도 다른 도구입니다.어떤 것을 사용하는지는 중요하지 않지만 컴파일러 경고는 가장 쉽게 얻을 수 있는 도구이며(설정할 수 있는 플래그는 1개뿐) 신호 대 잡음비가 매우 높습니다.그래서 안 쓸 이유가 없어요.
어떤 도구도 완벽하지 않다.쓰시면const float pi = 3.14;
대부분의 툴은 ①을 잘못 정의했다고 알려주지 않기 때문에 향후 문제가 발생할 수 있습니다.대부분의 툴은 에 대해 눈썹 하나 까딱하지 않습니다.if(tmp < 42)
비록 변수에 의미 없는 이름을 붙이고 매직넘버를 사용하는 것이 대규모 프로젝트에서는 재앙을 불러올 수 있는 방법이라는 것이 널리 알려져 있다.작성한 「퀵 테스트」코드는, 단지 테스트일 뿐입니다.다른 태스크로 넘어가기 전에, 그 단점을 확인할 필요가 있습니다.이 코드를 그대로 두면 새로운 기능을 추가하는 데 2개월이 걸린 후 디버깅이 상당히 어려워집니다.
올바른 마음가짐이 생겼을 때 사용하는 것은 의미가 없습니다.-Werror
경고를 경고로 표시하면 시작하려는 디버깅세션을 실행하는 것이 적절한지, 아니면 중단하고 경고를 먼저 수정하는 것이 적절한지 충분한 정보를 바탕으로 판단할 수 있습니다.
레거시 임베디드 C코드로 작업하는 사용자로서 컴파일러 경고를 활성화하면 많은 약점과 수정 제안 시 조사해야 할 영역이 나타납니다.GCC에서는 사용 및 심지어 사용이 필수적입니다.모든 위험에 대해 설명하지는 않겠지만 코드 문제를 보여주는 데 도움이 되는 몇 가지 사례를 제시하겠습니다.
남겨진 변수
이는 미완료 작업 및 문제가 될 수 있는 전달 변수를 모두 사용하지 않을 수 있는 영역을 쉽게 가리킬 수 있습니다.이를 트리거할 수 있는 간단한 함수를 살펴보겠습니다.
int foo(int a, int b)
{
int c = 0;
if (a > 0)
{
return a;
}
return 0;
}
컴파일 할 필요 없이-Wall
또는-Wextra
문제는 반환되지 않습니다. -Wall
그렇다고는 해도c
는 사용되지 않습니다.
foo.c: 함수 'foo'에서:
foo.c:9:20: warning: 미사용 변수 'c' [-Wunused-variable]
-Wextra
또한 파라미터가b
는 아무것도 하지 않습니다.
foo.c: 함수 'foo'에서:
foo.c:9:20: warning: 미사용 변수 'c' [-Wunused-variable]
foo.c:7:20: 경고: 사용되지 않은 매개 변수 'b' [-Wunused-parameter] int foo(int a, int b)
전역 변수 섀도우링
이건 좀 딱딱해서 그때까지 나타나지 않았어요.-Wshadow
사용되었습니다.위의 예를 수정하여 추가만 하겠습니다만, 로컬과 같은 이름의 글로벌이 존재하기 때문에 양쪽을 사용하려고 할 때 많은 혼란이 발생합니다.
int c = 7;
int foo(int a, int b)
{
int c = a + b;
return c;
}
언제-Wshadow
켜져 있어서 이 문제를 쉽게 발견할 수 있습니다.
foo.c:11:9: warning: 'c' 선언이 글로벌 선언을 가리킵니다 [-Whadow]
foo.c:1:5: 주의: 음영 선언이 여기에 있습니다.
형식 문자열
이것은 GCC에 추가 플래그를 필요로 하지 않지만, 지금까지도 문제의 원인이 되고 있습니다.데이터를 인쇄하려고 하지만 포맷 오류가 있는 단순한 기능은 다음과 같습니다.
void foo(const char * str)
{
printf("str = %d\n", str);
}
포맷 플래그가 잘못되었기 때문에 문자열은 인쇄되지 않습니다.GCC는 이 플래그가 원하는 것이 아닌 것 같다고 기쁘게 말합니다.
foo.c: 함수 'foo'에서:
foo.c:10:12: 경고: 형식 '%d'은(는) 형식 'int'의 인수를 예상하지만 인수 2는 형식 'const char *'[-Wformat=]을(를) 가집니다.
이것들은 컴파일러가 당신을 위해 다시 확인할 수 있는 많은 것 중 세 가지에 불과합니다.다른 사람들이 지적한 초기화되지 않은 변수를 사용하는 것과 같은 많은 것들이 있습니다.
컴파일러 경고는 당신의 친구입니다.
저는 레거시 Fortran 77 시스템에서 일하고 있습니다.컴파일러는 중요한 것을 알려 줍니다.서브루틴 콜에서의 인수 데이터 타입 불일치, 사용되지 않는 변수 또는 서브루틴 인수가 있는 경우 값이 변수로 설정되기 전에 로컬 변수를 사용합니다.이것들은 거의 항상 에러입니다.
내 코드가 깔끔하게 컴파일되면 97%가 작동합니다.저와 함께 일하는 다른 사람은 모든 경고를 해제한 채 컴파일하고 디버거에 몇 시간 또는 며칠을 보낸 다음 제게 도움을 요청해요.난 그냥 경고들이 켜진 상태로 코드를 컴파일해서 뭘 고칠지 말해주는거야.
저는 전자 테스트 장비를 제조하는 대기업(Fortune 50)에서 일한 적이 있습니다.
저희 그룹의 핵심 제품은 MFC 프로그램이었는데, 수년 동안 문자 그대로 수백 개의 경고를 발생시켰습니다.거의 모든 경우에서 무시당했죠
버그가 발생할 때 이건 빌어먹을 악몽이야.
그 후, 저는 운 좋게 새로운 스타트업의 첫 개발자로 채용되었습니다.
컴파일러 경고 수준이 상당히 시끄럽도록 설정된 상태에서 모든 빌드에 대해 '경고 없음' 정책을 권장했습니다.
디버깅 레벨의 로그 문과 함께 개발자가 정상이라고 확신하는 코드에 대해 #pragma warning - push/disable/pop을 사용하는 것이 관례였습니다.
이 연습은 우리에게 효과가 있었다.
이것은 C에 대한 구체적인 답변이며, 왜 이것이 C에 가장 중요한가 하는 것입니다.
#include <stdio.h>
int main()
{
FILE *fp = "some string";
}
이 코드는 경고와 함께 컴파일됩니다.지구상의 다른 거의 모든 언어(어셈블리 언어 제외)의 오류는 C의 경고입니다.C의 경고는 거의 항상 위장 오류입니다.경고는 억제가 아니라 수정해야 합니다.
GCC 에서는, 이것을 다음과 같이 실시합니다.gcc -Wall -Werror
.
이는 또한 일부 Microsoft 비보안 API 경고에 대한 위험성이 높은 이유이기도 합니다.C를 프로그래밍하는 대부분의 사람들은 경고를 오류로 취급하는 방법을 어렵게 배웠습니다.이러한 문제는 같은 종류의 것이 아니라 포터블 이외의 수정을 원하는 것으로 나타났습니다.
컴파일러가 코드 문제를 알려주는 경우가 많기 때문에 항상 컴파일러 경고를 활성화해야 합니다.이를 수행하려면 컴파일러에 전달합니다-Wextra
.
경고는 일반적으로 코드에 문제가 있음을 나타내므로 일반적으로 경고는 오류로 취급해야 합니다.그러나 이러한 오류는 무시하기 쉽습니다.따라서 이러한 오류를 오류로 처리하면 빌드가 실패하므로 오류를 무시할 수 없습니다.경고를 오류로 처리하려면 컴파일러에 전달합니다.
경고는 발생을 기다리는 오류입니다.따라서 컴파일러 경고를 활성화하고 코드를 정리하여 경고를 삭제해야 합니다.
경고를 무시한다는 것은 앞으로 다른 사람에게 문제를 일으킬 수 있을 뿐만 아니라 중요한 컴파일메시지를 알아차리지 못하는 엉성한 코드를 남겼다는 것을 의미합니다.
컴파일러의 출력이 많을수록 눈치채거나 귀찮은 일이 적어집니다.깨끗할수록 좋다.그것은 또한 당신이 무엇을 하고 있는지 알고 있다는 것을 의미합니다.경고는 매우 전문적이지 않고 부주의하며 위험합니다.
C++의 컴파일러 경고는 어떤 이유로 매우 유용합니다.
조작의 최종 결과에 영향을 줄 수 있는 실수가 있었을 가능성이 있는 장소를 표시할 수 있습니다.예를 들어 변수를 초기화하지 않았거나 "==" 대신 "="를 사용하는 경우(예만 있음)
또, 코드가 C++ 의 표준에 준거하고 있지 않은 장소도 표시할 수 있습니다.예를 들어 코드가 실제 표준에 적합하면 코드를 다른 플랫폼으로 이동하기가 쉬워지기 때문에 유용합니다.
일반적으로 경고는 알고리즘의 결과에 영향을 미치거나 사용자가 프로그램을 사용할 때 발생하는 오류를 방지할 수 있는 코드에 오류가 있는 위치를 보여 주는 데 매우 유용합니다.
C++ 컴파일러가 명백히 정의되지 않은 동작을 일으키는 컴파일 코드를 받아들이는 것은 컴파일러의 주요 결함입니다.이 문제를 해결하지 않는 이유는 이 문제를 해결하면 사용 가능한 빌드가 파손될 수 있기 때문입니다.
대부분의 경고는 빌드를 완료할 수 없는 치명적인 오류입니다.오류를 표시하고 빌드만 하는 기본 설정은 잘못되었으며 경고를 오류로 간주하고 일부 경고를 남기지 않으면 프로그램이 크래시되어 임의 작업을 수행할 수 있습니다.
경고를 오류로 처리하는 데 문제가 있는 것은 다음 한 가지뿐입니다.다른 소스(예를 들어 Microsoft 라이브러리, 오픈 소스 프로젝트)에서 가져온 코드를 사용할 경우 해당 코드가 제대로 작동하지 않아 코드를 컴파일하면 많은 경고가 발생합니다.
경고나 오류가 발생하지 않도록 항상 코드를 작성하고 불필요한 노이즈가 발생하지 않도록 컴파일할 때까지 정리합니다.내가 처리해야 할 쓰레기는 나를 놀라게 하고, 내가 큰 프로젝트를 만들어야 할 때, 그리고 컴파일이 어떤 파일을 처리했는지 알리는 경고의 연속을 보면 나는 깜짝 놀라게 된다.
또, 소프트웨어의 실제 라이프 타임 코스트의 대부분은 처음에 작성했을 때의 코드가 아니고, 유지 보수에 의한 것이 많기 때문에, 코드를 기록합니다.하지만, 그것은 다른 이야기입니다.
일부 경고는 코드의 의미 오류 또는 UB(예:;
끝나고if()
, 미사용 변수, 로컬에 의해 마스크된 글로벌 변수 또는 서명된 변수와 서명되지 않은 변수의 비교.많은 경고는 컴파일러의 정적 코드아나라이저 또는 컴파일 시 검출 가능한 ISO 표준 위반과 관련되어 있습니다.이러한 경고는 "진단"이 필요합니다.이러한 발생은 하나의 특정 경우에 합법적일 수 있지만, 대부분의 경우 설계상의 문제로 인해 발생할 수 있다.
일부 컴파일러(GCC 등)에는 "오류로서의 경고" 모드를 활성화하기 위한 명령줄 옵션이 있습니다.그것은 비록 잔인하지만 초보 코더를 교육하는 좋은 도구이다.
컴파일러에 따라서는 다음과 같은 일반적인 프로그래밍 오류를 보고할 수 없기 때문에 반드시 컴파일러 경고를 활성화해야 합니다.
- 변수를 잊어버린 경우 초기화
- 함수의 누락 값을 반환합니다.
- printf 및 scanf 패밀리의 단순 인수가 형식 문자열과 일치하지 않습니다.
- 함수는 C에서만 발생하지만 사전에 선언되지 않고 사용됩니다.
이러한 함수는 검출 및 보고가 가능하기 때문에 보통 디폴트로는 검출되지 않습니다.따라서 이 기능은 컴파일러 옵션을 통해 명시적으로 요구되어야 합니다.
안심하세요.필요 없어요.-Wall과 -Werror는 코드 리팩터링 마니아가 직접 설계한 것입니다.컴파일러 개발자는 컴파일러나 사용자 측의 언어 업데이트 후 기존 빌드가 깨지지 않도록 하기 위해 개발했습니다.이 기능은 빌드를 파괴할지 말지 결정하는 것이 전부입니다.
그것을 사용하는지 안 사용하는지는 전적으로 당신의 취향에 달려 있습니다.실수를 고치는 데 도움이 되기 때문에 항상 쓰고 있어요.
언급URL : https://stackoverflow.com/questions/57842756/why-should-i-always-enable-compiler-warnings
'programing' 카테고리의 다른 글
PHP "pretty print" json_encode (0) | 2022.11.21 |
---|---|
C 논블로킹 키보드 입력 (0) | 2022.11.02 |
Java에서 표준 입력에서 정수 값을 읽는 방법 (0) | 2022.11.02 |
MySQL에서 영숫자만 포함하는 행만 선택 (0) | 2022.11.02 |
배열에 TypeScript 문자열이 포함되어 있는지 확인하려면 어떻게 해야 합니까? (0) | 2022.11.02 |