วิธีเปิดคำเตือนทั้งหมดของ GCC (ตามตัวอักษร)?


194

ผมอยากจะเปิดใช้งาน - ตัวอักษร - ทั้งหมดของคำเตือนที่มี GCC (คุณคิดว่ามันจะง่าย ... )

  • คุณคิดว่า -Wallอาจอาจทำกลอุบาย แต่ไม่! -Wextraยังคงต้อง

  • คุณ-Wextraอาจคิดว่าอาจทำกลอุบาย แต่ไม่! ไม่ใช่คำเตือนทั้งหมดที่ระบุไว้ที่นี่ (ตัวอย่างเช่น-Wshadow) ไม่ได้เปิดใช้งานโดยสิ่งนี้ และฉันก็ยังไม่รู้ว่ารายการนี้ครอบคลุมหรือไม่

ฉันจะบอกให้ GCC เปิดใช้งานได้ (ไม่ว่าจะเป็นหรือไม่ก็เป็นได้ แต่อย่างเดียว) ทั้งหมดคำเตือนที่มีอยู่หรือไม่


27
@Arafangion: ฉันไม่เข้าใจสิ่งที่ "ไม่ชัดเจน" เกี่ยวกับคำถาม - ใช่ฉันต้องการที่จะเปิดคำเตือนทั้งหมดที่เกี่ยวข้องกับรหัสของฉันไม่ว่าจะอวดความรู้ สำหรับเหตุผลมันง่ายมาก: ฉันได้พบคำเตือนบางอย่างที่ไม่ได้เปิดใช้งาน - Wall หรือ -Wextra เพื่อเป็นประโยชน์และฉันต้องการลองใช้ส่วนที่เหลือเพื่อดูว่าฉันสามารถปรับปรุงรหัสของฉันได้หรือไม่ มันง่ายอย่างที่คิด
user541686

12
@JoachimPileborg: "คุณต้องการให้คอมไพเลอร์เตือนอย่างไร" ข้อผิดพลาดที่อาจเกิดขึ้นและ / หรือรูปแบบที่ไม่ดี? ฉันหมายความว่าถ้าฉันรู้คำเตือนที่แน่นอนทั้งหมดฉันจะเปิดใช้งานด้วยตนเองไม่จำเป็นต้องตั้งคำถาม หากคำตอบคือ "คุณต้องดูซอร์สโค้ดเพื่อค้นหาทั้งหมด" จากนั้นโปรดโพสต์เป็นคำตอบ!
user541686

56
เสียงดังกราว 3.1 -Weverythingข้อเสนอ
Alexandre Hamez

5
@Arafangion ดีคำถามที่ติดแท็ก C ++ ดังนั้น ... :)
โปรแกรมเมอร์บางคนเพื่อน

5
@JoachimPileborg และตอนนี้มีวิธีสุดท้ายในการแยกคำเตือนจากแหล่งที่มา: github.com/barro/compiler-warnings
Kyle Strand

คำตอบ:


130

คุณทำไม่ได้

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

การเปิดใช้งานทุกอย่างจะรวมถึง-Wdouble-promotionสิ่งที่เกี่ยวข้องกับซีพียูที่มีจุดลอยตัวความแม่นยำเดี่ยว 32 บิตซึ่งใช้floatในฮาร์ดแวร์ แต่เลียนแบบdoubleในซอฟต์แวร์ ทำการคำนวณตามที่doubleต้องการจะใช้การจำลองซอฟต์แวร์และช้ากว่า สิ่งนี้เกี่ยวข้องกับซีพียูในตัวบางตัว แต่ไม่เกี่ยวข้องอย่างสมบูรณ์สำหรับซีพียูเดสก์ท็อปสมัยใหม่ที่รองรับฮาร์ดแวร์สำหรับทศนิยม 64 บิต

