ธง GCC ที่มีประโยชน์สำหรับ C


157

นอกเหนือจากการตั้งค่า-Wallและการตั้งค่า-std=XXXแล้วมีประโยชน์อื่น ๆ อีกมากมาย แต่มีการรวบรวมค่าสถานะคอมไพเลอร์น้อยกว่าที่ใช้ใน C?

ฉันสนใจเป็นพิเศษในการเตือนเพิ่มเติมและ / หรือการเปลี่ยนคำเตือนเป็นข้อผิดพลาดในบางกรณีเพื่อลดความไม่ตรงกันของประเภทอุบัติเหตุใด ๆ


9
ดี-save-temps, -Wshadowและ-fmudflapเป็นคนพบที่ยิ่งใหญ่ที่สุดผมไม่ทราบว่าของขอบคุณทั้งหมด
Matt Joiner

บริบทเท่าที่ฉันสามารถบอกได้: รันgcc -c [flags-go-here] -o myprog.o myprog.cเพื่อคอมไพล์ (ไม่ใช่ลิงก์) โปรแกรม C
Rory O'Kane

คำตอบ:


64

หลาย-fตัวเลือกรหัสรุ่นเป็นที่น่าสนใจ:

  • -ftrapvฟังก์ชั่นจะทำให้โปรแกรมที่จะยกเลิกในการลงนามจำนวนเต็มล้น (อย่างเป็นทางการ "พฤติกรรมที่ไม่ได้กำหนด" ใน C)

  • -fverbose-asmมีประโยชน์ถ้าคุณกำลังคอมไพล์ด้วย-Sเพื่อตรวจสอบเอาต์พุตแอสเซมบลี - เพิ่มความคิดเห็นที่ให้ข้อมูลบางอย่าง

  • -finstrument-functions เพิ่มรหัสเพื่อเรียกใช้ฟังก์ชั่นการทำโปรไฟล์ที่ผู้ใช้ป้อนในทุกฟังก์ชั่นการเข้าและออกจากจุด


สำหรับ-ftrapvลองดูที่นี่stackoverflow.com/questions/20851061/ … .. ดูเหมือนว่าจะมีข้อผิดพลาดที่รอการแก้ไข
Arjun Sreedharan

คุณสามารถตรวจสอบความคิดเห็นข้างต้นได้หรือไม่
Suraj Jain

-ftrapv ถูกแทนที่โดย -fsanitize = Sign-integer-overflow
Marc Glisse

139

นี่คือของฉัน:

  • -Wextra, -Wall: จำเป็น
  • -Wfloat-equal: มีประโยชน์เพราะโดยปกติแล้วการทดสอบจำนวนจุดลอยตัวเพื่อความเท่าเทียมนั้นไม่ดี
  • -Wundef: เตือนหากมีการระบุเตรียมรับการประเมินใน#ifคำสั่ง
  • -Wshadow: เตือนเมื่อใดก็ตามที่ตัวแปรท้องถิ่นแสดงเงาตัวแปรภายในตัวอื่นพารามิเตอร์หรือตัวแปรส่วนกลางหรือเมื่อใดก็ตามที่มีฟังก์ชั่นในตัวเป็นเงา
  • -Wpointer-arith: voidเตือนหากมีสิ่งใดขึ้นอยู่กับขนาดของฟังก์ชั่นหรือของ
  • -Wcast-align: เตือนเมื่อใดก็ตามที่ตัวชี้ถูกส่งไปซึ่งการปรับตำแหน่งที่ต้องการของเป้าหมายจะเพิ่มขึ้น ตัวอย่างเช่นเตือนถ้า 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รหัสชื่อที่ระบุอย่างน้อยหนึ่งรายการ*
  • -Wconversion: เตือนสำหรับการแปลงนัยที่อาจปรับเปลี่ยนค่า*
  • -Wunreachable-code: เตือนถ้าคอมไพเลอร์จะตรวจพบโค้ดที่จะไม่ดำเนินการ*

