setting -Wall
과 setting 외에도 -std=XXX
C에서 사용하기에 실제로 유용하지만 덜 알려진 컴파일러 플래그는 무엇입니까?
특히 추가 경고에 관심이 있으며 우발적 인 유형 불일치를 최소화하기 위해 경고를 오류로 전환하는 경우가 있습니다.
gcc -c [flags-go-here] -o myprog.o myprog.c
C 프로그램을 컴파일 (링크가 아님)하기 위해 실행 중 입니다.
setting -Wall
과 setting 외에도 -std=XXX
C에서 사용하기에 실제로 유용하지만 덜 알려진 컴파일러 플래그는 무엇입니까?
특히 추가 경고에 관심이 있으며 우발적 인 유형 불일치를 최소화하기 위해 경고를 오류로 전환하는 경우가 있습니다.
gcc -c [flags-go-here] -o myprog.o myprog.c
C 프로그램을 컴파일 (링크가 아님)하기 위해 실행 중 입니다.
답변:
몇 가지 -f
코드 생성 옵션이 흥미 롭습니다.
이 -ftrapv
함수는 프로그램이 부호있는 정수 오버 플로우 (공식적으로 C에서 "정의되지 않은 동작")에서 중단되도록합니다.
-fverbose-asm
-S
어셈블리 출력을 검사하기 위해 컴파일 할 때 유용합니다 . 유익한 주석이 추가됩니다.
-finstrument-functions
모든 기능 시작 및 종료 지점에서 사용자 제공 프로파일 링 함수를 호출하는 코드를 추가합니다.
-ftrapv
여기를 살펴보십시오. stackoverflow.com/questions/20851061/… .. 긴 버그가 수정되기를 기다리는 것 같습니다.
여기 내 것이 있습니다 :
-Wextra
, -Wall
: 필수.-Wfloat-equal
: 일반적으로 부동 소수점 숫자가 동일한 지 테스트하는 것이 좋지 않기 때문에 유용합니다.-Wundef
: #if
지시문 에서 초기화되지 않은 식별자가 평가되면 경고합니다 .-Wshadow
: 지역 변수가 다른 지역 변수, 매개 변수 또는 전역 변수를 가리거나 내장 함수가 그림자 될 때마다 경고합니다.-Wpointer-arith
: 함수 크기 또는 크기에 따라 달라지는 경우 경고합니다 void
.-Wcast-align
: 대상의 필요한 정렬이 증가하도록 포인터를 캐스트 할 때마다 경고합니다. 예를 들어 정수가 2 바이트 또는 4 바이트 경계에서만 액세스 할 수있는 컴퓨터에서 a char *
가 캐스팅 된 경우 경고합니다 int *
.-Wstrict-prototypes
: 인수 유형을 지정하지 않고 함수가 선언되거나 정의되면 경고합니다.-Wstrict-overflow=5
: 부호있는 오버플로가 발생하지 않는다는 가정에 따라 컴파일러가 최적화되는 경우에 대해 경고합니다. (값 5가 너무 엄격 할 수 있습니다. 매뉴얼 페이지를 참조하십시오.)-Wwrite-strings
: 문자열 상수에 const char[
길이를]
지정하여 주소의 주소를 비 const char *
포인터에 복사하면 경고가 표시됩니다.-Waggregate-return
: 구조체 나 공용체를 반환하는 함수가 정의되거나 호출되면 경고합니다.-Wcast-qual
: 대상 유형 * 에서 유형 한정자를 제거하기 위해 포인터를 캐스트 할 때마다 경고 합니다.-Wswitch-default
: switch
문장에 default
대소 문자 가 없을 때마다 경고합니다 * .-Wswitch-enum
: switch
명령문에 열거 된 유형의 색인이 있고 case
해당 열거의 명명 된 코드 중 하나 이상에 대해 a가 없을 때 경고합니다 * .-Wconversion
: 값을 변경할 수있는 암시 적 변환에 대해 경고합니다 * .-Wunreachable-code
: 컴파일러에서 해당 코드가 실행되지 않음을 감지하면 경고합니다 * .* 표시가있는 사람들은 때때로 너무 많은 가짜 경고를하므로 필요에 따라 사용합니다.
-Wformat=2
: printf / scanf 기능에 대한 추가 형식 확인.
-Wall
않습니까?
-Wwrite-strings
그것을 너무 싫어하기 때문에 명시 적으로 꺼야한다는 것을 알고 있습니다.
-Wwrite-strings
구체적으로는의 일부가 아닌 말한다 -Wall
: gcc.gnu.org/onlinedocs/gcc/... . 어쩌면 설정에서 다른 것이 그 플래그를 설정하고 있습니까? 아니면 C ++를 컴파일하고 있습니까?
항상 사용 -O
이상 ( -O1
, -O2
, -Os
, 등). 기본 최적화 수준에서 gcc는 컴파일 속도를 결정하고 단위 변수와 같은 것에 대해 경고하기에 충분한 분석을 수행하지 않습니다.
-Werror
컴파일을 중지하지 않는 경고는 무시되는 경향이 있으므로 정책을 고려하십시오 .
-Wall
오류 일 가능성이 높은 경고를 거의 설정합니다.
포함 된 경고는 -Wextra
일반적인 합법적 인 코드를 표시하는 경향이 있습니다. 코드 검토에 유용 할 수 있지만 (보풀이 많은 프로그램은 더 많은 함정이 더 유연하다는 것을 알지만) 정상적인 개발을 위해 설정하지는 않습니다.
-Wfloat-equal
프로젝트의 개발자가 부동 소수점에 익숙하지 않은 경우 좋은 아이디어이고 그렇지 않은 경우 나쁜 아이디어입니다.
-Winit-self
유용하다; 에 포함되지 않은 이유가 궁금합니다 -Wuninitialized
.
-Wpointer-arith
와 호환되지 않는 대부분 이식 가능한 코드가있는 경우 유용합니다 -pedantic
.
아무도 이것에 대해 아직 말하지 않은 것에 놀랐습니다. 내가 염려하는 한 가장 유용한 플래그는 -g
디버깅 정보를 실행 파일에 넣어 디버깅하고 소스를 단계별로 실행할 수있는 것입니다. 등 stepi
프로그램의 명령)이 실행하는 것 동안.
-fmudflap -UB를 잡기 위해 모든 위험한 포인터 작업에 런타임 검사를 추가합니다. 이를 통해 프로그램이 버퍼 오버플로를 다시 효과적으로 예방하고 모든 종류의 매달려있는 포인터를 잡을 수 있습니다.
데모는 다음과 같습니다.
$ cat mf.c
int main()
{
int a[10];
a[10]=1; // <-- o noes, line 4
}
$ gcc -fmudflap mf.c -lmudflap
$ ./a.out
*******
mudflap violation 1 (check/write): time=1280862302.170759 ptr=0x7fff96eb3d00 size=44
pc=0x7f3a575503c1 location=`mf.c:4:2 (main)'
/usr/lib/libmudflap.so.0(__mf_check+0x41) [0x7f3a575503c1]
./a.out(main+0x90) [0x400a54]
/lib/libc.so.6(__libc_start_main+0xfd) [0x7f3a571e2c4d]
Nearby object 1: checked region begins 0B into and ends 4B after
mudflap object 0xf9c560: name=`mf.c:3:6 (main) a'
bounds=[0x7fff96eb3d00,0x7fff96eb3d27] size=40 area=stack check=0r/3w liveness=3
alloc time=1280862302.170749 pc=0x7f3a57550cb1
number of nearby objects: 1
-fmudflap
GCC 4.9 이후 더 이상 지원되지 않습니다 warning: switch '-fmudflap' is no longer supported
. AddressSanitizer로 대체되었습니다.
실제로 오류를 감지하는 데 도움이되지는 않지만 거의 언급되지 않은 -masm=intel
옵션은 -S
어셈블리 출력을 훨씬 더 잘 검사하는 데 사용 됩니다.
AT & T 어셈블리 구문으로 인해 머리가 너무 아파요.
내 makefile에는 일반적으로
CFLAGS= -Wall -Wextra -Weffc++ -Os -ggdb
...
g++ $(CFLAGS) -o junk $<
gcc $(CFLAGS) -o $@ $<
rm -f junk
이러한 옵션 중 가장 중요한 것은 이전에 논의되었으므로 아직 지적되지 않은 두 가지 기능을 지적하겠습니다.
내가 그 코드베이스에서 일하고 있어요 비록 요구 사항이 일부 플랫폼 이식성에 대한 일반 C로 여전히 더 괜찮은 C ++ 컴파일러가없는, 내가 (C 컴파일러뿐만 아니라) C ++ 컴파일러와의 "추가"컴파일을한다. 3 가지 이점이 있습니다.
네, 생각을 계속 절망적으로 낙관적 인 낙천적이야 그 확실히 어떤 달 이제 하나 개의 플랫폼이 하나 ++ 폐기 선언, 또는 괜찮은 C ++ 컴파일러를 얻을, 우리는 결국 C로 전환 할 수 있습니다됩니다. 내 마음에, 그것은 불가피하다-유일한 질문은 경영진이 모든 사람을 조랑말로 발행하기 전 또는 후에 발생하는지 여부이다. :-)
-Wstrict-prototypes -Wmissing-prototypes
-Wold-style-definition
프로토 타입 선언에서도 K & R 스타일 함수가 좋은 생각이라고 생각하는 상호 주의자를 다루어야합니다. (저는 그런 사람들을 다뤄야합니다. K & R로 작성된 새 코드를 찾으면 정말 짜증납니다. 수정되지 않은 레거시 K & R 자료를 가지고있는 것이 좋지만 새로운 코드입니다! Grump !!!)
man gcc
매뉴얼에는 좋은 설명이 담긴 흥미로운 깃발이 가득합니다. 그러나 -Wall은 아마도 gcc를 가능한 한 장황하게 만들 것입니다. 더 흥미로운 데이터를 원한다면 valgrind 또는 오류를 확인하기위한 다른 도구를 살펴보십시오.
man gcc | nl
11000 라인 이상을보고합니다. 그것은 악명 높은 bash
맨 페이지 이상입니다 !
-M*
옵션 군.
이를 통해 c 또는 c ++ 소스 파일이 의존해야하는 헤더 파일을 자동으로 알아내는 make 파일을 작성할 수 있습니다. GCC는이 의존성 정보로 make 파일을 생성 한 다음 기본 make 파일에서이를 포함시킵니다.
다음은 c ++ 소스 및 헤더 파일로 가득 찬 디렉토리를 컴파일하고 모든 종속성을 자동으로 알아내는 -MD 및 -MP를 사용하는 매우 일반적인 makefile의 예입니다.
CPPFLAGS += -MD -MP
SRC = $(wildcard *.cpp)
my_executable: $(SRC:%.cpp=%.o)
g++ $(LDFLAGS) -o $@ $^
-include $(SRC:%.cpp=%.d)
보다 자세한 내용을 다루는 블로그 게시물은 다음과 같습니다. http://www.microhowto.info/howto/automatically_generate_makefile_dependencies.html
-Werror
모든 경고를 오류로 취급하고 컴파일을 중지하는가 있습니다 . gcc
매뉴얼 페이지는 컴파일러에 대한 모든 명령 줄 스위치에 대해 설명합니다.
gcc
플래그는 사용자와 다른 사람이 제안 할 수있는 링크마다 다를 수 있습니다. 매뉴얼 페이지가 소프트웨어와 함께 제공되는 이유입니다.
-Wfloat-equal
보낸 사람 : http://mces.blogspot.com/2005/07/char-const-argv.html
내가 좋아하는 다른 새로운 경고 중 하나는 -Wfloat-equal입니다. 평등 조건에서 부동 소수점 숫자를 가질 때마다 경고합니다. 그것은 화려합니다! 모든 컴퓨터 그래픽 또는 (질서 :) 계산 기하학 알고리즘이 프로그래밍 된 경우 두 개의 부동 소수점이 동등성과 일치하지 않는다는 것을 알고 있습니다.
이 스레드가 특정 문제를 해결하기 위해 플래그를 찾고 있다는 것을 알았습니다. 여기에 표시되지 않으므로 게시물에 저를 비웃는 것을 추가 할 것입니다 .
-Wformat=2
플래그
-Wformat
=>printf
및에 대한 호출을scanf
확인하여 제공된 인수에 지정된 형식 문자열에 적합한 유형이 있는지 확인하십시오.
그리고 GCC 매뉴얼에 따르면 실제로 중요한 부분은 다음과 같습니다.
-Wformat
에 포함되어-Wall
있습니다. , 옵션을 체크 형식의 일부 측면을 더 제어를 위해-Wformat-y2k
,-Wno-format-extra-args
,-Wno-format-zero-length
,-Wformat-nonliteral
,-Wformat-security
, 및-Wformat=2
사용할 수 있지만 -Wall.`에 포함되지 않습니다
그래서, 당신은 단지 때문에 -Wall
의미하지 않는다 당신은 모든 것을 가지고있다. ;)
때로는 -s
훨씬 작은 실행 파일에 사용합니다.
-s
Remove all symbol table and relocation information from the executable.
출처 : http://gcc.gnu.org/onlinedocs/gcc/Link-Options.html#Link-Options
strip
바이너리에서 실행해야 합니다. 이런 식으로 디버그 정보가있는 바이너리를 가질 수 있습니다. 나중에 배포하기 위해 제거하십시오.
strip
작동하지만 -s
더 빠르고 쉬울 수는 있지만 달리는 것만 큼 정교하지는 않습니다.strip
이 답변은 약간 주제가 맞지 않을 수 있지만 질문은 나에게서 가치있는 +1이지만
특히 추가 경고에 관심이 있으며 우발적 인 유형 불일치를 최소화하기 위해 경고를 오류로 전환하는 경우가 있습니다.간파해야하는 도구가 모두 명확하지 않을 수있는 오류와 오류 가능성이있다, 부목 이럴 gcc가 또는 그 문제에 대한 모든 다른 컴파일러에 비해 오류를 잡기에 더 나은 방법 일을한다. 그것은 당신의 도구 가슴에 가치있는 도구입니다.
스플린트와 같은 린트 유형의 도구를 통한 정적 검사는 컴파일러 도구 체인의 일부 여야합니다.
추가 경고에 특히 관심이 있습니다.
또한 -Wall
, -W
또는 -Wextra
옵션 ( -W
이전 버전의 gcc 및 최신 버전에서 작동합니다. 최신 버전은 대체 이름을 지원합니다 -Wextra
. 이는 같은 것을 의미하지만 더 설명적임)은 다양한 추가 경고를 가능하게합니다.
일반적으로 더 의심스러운 것들에 대해 더 많은 경고가 가능하지 않습니다. 사용 가능한 옵션 세트는 사용중인 gcc 버전에 따라 다릅니다. 자세한 내용은 문의 man gcc
하거나 관심있는 특정 gcc 버전에 대한 온라인 설명서 를 info gcc
참조하십시오 . 사용중인 특정 표준에 필요한 모든 경고를 표시합니다 ( 또는 )와 같은 다른 옵션 에서 gcc 확장 프로그램 사용에 대해 불평합니다.-pedantic
-std=xxx
-ansi
우발적 인 유형 불일치를 최소화하기 위해 경고를 오류로 전환하는 경우도 있습니다.
-Werror
모든 경고를 오류로 바꿉니다. 그래도 gcc를 사용하면 특정 경고에 대해 선택적으로 그렇게 할 수 있다고 생각하지 않습니다.
-Werror
외부 라이브러리의 헤더 파일이 일부를 트립 할 수 있으므로 프로젝트별로 (특히 사용하는 경우 ) 경고를 선택적으로 선택해야 할 수도 있습니다. ( -pedantic
특히 내 경험상 이런 점에서 도움이되지 않는 경향이 있습니다.)
-Werror=some-warning
.
-Werror=return-type
: gcc에서 함수가 반환되지 않으면 오류를 적용합니다. 그것은이다 /we4716
Visual Studio에서.
-Werror=implicit-function-declaration
: 정의 / 포함되지 않은 기능을 사용할 때 오류를 시행합니다. 그것은이다 /we4013
Visual Studio에서.
-Werror=incompatible-pointer-types
: 포인터 유형이 예상 포인터 유형과 일치하지 않을 때 오류가 발생합니다. 그것은이다 /we4133
Visual Studio에서.
실제로 C 코드를 크로스 플랫폼으로 유지하고 CMake를 사용하고 제공된 cflags를 다음과 같이 CMakeLists.txt에 넣습니다.
if (CMAKE_SYSTEM_NAME MATCHES "Windows")
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} /we4013 /we4133 /we4716")
elseif (CMAKE_SYSTEM_NAME MATCHES "Linux" OR CMAKE_SYSTEM_NAME MATCHES "Darwin")
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Werror=implicit-function-declaration -Werror=incompatible-pointer-types -Werror=return-type")
endif()
-save-temps
,-Wshadow
그리고-fmudflap
내가 아는하지 않은 가장 큰 발견은, 모두에게 감사했다.