คำเตือนอีกอย่างที่มักไม่ค่อยมีประโยชน์คือ-Wtraditionalซึ่งเตือนเกี่ยวกับโค้ดที่มีรูปแบบที่ดีซึ่งมีความหมายแตกต่างกัน (หรือไม่ทำงาน) ใน C ดั้งเดิมเช่น"string " "concatenation"หรือนิยามฟังก์ชัน ISO C! คุณสนใจความเข้ากันได้กับคอมไพเลอร์อายุ 30 ปีหรือไม่? คุณต้องการคำเตือนสำหรับการเขียนint inc(int i) { return i+1; }หรือไม่?

ฉันคิดว่า-Weffc++มันมีเสียงดังเกินไปที่จะเป็นประโยชน์มันขึ้นอยู่กับEffective C ++รุ่นแรกที่ล้าสมัยและเตือนเกี่ยวกับการสร้างที่ถูกต้องสมบูรณ์ C ++ (และแนวทางที่เปลี่ยนไปในหนังสือรุ่นต่อมา) ฉันไม่ต้องการ เตือนว่าฉันยังไม่ได้เริ่มstd::stringสมาชิกในคอนสตรัคของฉัน; มันมีคอนสตรัคเตอร์เริ่มต้นที่ทำสิ่งที่ฉันต้องการอย่างแน่นอนทำไมฉันจึงควรเขียนm_str()เพื่อเรียกมัน -Weffc++คำเตือนว่าจะเป็นประโยชน์เป็นเรื่องยากเกินไปสำหรับคอมไพเลอร์ในการตรวจสอบอย่างถูกต้อง (ให้ปลอมเนกาทีฟ) และคนที่ไม่ได้เป็นประโยชน์เช่นการเริ่มต้นสมาชิกทุกคนอย่างชัดเจนเพียงแค่การผลิตมากเกินไปเสียงให้ผลบวกปลอม

Luc Danton เป็นตัวอย่างที่ดีของการเตือนที่ไร้ประโยชน์-Waggregate-returnซึ่งแทบจะไม่สมเหตุสมผลเลยสำหรับรหัส C ++

เช่นคุณไม่ต้องการทุกคำเตือนคุณเพียงแค่คิดว่าคุณทำ

ทำตามคู่มืออ่านเกี่ยวกับพวกเขาตัดสินใจว่าคุณต้องการเปิดใช้งานลองอะไร การอ่านคู่มือของคอมไพเลอร์ของคุณคือ Good Thing TMอย่างไรก็ตามการตัดทอนและเปิดใช้งานคำเตือนที่คุณไม่เข้าใจนั้นไม่ใช่ความคิดที่ดีโดยเฉพาะอย่างยิ่งหากต้องหลีกเลี่ยงการใช้ RTFM

ใครก็ตามที่เพิ่งเปิดใช้งานทุกอย่างน่าจะทำเช่นนั้นเพราะพวกเขาไร้สาระเพราะหรือเจ้านายที่มีผมแหลมพูดว่า "ไม่มีคำเตือน"

คำเตือนบางอย่างมีความสำคัญและบางคำเตือนไม่ได้ คุณต้องเลือกปฏิบัติหรือทำให้โปรแกรมของคุณยุ่งเหยิง -Wdouble-promotionพิจารณาตัวอย่างเช่น หากคุณกำลังทำงานกับระบบฝังตัวคุณอาจต้องการสิ่งนี้ หากคุณกำลังทำงานกับระบบเดสก์ท็อปคุณอาจไม่ทำเช่นนั้น และคุณต้องการ-Wtraditional? ฉันสงสัยมัน.

แก้ไข:ดูเพิ่มเติม-Wall-all เพื่อเปิดใช้งานคำเตือนทั้งหมดที่ปิดเป็น WONTFIX