เครื่องหมาย*เหล่านั้นบางครั้งให้คำเตือนปลอมมากเกินไปดังนั้นฉันจึงใช้มันตามความจำเป็น


11
รายการสวยสมบูรณ์เพียงต้องการที่จะเพิ่มมากขึ้น -Wformat=2: การตรวจสอบรูปแบบพิเศษใน printf / ฟังก์ชั่น scanf
Schot

1
arent ทั้งหมดเหล่านี้โดยนัยโดย-Wall?
chacham15

2
@ chacham15 ไม่ฉันไม่คิดอย่างนั้น gcc.gnu.org/onlinedocs/gcc/Warning-Options.html
Alok Singhal

1
@ ถามอืมบางทีมันอาจไม่ได้มาตรฐานในการแจกแจงเหรอ? ฉันรู้ว่าใน mbp ของฉันฉันต้องปิดอย่างชัดเจน-Wwrite-stringsเพราะฉันเกลียดมันมาก
chacham15

@ chacham15 อาจจะ แต่คำอธิบายสำหรับ-Wwrite-stringsเฉพาะบอกว่ามันไม่ได้เป็นส่วนหนึ่งของ-Wall: gcc.gnu.org/onlinedocs/gcc/... อาจมีอย่างอื่นในการตั้งค่าของคุณที่ตั้งค่าสถานะนั้น หรือบางทีคุณกำลังรวบรวม C ++?
Alok Singhal

52

มักจะใช้-Oหรือสูงกว่า ( -O1, -O2, -Osฯลฯ ) ที่ระดับการปรับให้เหมาะสมเริ่มต้น gcc จะมีความเร็วในการรวบรวมและไม่เพียงพอที่จะวิเคราะห์เตือนสิ่งต่าง ๆ เช่นตัวแปรตามหน่วย

พิจารณา-Werrorกำหนดนโยบายเนื่องจากคำเตือนที่ไม่หยุดรวบรวมมีแนวโน้มที่จะถูกละเว้น

-Wall คำเตือนที่มีแนวโน้มว่าจะเป็นข้อผิดพลาดค่อนข้างมาก

คำเตือนรวมอยู่ใน-Wextraแนวโน้มที่จะธงทั่วไปรหัสถูกต้องตามกฎหมาย พวกเขาอาจจะมีประโยชน์สำหรับการตรวจสอบรหัส (แม้ว่าโปรแกรมผ้าสำลีสไตล์หาข้อผิดพลาดมากขึ้นจะมีความยืดหยุ่นมากขึ้น) แต่ฉันจะไม่ทำให้พวกเขาสำหรับการพัฒนาปกติ

-Wfloat-equal เป็นความคิดที่ดีถ้านักพัฒนาในโครงการที่ไม่คุ้นเคยกับจุดลอยและเป็นความคิดที่ไม่ดีถ้าพวกเขามี

-Winit-selfมีประโยชน์ -Wuninitializedผมสงสัยว่าทำไมมันไม่ได้รวมอยู่ใน

-Wpointer-arith-pedanticจะเป็นประโยชน์ถ้าคุณมีรหัสส่วนใหญ่แบบพกพาที่ไม่ได้ทำงานกับ


9
+1 สำหรับ "-Wfloat เท่ากับเป็นความคิดที่ดีถ้านักพัฒนาในโครงการที่ไม่คุ้นเคยกับจุดลอยและเป็นความคิดที่ไม่ดีถ้าพวกเขาจะ." โดยเฉพาะอย่างยิ่งในช่วงครึ่งหลังของมัน :-)
R .. GitHub ช่วยหยุด ICE

39
-save-temps

สิ่งนี้จะทิ้งไว้ข้างหลังผลลัพธ์ของตัวประมวลผลล่วงหน้าและแอสเซมบลี

ซอร์สที่ถูกประมวลผลล่วงหน้ามีประโยชน์สำหรับการดีบักแมโคร