แก้ไข 2:เพื่อตอบสนองต่อการร้องเรียนของ DevSolar เกี่ยวกับ makefiles ที่จำเป็นต้องใช้คำเตือนที่แตกต่างกันขึ้นอยู่กับรุ่นของคอมไพเลอร์ถ้า-Wall -Wextraไม่เหมาะสมก็ไม่ยากที่จะใช้ CFLAGS เฉพาะคอมไพเลอร์และรุ่นเฉพาะ:

compiler_name := $(notdir $(CC))
ifeq ($(compiler_name),gcc)
compiler_version := $(basename $(shell $(CC) -dumpversion))
endif
ifeq ($(compile_name),clang)
compiler_version := $(shell $(CC) --version | awk 'NR==1{print $$3}')
endif
# ...
wflags.gcc.base := -Wall -Wextra
wflags.gcc.4.7 := -Wzero-as-null-pointer-constant
wflags.gcc.4.8 := $(wflags.gcc.4.7)
wflags.clang.base := -Wall -Wextra
wflags.clang.3.2 := -Weverything
CFLAGS += $(wflags.$(compiler_name).base) $(wflags.$(compiler_name).$(compiler_version))

38
"อ่านคู่มืออ่านเกี่ยวกับพวกเขาตัดสินใจเลือกว่าคุณต้องการเปิดใช้งานลองอะไรบ้าง" ปัญหาต่อไปนี้คือขั้นตอนที่คุณทิ้งไว้: "เยี่ยมชมคู่มือสำหรับคอมไพเลอร์แต่ละเวอร์ชั่นทุกครั้งและปรับรายการคำเตือนของคุณเนื่องจากมันเปลี่ยนไป Makefiles ของคุณตรวจสอบเวอร์ชั่นคอมไพเลอร์ที่แน่นอนและใช้รายการคำเตือนต่าง ๆสำหรับแต่ละคน " เรามีการเพิ่มประสิทธิภาพในระดับผู้ดูแลรักษา; ทำไมพวกเขาถึงไม่ใส่ใจที่จะให้บริการเดียวกันสำหรับคำเตือน?
DevSolar

17
@ JonathanWakely: ฉันมีโครงการของฉันและ GCC ไม่ได้อยู่ในหมู่พวกเขา ฉันชี้ไปที่จุดอ่อนในผลิตภัณฑ์ของพวกเขา ไม่ว่าพวกเขาจะแก้ไขหรือยอมรับความผิดที่ไม่ทำเช่นนั้น แต่ฉันไม่สามารถแก้ไขได้สำหรับพวกเขา OSS จะถูกสาป
DevSolar

14
@ JonathanWakely: "ถ้าคุณต้องการอะไรซักอย่างจงอย่าไปสนใจมัน" - ฉันไม่จำเป็นต้องเข้าร่วมในโครงการ GCC เพื่อทำการวิพากษ์วิจารณ์โดยเฉพาะอย่างยิ่งถ้า # 31573 ถูกตั้งค่าสถานะเป็น WONTFIX แล้ว ที่ทำให้เรื่องนี้จาก "ถามเกี่ยวกับมัน" ลงใน "เลวเกี่ยวกับมัน" ballpark
DevSolar

61
-Weverythingฉันคิดว่าเป็นทางออกที่ดีกว่ากลยุทธ์ gcc ที่ไม่ให้ทางเลือกดังกล่าว ฉันใช้ธงนั้นด้วยเสียงดังกราวเพราะปรัชญาของฉันคือฉันต้องการให้มีคำเตือนทั้งหมดตามค่าเริ่มต้น (เพราะมีคนคิดว่ามันมีประโยชน์มากพอที่จะเพิ่มในคอมไพเลอร์) และถ้าฉันไม่ชอบมันฉันก็ปิดคำเตือนนั้นโดยเฉพาะ ประเด็นคือคุณไม่ทราบเกี่ยวกับคำเตือนที่ไม่เรียกใช้ แต่คุณรู้เกี่ยวกับคำเตือนที่คุณไม่ต้องการให้เรียกใช้และจะปิดได้ง่าย
David Stone

17
@JonathanWakely ใช่ แต่พวกเขาก็เล็ก ๆ น้อย ๆ วิธีที่ง่ายที่สุดในการดูว่าคำเตือนใดที่อาจเกี่ยวข้องกับรหัสของคุณคือการดูว่าคำเตือนใดที่ถูกกระตุ้นด้วยรหัสของคุณ ณ จุดนั้นคุณจะเห็นตัวอย่างที่เกี่ยวข้องและเป็นจริงของรหัสที่อาจเป็นอันตรายก่อนตัดสินใจว่าจะปิดใช้งานคำเตือนหรือไม่ สิ่งนี้สามารถทำได้อย่างง่ายดายด้วย-Weverythingตัวเลือกของ Clang แต่ไม่สามารถทำได้กับ GCC
Kyle Strand

71

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

gcc -Q --help=warning

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

gcc -Wall -Wextra -Q --help=warning

เพื่อเปิดใช้งานคำเตือนทั้งหมดคุณสามารถใช้ regex บางอย่างเพื่อแยกพารามิเตอร์บรรทัดคำสั่ง

gcc -Q --help=warning | sed -e 's/^\s*\(\-\S*\)\s*\[\w*\]/\1 /gp;d' | tr -d '\n'

สำหรับ GCC ปัจจุบันของฉันสิ่งนี้ให้:

-Wabi -Wabi-tag -Waddress -Waggregate-return -Waggressive-loop-optimization -Waliasing -Walign-commons -Wampersand -Warray-ขอบเขต -Warray-temporary -Wassign-intercept -Wattign-function-cast -Wbuiltin-macro-redefined -Wc ++ - ความเข้ากันได้ -Wc ++ 0x-compat -Wc ++ 14-compat -Wc-binding-type -Wc90-c99-compat -Wc99-c11-compat -Wcast-qual -Wchar-subscripts -Wcharacter-truncation -Wchkp -Wclobbered -Wcomment -Wcompare-reals -Wals -dition -dition -Wconversion -Wconversion- พิเศษ -Wconversion-null -after-statement -Wdelete- ที่ไม่สมบูรณ์ -Wdelete- ไม่ใช่ -dtor เสมือน -Wdeprecated -Wdeprecated- ประกาศ -designed-init -Wdiseceded-init -Wdisard-optimization -Wdiscarded-qualifiers -Wdiscarded-qualifier -Wdiv- โดย - ศูนย์ -wdeprecate -Weffc ++ -Wempty-body-Wendif- ป้ายชื่อ -Wenum- เปรียบเทียบ -Wextra -Wfloat- เท่ากับ - รูปแบบที่มี -Nul - รูปแบบพิเศษ - args - รูปแบบที่ไม่ใช่รูปแบบ - การรักษาความปลอดภัย - รูปแบบ - เซ็น - รูปแบบ -y2k -nonheap-object -Wfunction-elimination -Wignored-qualifiers -Wimplicit -Wimplicit- ฟังก์ชั่นประกาศ -Wimplicit-int -Wimplicit-int -Wimplicit-procedure -Winplatable-pointer-type -Wint-conversion -Wint-to-pointer-cast -Wintrinsic-shadow -Wintrinsics-std -Winvalid-memory-model -Winvalid-offsetof -Winvalid-pch -Wjump-miss-init -Wline-truncation -not-วงเล็บ -Wlogical-op -Wlong-long -Wmain -Wmaybe-uninitialized -Wmemset-transposed-args -Wmissing-braces -Wmissing-field-initializer -Wmissing-field-initializers -Wmissing ต้นแบบ-Wmultichar -Wnarrowing -Wnested-externs -Wnoexcept -Won-template-friend -Wnon-virtual-dtor -Wnonnull -Wodr -Wold-style-cast -Wold-style-declar -Wold-style-definition -Wold-style-definition -Woverlength-strings -Woverloaded-virtual -Woverride-init -Wpacked -Wpacked-bitfield-compat -Wpadded -Wparentheses -Wpedantic -Wpmf-conversion -Wpointer-arith -Wpointer-to-int-cast -prprmas กำหนดค่าเริ่มต้น -Wprotocol -Wreal-q- คงที่ -Wrealloc-lhs -Wrealloc-lhs-all -Wundundant-decls -Wreorder -Wreturn-local-addr -Wreturn-type -Wsadowor -Wshadow-ivh -... -Wshift-count-negative -Wshift-count-over -Wsign- เปรียบเทียบ -Wsign-promo -Wsized-deallocation -Wsizeof-array-อาร์กิวเมนต์ -Wsizeof-pointer-memaccess -Wstack-null-sentinel -Wstrict เลือกการแข่งขัน-Wsuggest-attribute = const -Wsuggest-attribute = format รูปแบบ -Wsuggest-attribute = noreturn -Wsuggest-attribute = pure -Wsuggest-final-methods -Wsuggest-final-type -Wsuggest-overs -Wsitch-bool -Wschitch -Wool -default -Wswitch-enum -Wsync-nand -Wsynth -Wsystem-headers -Wtabs -Wtagetial -wtagetial-life -Wunsafe-loop-optimization -Wunsuffixed-float-constants -Wunused -Wunused-but-set-parameter -Wunused-but-set-variable -Wunused-dummy-อาร์กิวเมนต์ -Wunused-local-typedefef -Wunused-macros -Wunused-parameter -Wunused-result -Wunused-value -Wunused-variable -Wunused-variable -Wuse-without-only -Wuseless-cast -Wvarargs -Wvariadic-macros -WVariadic-macros -WVUUICIC-MOUNT-MOUNT-Wvla -Wvolatile-register-var -Wwrite-strings-Wzero-as-null-pointer-constant -Wzerotrip -frequire-return-statement