แอสเซมบลีมีประโยชน์สำหรับการพิจารณาว่าการปรับให้เหมาะสมใดมีผลบังคับใช้ ตัวอย่างเช่นคุณอาจต้องการตรวจสอบว่า GCC กำลังทำการเพิ่มประสิทธิภาพการโทรหางในบางฟังก์ชั่นวนซ้ำโดยที่คุณไม่สามารถล้นกองซ้อนได้


ฉันสงสัยว่าคุณจะทำมันอย่างไร ... ฉันแค่ขอให้จีซีซีทิ้งชุดประกอบถ้าฉันต้องการมัน

35

ฉันประหลาดใจที่ไม่มีใครได้กล่าวว่านี้ยัง - ธงประโยชน์มากที่สุดเท่าที่ฉันเป็นห่วง-gซึ่งทำให้การแก้จุดบกพร่องข้อมูลลงในปฏิบัติการดังกล่าวที่คุณสามารถแก้ปัญหาและขั้นตอนผ่านแหล่งที่มา (เว้นแต่คุณจะมีความเชี่ยวชาญและการอ่านการชุมนุมและกำลัง เช่นstepiคำสั่ง) ของโปรแกรมในขณะที่มันดำเนินการ


35

-fmudflap - เพิ่มการตรวจสอบรันไทม์ทุกการดำเนินงานตัวชี้ความเสี่ยงที่จะจับ UB ได้อย่างมีประสิทธิภาพ immunizes โปรแกรมของคุณอีกครั้งบัฟเฟอร์ล้นและช่วยในการจับทุกชนิดของตัวชี้ห้อย

นี่คือตัวอย่าง:

$ 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

อืมดูเหมือนว่าโคลนที่น่ารังเกียจ: P
Matt Joiner

9
-fmudflapไม่มีการสนับสนุนตั้งแต่ GCC 4.9 warning: switch '-fmudflap' is no longer supportedคุณจะได้รับ มันถูกแทนที่โดย AddressSanitizer
ตือ

21

ไม่เกี่ยวข้องกับ C / C ++ จริงๆ แต่มีประโยชน์อยู่ดี:

@file

ใส่แฟล็กที่ดีทั้งหมดข้างต้น (ซึ่งคุณระบุไว้ทั้งหมด) ใน 'ไฟล์' และใช้แฟล็กนี้ด้านบนเพื่อใช้การตั้งค่าสถานะทั้งหมดในไฟล์นั้นร่วมกัน

เช่น:

ไฟล์: compilerFlags

-ผนัง

-std = c99

-Wextra

จากนั้นรวบรวม:

gcc yourSourceFile @compilerFlags

15

-march=native เพื่อสร้างโค้ดที่ปรับให้เหมาะสมที่สุดสำหรับแพลตฟอร์ม (= ชิป) ที่คุณกำลังรวบรวม


2
หากคุณกำลังรวบรวมสำหรับเครื่องที่ไม่ใช่เจ้าของภาษาที่คุณไม่ทราบว่าเป้าหมายที่คุณสามารถใช้ mtune = xxx ซึ่งเพิ่มประสิทธิภาพโดยไม่ต้องใช้ชุดคำสั่ง ตัวอย่างเช่น mtune = generic ได้รับการปรับปรุงด้วยตัวประมวลผลเคส "เฉลี่ย"
Turix

15

หากคุณจำเป็นต้องรู้ธง preprocessor ที่มีการกำหนดไว้ล่วงหน้าโดยคอมไพเลอร์:

echo | gcc -E -dM -

13

มันไม่ได้เป็นประโยชน์มากสำหรับการตรวจสอบข้อผิดพลาด แต่ไม่ค่อยกล่าวถึง-masm=intelตัวเลือกที่จะทำให้การใช้-Sในการตรวจสอบการส่งออกการชุมนุมมากมาก nicer

AT & T ประกอบไวยากรณ์เจ็บหัวของฉันมากเกินไป