ตอนนี้สามารถใช้เรียก GCC ได้แล้วเช่น

gcc $(gcc -Q --help=warning | sed -e 's/^\s*\(\-\S*\)\s*\[\w*\]/\1 /gp;d' | tr -d '\n')

อย่างไรก็ตามโปรดทราบว่าสิ่งนี้ส่งผลให้เกิดการเตือนเนื่องจากตัวเลือกการเตือนบางอย่างมีเฉพาะในบางภาษา (เช่นC++) สิ่งเหล่านี้สามารถหลีกเลี่ยงได้โดยใช้ regex เพิ่มเติมเพื่อรวมเฉพาะตัวเลือกที่อนุญาตสำหรับภาษาปัจจุบันหรือโดยการเพิ่มความเหมาะสม-Wno-whateverเมื่อสิ้นสุดการโทร


10
ฉันกลัวว่ามันจะไม่สามารถใช้งานได้จริง Gcc แสดงคำเตือนจาก std lib ให้ฉันแล้ว
Valentin Heinitz

13
@VententHeinitz อย่างที่ฉันบอกว่าฉันไม่คิดว่ามันจะมีประโยชน์ในการเปิดใช้งานการเตือนทั้งหมด แต่นี่คือสิ่งที่ OP ขอ อย่างไรก็ตามฉันคิดว่าโดยการลบคำเตือนที่เป็นปัญหาบางอย่างที่กล่าวถึงแล้วในคำตอบอื่น ๆ (เช่นโดยการเพิ่มตามลำดับ - ไม่ว่าอะไรก็ตามในตอนท้ายของการโทร) สิ่งนี้สามารถนำไปใช้ได้จริง
Haatschii

6
@ValentinHeinitz คุณสามารถป้องกัน gcc จากการออกคำเตือนสำหรับส่วนหัวของระบบ / std / บุคคลที่สามโดยใช้-isystemแทน-Iไดเรกทอรีที่เกี่ยวข้อง
Kyle Strand