2
ความแตกต่างระหว่าง AT&T กับ Intel สำหรับฉันคือความแตกต่างระหว่าง C # และ Java ไวยากรณ์เพียง ทั้งน่ากลัว :)
แมตต์ช่างไม้

2
1 @michael สำหรับการใช้ gcc ไวยากรณ์ Intel แทนของพระเจ้าอันยิ่งใหญ่ของ AT & T การตรวจสอบการประกอบใช้วงจรสมองพอ - ไม่จำเป็นต้องเสียรอบสมองที่ src ไปก่อนปลายทางใน opcodes ตอนนี้ถ้าเพียง GCC สนับสนุน __asm {} อินไลน์เช่นคอมไพเลอร์อื่น ๆ ที่เราได้ตั้งค่าทั้งหมด!
greatwolf

10

makefile ของฉันมักจะมี

  CFLAGS= -Wall -Wextra -Weffc++ -Os -ggdb
  ...
  g++ $(CFLAGS) -o junk $<
  gcc $(CFLAGS) -o $@ $<
  rm -f junk

สิ่งสำคัญที่สุดของตัวเลือกเหล่านี้ได้ถูกกล่าวถึงก่อนหน้านี้ดังนั้นฉันจะชี้ให้เห็นคุณสมบัติทั้งสองที่ยังไม่ได้ชี้:

แม้ว่าฉันจะทำงานกับ codebase ที่ต้องธรรมดา C สำหรับการพกพาไปยังแพลตฟอร์มที่ยังไม่มีคอมไพเลอร์ C ++ ที่เหมาะสมฉันก็คอมไพล์ "พิเศษ" กับคอมไพเลอร์ C ++ (นอกเหนือจากคอมไพเลอร์ C) ที่มีประโยชน์ 3:

  1. คอมไพเลอร์ C ++ บางครั้งทำให้ฉันมีข้อความเตือนดีกว่าคอมไพเลอร์ C
  2. คอมไพเลอร์ C ++ ยอมรับตัวเลือก -Weffc ++ ซึ่งบางครั้งก็ให้คำแนะนำที่เป็นประโยชน์กับฉันซึ่งฉันจะพลาดถ้าฉันรวบรวมมันด้วย C เท่านั้น
  3. ฉันจะเก็บรหัสค่อนข้างง่ายที่จะพอร์ตไปยัง C ++ หลีกเลี่ยงเงื่อนไขขอบเขตไม่กี่ที่รหัส C ธรรมดาไม่ถูกต้องรหัส c ++ (เช่นการกำหนดตัวแปรที่ชื่อ "บูล")

ใช่ฉันมองโลกในแง่ดีเสมออย่างไร้ความหวังที่ช่วยให้การคิดว่าแน่นอนเดือนใด ๆ ในขณะนี้ว่าแพลตฟอร์มหนึ่งอาจจะได้รับการประกาศล้าสมัยหรือได้รับความดี C ++ คอมไพเลอร์และในที่สุดเราก็สามารถเปลี่ยนไปใช้ภาษา C ++ ในใจของฉันมันเป็นสิ่งที่หลีกเลี่ยงไม่ได้ - คำถามเดียวก็คือว่าจะเกิดขึ้นก่อนหรือหลังการจัดการในที่สุดก็ทำให้ทุกคนเป็นม้า :-)


จุดที่ดีกับการเขียนมันเป็น C ++ ฉันพิจารณาเรื่องนี้บ่อยๆ (ย่อยตามธรรมชาติ)
แมตต์ช่างไม้

6
ฉันควรจะชี้ให้เห็นว่าซีถูกเลิกในความโปรดปรานของ C ++ จะไม่เกิดขึ้นขออภัย :)
แมตต์ช่างไม้

4
พิจารณา -o / dev / null แทน RM -f ขยะ
ulidtko

9
-Wstrict-prototypes -Wmissing-prototypes