4
นี่ควรเป็นคำตอบที่ยอมรับเช่นนี้จริงและตอบคำถามได้โดยตรง
TFuto

16

เป็นไปไม่ได้ที่โปรแกรมจะเปิดใช้งานคำเตือนทั้งหมด (เว้นแต่คุณจะเพิกเฉยต่อคำเตือนเหล่านั้น แต่ทำไมต้องกังวลด้วย) ตัวอย่างเช่นสมมติว่าคุณใช้ชุดธงต่อไปนี้:-Wstrict-prototypes -Wtraditionalตัวอย่างเช่นสมมติว่าคุณใช้ต่อไปนี้ชุดของค่าสถานะ:

แม้จะเปิดใช้งานคำเตือนสองครั้งโปรแกรมต่อไปนี้ก็จะบ่น

/tmp $ cat main.c 
int main(int argc, char **argv) {
    return 0;
}
/tmp $ gcc -Wstrict-prototypes -Wtraditional main.c 
main.c: In function main’:
main.c:1:5: warning: traditional C rejects ISO C style function definitions [-Wtraditional]
 int main(int argc, char **argv) {
     ^

คุณอาจคิดว่า "ดีฉันจะใช้ต้นแบบแบบเก่าแล้ว" ไม่นี่ใช้ไม่ได้

/tmp $ cat main.c 
int main(argc, argv)
    int argc;
    char **argv;
{
    return 0;
}
/tmp $ gcc -Wstrict-prototypes -Wtraditional main.c 
main.c:1:5: warning: function declaration isnt a prototype [-Wstrict-prototypes]
 int main(argc, argv)
     ^

และไม่ไม่การระบุต้นแบบใด ๆ ก็ผิดเช่นกันเพราะคอมไพเลอร์ก็จะบ่นเช่นกัน

/tmp $ cat main.c 
int main() {
    return 0;
}
/tmp $ gcc -Wstrict-prototypes -Wtraditional main.c 
main.c:1:5: warning: function declaration isnt a prototype [-Wstrict-prototypes]
 int main() {
     ^

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

สำหรับ C ++ สิ่งนี้เป็นไปได้ ( -Wtraditionalไม่มีค่าสถานะ) และสามารถคอมไพล์โปรแกรมที่ง่ายมากได้ หากต้องการเปิดใช้งานคำเตือนทั้งหมดให้ใช้รายการคำเตือนต่อไปนี้ (อาจมีคำเตือนบางคำซ้ำเนื่องจากฉันไม่ได้กังวลที่จะเปิดใช้งานการกรองคำเตือน-Wall)

-Wabi -Wctor-dtor-privacy -Wnon-virtual-dtor -Wreorder -Weffc++ -Wstrict-null-sentinel -Wno-non-template-friend -Wold-style-cast -Woverloaded-virtual -Wno-pmf-conversions -Wsign-promo -Wextra -Wall -Waddress -Waggregate-return -Warray-bounds -Wno-attributes -Wno-builtin-macro-redefined -Wc++0x-compat -Wcast-align -Wcast-qual -Wchar-subscripts -Wclobbered -Wcomment -Wconversion -Wcoverage-mismatch -Wno-deprecated -Wno-deprecated-declarations -Wdisabled-optimization -Wno-div-by-zero -Wempty-body -Wenum-compare -Wno-endif-labels -Wfatal-errors -Wfloat-equal -Wformat -Wformat=2 -Wno-format-contains-nul -Wno-format-extra-args -Wformat-nonliteral -Wformat-security -Wformat-y2k -Wignored-qualifiers -Winit-self -Winline -Wno-int-to-pointer-cast -Wno-invalid-offsetof -Winvalid-pch -Wunsafe-loop-optimizations -Wlogical-op -Wlong-long -Wmain -Wmissing-braces -Wmissing-field-initializers -Wmissing-format-attribute -Wmissing-include-dirs -Wmissing-noreturn -Wno-mudflap -Wno-multichar -Wnonnull -Wno-overflow -Woverlength-strings -Wpacked -Wpacked-bitfield-compat -Wpadded -Wparentheses -Wpointer-arith -Wredundant-decls -Wreturn-type -Wsequence-point -Wshadow -Wsign-compare -Wsign-conversion -Wstack-protector -Wstrict-aliasing=1 -Wstrict-overflow=5 -Wswitch -Wswitch-default -Wswitch-enum -Wsync-nand -Wsystem-headers -Wtrigraphs -Wtype-limits -Wundef -Wuninitialized -Wunknown-pragmas -Wno-pragmas -Wunreachable-code -Wunused -Wunused-function -Wunused-label -Wunused-parameter -Wunused-value -Wunused-variable -Wvariadic-macros -Wvla -Wvolatile-register-var -Wwrite-strings

13
ฉันไม่เคยใส่ใจที่จะตรวจสอบเรื่องนี้จนถึงตอนนี้ แต่จริงๆแล้วมันเป็นไปไม่ได้ ... ลองint main(int, char **); int main(argc, argv) int argc; char **argv; { (void)argc; (void)argv; return 0; }
user541686

2
แม้จะมีโปรแกรมเล็ก ๆ น้อย ๆ นี้ฉันยังสามารถได้รับ "คำเตือน: การใช้สแต็กคือ 16 ไบต์ [-Wstack-Usage =]" ;-)
Marc Glisse

7

มีคนสร้างชุดเครื่องมือสำหรับกำหนดความสมบูรณ์ชุดคำเตือนที่สำหรับรุ่น GCC หรือ Clang ที่ให้มา

สำหรับ GCC การคัดลอกจากรายการคำเตือนทั้งหมดที่มีให้โดยเครื่องมือนี้สำหรับเวอร์ชั่นคอมไพเลอร์ของคุณดูเหมือนจะเป็นวิธีเดียวที่จะทำให้มั่นใจได้ว่าคำเตือนทั้งหมดจะเปิดใช้งานเนื่องจาก (ไม่เหมือน Clang) GCC ไม่มี-Weverythingไม่ได้ให้

เครื่องมือจะแยกวิเคราะห์c.optไฟล์จริงในซอร์สโค้ด GCC ดังนั้นผลลัพธ์ควรจะเป็นชัดเจน

พื้นที่เก็บข้อมูลยังมีไฟล์ข้อความที่มีรายการคำเตือนที่สร้างขึ้นสำหรับรุ่น GCC และ Clang ส่วนใหญ่ (ปัจจุบัน Clang 3.2 ถึง 3.7 และ GCC 3.4 ถึง 5.3)

https://github.com/barro/compiler-warnings


นี่คือคำตอบ ใช้รายการ "ระดับสูงสุด" และเพิ่มอาร์กิวเมนต์ทั้งหมดที่อยู่ในระดับบนสุด (ไม่เยื้อง / ซ้อนกัน) github.com/Barro/compiler-warnings/blob/master/gcc/…
Jetski S-type

6

ตอนนี้ Gcc 4.3+ มี -Q --help = คำเตือนคุณสามารถระบุ --help = คำเตือนได้ C เพื่อพิมพ์คำเตือนที่เกี่ยวข้องกับ C

ฉันเพิ่งเขียนโมดูล m4 เพื่อใช้ประโยชน์จากสิ่งนี้ (ยังสนับสนุนเสียงดังกราว - ทุกอย่าง) ดูwget_manywarnings.m4

วิธีใช้งานนั้นค่อนข้างง่ายโดยทั่วไปโมดูลจะเปิดใช้งานการตั้งค่าสถานะการเตือนทุกครั้ง และคุณลบคำเตือนตามที่จำเป็น - บางอย่างเป็นจริง verbose ตัวอย่าง: configure.ac

หากคุณไม่ใช้เครื่องมืออัตโนมัติคุณจะพบรหัสเพื่อเปิดการเตือนที่ถูกปิดการใช้งานทั้งหมดในโมดูล m4 ซึ่งโดยทั่วไปแล้วจะเป็นการโทร gcc ผ่านไปยัง awk:

flags="-Wall -Wextra -Wformat=2 "$(gcc -Wall -Wextra -Wformat=2 -Q --help=warning,C|awk '{ if (($2 == "[disabled]" || $2 == "") && $1!~/=/ && $1~/^-W/&& $1!="-Wall") print $1 }'


3

จากหน้านี้ :

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

ผมคิดว่าคำถามคือคนที่ ? บางทีคุณอาจgrepหน้านั้นสำหรับทุกบรรทัดที่ขึ้นต้นด้วย -W และรับรายการคำเตือนทั้งหมด แล้วเปรียบเทียบกับผู้ที่มีรายชื่อที่อยู่ภายใต้และ-Wall -Wextraนอกจากนี้ยังมี-Wpedanticแม้ว่าคุณจะเห็นได้ชัดว่าต้องการที่จะยังคงอวดรู้มากขึ้น =)


"และฉันก็ยังไม่รู้ว่ารายการนี้จะครอบคลุม" ... ใช่ฉันสามารถ grep หน้านั้นได้ แต่คำถามคือมันครอบคลุมหรือไม่
user541686

1
ฉันไม่รู้ ... คุณอาจต้องเทรหัสแหล่ง GCC คุณกำลังพยายามทำให้ชีวิตของคุณในฐานะโปรแกรมเมอร์ลำบากหรือมีเหตุผลที่ดีที่คุณต้องการเห็นคำเตือนที่นึกออกได้ทั้งหมดหรือไม่? =)
ข้าวเปลือก