10
และ-Wold-style-definitionถ้าคุณต้องจัดการกับผู้กระทำผิดที่คิดว่าฟังก์ชั่นสไตล์ K&R นั้นเป็นความคิดที่ดีแม้จะมีการประกาศต้นแบบ (ฉันต้องจัดการกับคนแบบนั้นมันทำให้ฉันรำคาญจริง ๆ เมื่อฉันพบรหัสใหม่ที่เขียนใน K&R มันไม่ดีพอที่มีสิ่ง K & R แบบดั้งเดิมที่ไม่ได้รับการแก้ไข แต่รหัสใหม่ Grump !!!)
Jonathan Leffler

9

นี่คือธงที่ยอดเยี่ยมที่ไม่ได้กล่าวถึง:

-Werror-implicit-function-declaration

ให้ข้อผิดพลาดเมื่อใดก็ตามที่มีการใช้ฟังก์ชันก่อนที่จะถูกประกาศ


8
man gcc

คู่มือการใช้งานเต็มรูปแบบของธงที่น่าสนใจกับคำอธิบายที่ดี อย่างไรก็ตาม - อาจจะทำให้ gcc เป็น verbose มากที่สุด หากคุณต้องการข้อมูลที่น่าสนใจมากขึ้นคุณควรตรวจสอบ valgrind หรือเครื่องมืออื่น ๆ สำหรับตรวจสอบข้อผิดพลาด


1
แม้ว่ามันจะเป็น loooooooooooooooooooooooooooooooooooooooo man gcc | nlรายงานกว่า 11,000 สาย นั่นเป็นมากกว่าbashmanpage ที่น่าอับอาย!
new123456

12
ขอบคุณพระเจ้าที่พวกเขาหนาตาลงในหน้าชายคนหนึ่งแทนหนึ่งของ godawful unnavigateable หน้า "ข้อมูล" เหล่านั้น
แมตต์ช่างไม้

6

ดี-Wextraควรจะมีมาตรฐานมากเกินไป -Werrorเปลี่ยนคำเตือนเป็นข้อผิดพลาด (ซึ่งน่ารำคาญมากโดยเฉพาะถ้าคุณคอมไพล์โดยไม่มี-Wno-unused-result) -pedanticใช้ร่วมกับstd=c89ให้คำเตือนเพิ่มเติมหากคุณใช้คุณสมบัติ C99

แต่นั่นเป็นเรื่องของมัน คุณไม่สามารถปรับแต่งคอมไพเลอร์ C เป็นสิ่งที่ประหยัดมากขึ้นกว่า C เอง


6

-M* ครอบครัวของตัวเลือก

สิ่งเหล่านี้ช่วยให้คุณสามารถเขียนไฟล์ make ซึ่งจะระบุไฟล์ส่วนหัวของไฟล์ต้นฉบับ c หรือ c ++ ของคุณโดยอัตโนมัติ GCC จะสร้างไฟล์ที่มีข้อมูลการพึ่งพานี้จากนั้นคุณจะรวมไฟล์เหล่านั้นจากไฟล์สร้างหลัก

นี่คือตัวอย่างของ Makefile ทั่วไปมากใช้ -MD และ -MP ที่จะรวบรวมไดเรกทอรีเต็มรูปแบบของภาษา C ++ แหล่งที่มาและไฟล์ส่วนหัวและตัวเลขออกอ้างอิงทั้งหมดโดยอัตโนมัติ:

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


6

มี-Werrorซึ่งถือว่าคำเตือนทั้งหมดเป็นข้อผิดพลาดและหยุดการรวบรวม gccหน้าคู่มืออธิบายทุกสวิตช์บรรทัดคำสั่งสำหรับคอมไพเลอร์ของคุณ


@Matt Joiner: เนื่องจากคุณไม่ได้พูดถึงสถาปัตยกรรมของเครื่องจักรที่คุณกำลังใช้งานอยู่gccธงอาจแตกต่างกันระหว่างคุณกับสิ่งที่ทุกคนอาจแนะนำให้ลิงก์ นี่คือเหตุผลที่หน้าคู่มือมีให้กับซอฟต์แวร์ของคุณ
เกร็กฮิวกิลล์