2
ฉันต้องการเห็นการวิเคราะห์รหัสของ GCC - ฉันคิดว่าเป็นประโยชน์จริงๆ แต่เห็นได้ชัดว่าถ้าฉันรู้แล้วเกี่ยวกับคำเตือนทั้งหมดและสิ่งที่มีประโยชน์ (และที่ไม่ได้) แล้วก็จะไม่มีอะไรถาม ไม่มีทางที่จริงที่ฉันจะบอกเว้นแต่ว่าฉันลองพวกเขา (และฉันพบว่าเงาหนึ่งมีประโยชน์ดังนั้นจึงไม่ใช่ว่าพวกเขาไร้ประโยชน์เพราะพวกเขาถูกปิด)
user541686

3

และฉันก็ยังไม่รู้ว่ารายการนี้ครอบคลุมหรือไม่

อาจเป็น แต่รายการเดียวที่ครอบคลุม 100% เป็นแหล่งข้อมูลจริงสำหรับคอมไพเลอร์ อย่างไรก็ตาม GCC นั้นใหญ่มาก ! และฉันไม่รู้ว่าพารามิเตอร์บรรทัดคำสั่งทั้งหมดจะถูกรวบรวมไว้ในที่เดียวหรือกระจายไปทั่วหลายไฟล์ต้นฉบับ โปรดทราบว่าคำเตือนบางอย่างใช้สำหรับตัวประมวลผลล่วงหน้าบางตัวสำหรับคอมไพเลอร์จริงและบางส่วนสำหรับตัวเชื่อมโยง (ซึ่งเป็นโปรแกรมที่แยกจากกันโดยสิ้นเชิงและพบได้ในแพ็คเกจ binutils) ดังนั้นจึงเป็นไปได้มาก


3
ฉันเชื่อมโยงไปยังหน้าสรุปตัวเลือกในคำตอบของฉันซึ่งจัดกลุ่มตัวเลือกทั้งหมดไว้ในหน้าเดียว นโยบายการตรวจสอบรหัส GCC ไม่อนุญาตตัวเลือกใหม่โดยไม่มีเอกสารประกอบดังนั้นเอกสารควรจะครอบคลุม
โจนาธาน Wakely
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.