4

-Wfloat-equal

จาก: http://mces.blogspot.com/2005/07/char-const-argv.html

หนึ่งในคำเตือนใหม่อื่น ๆ ที่ผมชอบเป็น -Wfloat เท่ากับ ที่หนึ่งเตือนเมื่อใดก็ตามที่คุณ [มี] จำนวนจุดลอยตัวในสภาพที่เท่าเทียมกัน นั่นบ้าคลั่ง! ถ้าคุณได้ทุกโปรแกรมคอมพิวเตอร์กราฟิกหรือ (อัลกอริทึมเรขาคณิตที่เลวร้ายยิ่ง :) คำนวณคุณรู้ว่าไม่มีสองลอยเคยตรงกับความเท่าเทียมกัน ...


10
ลอยของฉันไม่ตรงกับความเสมอภาคที่ผมรู้ว่าสิ่งที่ฉันทำ
Roland Illig

4

ผมพบว่าหัวข้อนี้มองหาธงในการแก้ไขปัญหาเฉพาะที่ผมไม่เห็นมันในที่นี่ดังนั้นฉันจะเพิ่มหนึ่งที่เป็นเพียงโคนผมในการโพสต์ของฉัน :

-Wformat=2ธง

-Wformat=> ตรวจสอบการโทรไปยังprintfและscanfอื่น ๆ เพื่อให้แน่ใจว่าอาร์กิวเมนต์ที่ระบุมีประเภทที่เหมาะสมกับสตริงรูปแบบที่ระบุ ...

และส่วนที่สำคัญจริงๆเกี่ยวกับเรื่องนี้ ( ตามคู่มือจีซี ):

-Wformat-Wallจะรวมอยู่ใน สำหรับการควบคุมที่มากกว่าบางแง่มุมของรูปแบบการตรวจสอบตัวเลือก-Wformat-y2k, -Wno-format-extra-args, -Wno-format-zero-length, -Wformat-nonliteral, -Wformat-securityและ-Wformat=2มี แต่จะไม่รวมอยู่ใน -Wall.`

ดังนั้นเพียงเพราะคุณมี-Wallไม่ได้หมายความว่าคุณมีทุกอย่าง ;)


3

ผมบางครั้งใช้-sสำหรับปฏิบัติการขนาดเล็กมาก:

-s
    Remove all symbol table and relocation information from the executable.

ที่มา: http://gcc.gnu.org/onlinedocs/gcc/Link-Options.html#Link-Options


6
คุณควรรันstripบนไบนารี่ของคุณด้วยวิธีนี้คุณสามารถมีไบนารี่ที่มีข้อมูลดีบั๊กนำออกในภายหลังเพื่อการแจกจ่าย
Hasturkun

ใช่stripทำงานด้วย แต่-sสามารถเร็วและง่ายขึ้นแม้ว่าจะไม่ซับซ้อนเท่าการทำงานstrip
Vasiliy Sharapov

3

ในขณะที่คำตอบนี้อาจไม่ได้อยู่ที่หัวข้อเล็กน้อยและคำถามคือ +1 ที่คุ้มค่าจากฉันตั้งแต่

ฉันสนใจเป็นพิเศษในการเตือนเพิ่มเติมและ / หรือการเปลี่ยนคำเตือนเป็นข้อผิดพลาดในบางกรณีเพื่อลดความไม่ตรงกันของประเภทอุบัติเหตุใด ๆ
มีเครื่องมือที่ควรจับออกALLข้อผิดพลาดและข้อผิดพลาดที่อาจจะไม่ชัดเจนมีเฝือกซึ่ง IMHO ไม่ทำงานวิธีที่ดีกว่าในการจับข้อผิดพลาดเมื่อเทียบกับ GCC หรือคอมไพเลอร์อื่น ๆ สำหรับเรื่องที่ นั่นเป็นเครื่องมือที่ควรค่าแก่การมีในหีบเครื่องมือของคุณ

การตรวจสอบแบบคงที่ผ่านเครื่องมือชนิด lint เช่น splint ควรเป็นส่วนหนึ่งของ toolchain ของคอมไพเลอร์


มันมักจะแสดงข้อผิดพลาดไม่สามารถยื่นไฟล์ตัวประมวลผลล่วงหน้าใน C: \ รวม, ฉันไม่แน่ใจว่าจะทำอย่างไร
Suraj Jain

2

ฉันสนใจคำเตือนเพิ่มเติมเป็นพิเศษ

นอกเหนือไปจาก-Wallนี้-Wหรือ-Wextraตัวเลือก ( -Wทำงานร่วมกับรุ่นเก่าของ GCC เช่นเดียวกับคนรุ่นใหม่; รุ่นล่าสุดสนับสนุนการเลือกชื่อ-Wextraซึ่งหมายถึงสิ่งเดียวกัน แต่อธิบายเพิ่มเติม) ช่วยให้คำเตือนเพิ่มเติมต่างๆ

นอกจากนี้ยังมีคำเตือนเพิ่มเติมที่ไม่ได้เปิดใช้งานโดยทั้งสองอย่างโดยทั่วไปสำหรับสิ่งที่ไม่ดีอย่างน่าสงสัย ชุดตัวเลือกที่มีจะขึ้นอยู่กับรุ่น gcc ที่คุณกำลังใช้ - ปรึกษาman gccหรือinfo gccดูรายละเอียดหรือดูเอกสารออนไลน์สำหรับรุ่น gcc เฉพาะที่คุณสนใจและ-pedanticออกคำเตือนทั้งหมดที่จำเป็นสำหรับมาตรฐานที่ใช้ (ซึ่งขึ้นอยู่กับ ในตัวเลือกอื่น ๆ เช่น-std=xxxหรือ-ansi) และบ่นเกี่ยวกับการใช้ส่วนขยาย gcc

และ / หรือและการเปลี่ยนคำเตือนเป็นข้อผิดพลาดในบางกรณีเพื่อลดการจับคู่ประเภทอุบัติเหตุโดยไม่ตั้งใจ

-Werrorเปลี่ยนคำเตือนทั้งหมดเป็นข้อผิดพลาด ฉันไม่คิดว่า gcc ช่วยให้คุณสามารถเลือกคำเตือนนั้นได้

คุณอาจพบว่าคุณต้องเลือกเกี่ยวกับคำเตือนที่เปิดใช้งานในแต่ละโครงการ (โดยเฉพาะถ้าคุณใช้-Werror) เนื่องจากไฟล์ส่วนหัวจากไลบรารีภายนอกสามารถเดินทางบางส่วนได้ ( -pedanticโดยเฉพาะอย่างยิ่งมีแนวโน้มที่จะไม่ช่วยเหลือในส่วนนี้ในประสบการณ์ของฉัน)


4
"ฉันไม่คิดว่า gcc จะช่วยให้คุณสามารถเลือกคำเตือนนั้นเป็นพิเศษได้" -Werror=some-warningที่จริงแล้วคุณสามารถมี
Matthew Flaschen

0
  • -Wmissing-prototypes: ถ้าฟังก์ชั่นระดับโลกถูกกำหนดโดยไม่ต้องประกาศก่อนหน้าต้นแบบ
  • -Wformat-security: เตือนเกี่ยวกับการใช้ฟังก์ชั่นในรูปแบบที่เป็นตัวแทนของปัญหาด้านความปลอดภัยที่เป็นไปได้ ในปัจจุบันนี้เตือนเกี่ยวกับการโทรไปยังprintfและscanfฟังก์ชั่นที่สตริงรูปแบบไม่ได้เป็นตัวอักษรสตริงและไม่มีข้อโต้แย้งรูปแบบ

0
  • -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()
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.