ทำไมฟังก์ชั่นที่ไม่มีพารามิเตอร์ (เมื่อเปรียบเทียบกับนิยามของฟังก์ชันจริง) คอมไพล์?


388

ฉันเพิ่งเจอรหัส C ของใครบางคนที่ฉันสับสนว่าทำไมมันถึงรวบรวม มีสองประเด็นที่ฉันไม่เข้าใจ

ก่อนอื่นฟังก์ชั่นต้นแบบนั้นไม่มีพารามิเตอร์เทียบกับนิยามฟังก์ชันจริง ประการที่สองพารามิเตอร์ในการกำหนดฟังก์ชั่นไม่ได้มีประเภท

#include <stdio.h>

int func();

int func(param)
{
    return param;
}

int main()
{
    int bla = func(10);    
    printf("%d", bla);
}

ทำไมจึงใช้งานได้ ฉันได้ทดสอบมันในคอมไพเลอร์สองสามอันและมันใช้งานได้ดี


77
มันคือ K&R C. เราเขียนโค้ดแบบนี้ในช่วงปี 1980 ก่อนที่จะมีฟังก์ชั่นต้นแบบสมบูรณ์
hughdbrown

6
gcc เตือนด้วย-Wstrict-prototypesทั้งint func()และint main(): xc: 3: คำเตือน: การประกาศฟังก์ชั่นไม่ใช่ต้นแบบ คุณควรประกาศmain()เป็นmain(void)เช่นกัน
Jens

3
@Jens ทำไมคุณถึงแก้ไขคำถาม ดูเหมือนว่าคุณจะพลาดประเด็น ...
dlras2

1
ฉันเพิ่งทำ int ชัดเจนโดยนัย นั่นทำให้พลาดจุดนี้อย่างไร ผมเชื่อว่าจุดคือเหตุผลที่เข้ากันได้กับint func(); int func(arglist) { ... }
Jens

3
@MatsPetersson นี้ผิด C99 5.1.2.2.1 int main(void)ชัดขัดแย้งกับการเรียกร้องและรัฐของคุณว่ารุ่นไม่มีอาร์กิวเมนต์เป็น
เจนส์

คำตอบ:


271

คำตอบอื่น ๆ ทั้งหมดนั้นถูกต้อง แต่เมื่อเสร็จแล้ว

มีการประกาศฟังก์ชันในลักษณะต่อไปนี้:

  return-type function-name(parameter-list,...) { body... }

return-typeเป็นชนิดตัวแปรที่ฟังก์ชันส่งคืน สิ่งนี้ไม่สามารถเป็นประเภทอาเรย์หรือประเภทฟังก์ชั่น หากไม่ได้รับแล้ว int จะสันนิษฐาน

function-nameคือชื่อของฟังก์ชั่น

parameter-listคือรายการพารามิเตอร์ที่ฟังก์ชันใช้คั่นด้วยเครื่องหมายจุลภาค หากไม่ได้รับพารามิเตอร์ฟังก์ชันจะไม่ทำอะไรและควรกำหนดด้วยวงเล็บที่ว่างเปล่าหรือด้วยคำหลักที่เป็นโมฆะ ถ้าไม่มีชนิดตัวแปรที่อยู่ในด้านหน้าของตัวแปรในรายการ paramater แล้ว int จะสันนิษฐาน อาร์เรย์และฟังก์ชั่นจะไม่ถูกส่งไปยังฟังก์ชั่น แต่จะถูกแปลงเป็นพอยน์เตอร์โดยอัตโนมัติ หากรายการถูกยกเลิกด้วยจุดไข่ปลา (, ... ) แสดงว่าไม่มีพารามิเตอร์จำนวนที่กำหนดไว้ หมายเหตุ: ส่วนหัว stdarg.h สามารถใช้เพื่อเข้าถึงอาร์กิวเมนต์เมื่อใช้จุดไข่ปลา

และอีกครั้งเพื่อความสมบูรณ์ จากข้อกำหนด C11 6: 11: 6 (หน้า: 179)

ใช้ declarators ฟังก์ชั่นที่มีวงเล็บที่ว่างเปล่า (ไม่ต้นแบบรูปแบบพารามิเตอร์ชนิด declarators) เป็นคุณลักษณะที่ล้าสมัย


2
"หากไม่มีประเภทตัวแปรที่อยู่ด้านหน้าของตัวแปรในรายการพารามิเตอร์จะมีการสันนิษฐานว่า int" ฉันเห็นสิ่งนี้ในลิงค์ที่คุณให้ แต่ฉันไม่สามารถหาได้ในมาตรฐาน c89, c99 ... คุณสามารถจัดหาแหล่งอื่นได้หรือไม่
godaygo

"หากไม่ได้รับพารามิเตอร์ฟังก์ชั่นจะไม่ทำสิ่งใดและควรกำหนดด้วยวงเล็บที่ว่างเปล่า" ฟังดูขัดแย้งกับคำตอบของ Tony The Lionแต่ฉันเพิ่งรู้ว่าคำตอบของ Tony The Lion นั้นถูกต้องอย่างหนัก
jakun

160

ใน C func()หมายความว่าคุณสามารถผ่านการโต้แย้งจำนวนเท่าใดก็ได้ func(void)หากคุณต้องการการขัดแย้งใดแล้วคุณจะต้องประกาศเป็น intชนิดที่คุณผ่านฟังก์ชั่นของคุณถ้าไม่ได้ระบุค่าเริ่มต้น


3
จริงๆแล้วไม่มีการกำหนดค่าเริ่มต้นให้เป็น int อันที่จริงแล้วค่าเริ่มต้นทั้งหมดเป็น int (แม้แต่ประเภทที่ส่งคืน) มันเป็นการดีที่จะตกลงfunc(42,0x42);(ที่ทุกคนต้องใช้ทั้งสองแบบฟอร์ม args)
Jens

1
ใน C มันเป็นเรื่องธรรมดาสำหรับประเภทที่ไม่ได้ระบุเป็นค่าเริ่มต้นเป็นintเช่นเมื่อคุณประกาศตัวแปร: x ที่ไม่ได้ลงชื่อ ตัวแปร x คืออะไร? มันกลับกลายเป็นint
bitek ที่

4
ฉันอยากจะบอกว่านัย int เป็นเรื่องธรรมดาในสมัยก่อน ไม่แน่นอนอีกต่อไปและใน C99 จะถูกลบออกจาก C
Jens

2
มันอาจจะคุ้มค่าที่จะสังเกตว่าคำตอบนี้นำไปใช้กับฟังก์ชั่นต้นแบบที่มีรายการพารามิเตอร์ที่ว่างเปล่า แต่ไม่ใช่คำจำกัดความของฟังก์ชั่นที่มีรายการพารามิเตอร์ที่ว่างเปล่า
ออทิสติก

@mnemonicflow นั่นไม่ใช่ "การไม่กำหนดประเภทเริ่มต้นเป็น int"; เป็นเพียงชื่อสำหรับประเภทเดียวกับที่อื่นunsigned unsigned int
ฮอบส์

58

int func();เป็นการประกาศฟังก์ชั่นที่ล้าสมัยจากวันที่ไม่มีมาตรฐาน C คือวันของK&R C (ก่อนปี 1989 ปีที่เผยแพร่มาตรฐาน "ANSI C" ครั้งแรก)

โปรดจำไว้ว่าไม่มีต้นแบบใน K&R Cและคำหลักvoidยังไม่ได้ประดิษฐ์ สิ่งที่คุณทำได้คือบอกคอมไพเลอร์เกี่ยวกับประเภทการคืนของฟังก์ชัน รายการพารามิเตอร์ที่ว่างเปล่าใน K&R C หมายถึงจำนวนอาร์กิวเมนต์ที่ "ไม่ระบุ แต่คงที่" หมายความว่าคุณต้องเรียกใช้ฟังก์ชั่นที่มีความคงที่เดียวกันจำนวน args แต่ละครั้ง (เมื่อเทียบกับvariadicฟังก์ชั่นเหมือนprintfที่จำนวนและชนิดสามารถแตกต่างกันสำหรับการโทรแต่ละ)

คอมไพเลอร์หลายคนจะวินิจฉัยโครงสร้างนี้ โดยเฉพาะอย่างยิ่งgcc -Wstrict-prototypesจะบอกคุณว่า "การประกาศฟังก์ชั่นไม่ใช่ต้นแบบ" ซึ่งเป็นจุดเพราะมันดูเหมือนต้นแบบ (โดยเฉพาะถ้าคุณถูกวางยาพิษด้วย C ++!) แต่ไม่ใช่ เป็นการประกาศประเภทการส่งคืน K&R แบบเก่า

Rule of thumb:อย่าปล่อยให้รายการพารามิเตอร์ว่างเปล่าว่างเปล่าใช้int func(void)เฉพาะเจาะจง สิ่งนี้เปลี่ยน K&R return type type เป็น C89 ต้นแบบที่เหมาะสม คอมไพเลอร์มีความสุขนักพัฒนามีความสุขตัวตรวจสอบแบบคงที่มีความสุข ผู้ที่เข้าใจผิดโดย ^ W ^ Wfond ของ C ++ อาจประจบประแจงเพราะพวกเขาจำเป็นต้องพิมพ์อักขระพิเศษเมื่อพวกเขาพยายามฝึกทักษะภาษาต่างประเทศ :-)


1
โปรดอย่าเชื่อมโยงสิ่งนี้กับ C ++ เป็นเรื่องธรรมดาที่รายการอาร์กิวเมนต์ที่ว่างเปล่าหมายถึงไม่มีพารามิเตอร์และผู้คนในโลกไม่สนใจที่จะจัดการกับข้อผิดพลาดที่เกิดขึ้นจากกลุ่ม K&R เมื่อ 40 ปีก่อน แต่คณะกรรมการผู้ชำนาญการยังคงลากตัวเลือกที่ขัดแย้งกันตามมา - ใน C99, C11
pfalcon

1
@ pfalcon สามัญสำนึกค่อนข้างเป็นส่วนตัว สิ่งที่สามัญสำนึกของคนคนหนึ่งคือความวิกลจริตธรรมดาต่อผู้อื่น โปรแกรมเมอร์มืออาชีพ C รู้ว่ารายการพารามิเตอร์ที่ว่างเปล่าบ่งบอกถึงจำนวนอาร์กิวเมนต์ที่ไม่ระบุ แต่คงที่ การเปลี่ยนแปลงที่อาจทำลายการใช้งานหลายอย่าง การกล่าวโทษคณะกรรมการเพื่อหลีกเลี่ยงการเปลี่ยนแปลงเงียบ ๆ ทำให้เห่าต้นไม้ที่ไม่ถูกต้อง IMHO
เจนส์

53
  • รายการพารามิเตอร์ที่ว่างเปล่าหมายถึง "ข้อโต้แย้งใด ๆ " ดังนั้นคำนิยามไม่ผิด
  • intชนิดที่หายไปจะถือว่าเป็น

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


30

มันคือการประกาศฟังก์ชันและนิยามสไตล์K&R จาก C99 มาตรฐาน (ISO / IEC 9899: TC3)

มาตรา 6.7.5.3 Declarators ฟังก์ชั่น (รวมถึงต้นแบบ)

รายการตัวระบุประกาศเพียงตัวระบุของพารามิเตอร์ของฟังก์ชั่น รายการว่างในตัวประกาศฟังก์ชันที่เป็นส่วนหนึ่งของนิยามของฟังก์ชันนั้นระบุว่าฟังก์ชันนั้นไม่มีพารามิเตอร์ รายการว่างในตัวประกาศฟังก์ชันที่ไม่ได้เป็นส่วนหนึ่งของนิยามของฟังก์ชันนั้นระบุว่าไม่มีข้อมูลเกี่ยวกับจำนวนหรือชนิดของพารามิเตอร์ (หากทั้งสองประเภทฟังก์ชั่นเป็น "รูปแบบเก่า" ประเภทพารามิเตอร์จะไม่ถูกเปรียบเทียบ)

ส่วนที่ 6.11.6 ฟังก์ชันการประกาศ

การใช้งานตัวประกาศฟังก์ชันที่มีวงเล็บว่างเปล่า (ไม่ใช่ตัวประกาศประเภทพารามิเตอร์รูปแบบต้นแบบ) เป็นคุณสมบัติที่ล้าสมัย

ส่วนที่ 6.11.7 นิยามฟังก์ชั่น

การใช้นิยามฟังก์ชันที่มีตัวระบุพารามิเตอร์แยกต่างหากและรายการการประกาศ (ไม่ใช่ประเภทพารามิเตอร์รูปแบบต้นแบบและการประกาศตัวระบุ) เป็นคุณลักษณะที่ล้าสมัย

ซึ่งรูปแบบเดิมหมายความว่าK & Rสไตล์

ตัวอย่าง:

ประกาศ: int old_style();

ความหมาย:

int old_style(a, b)
    int a; 
    int b;
{
     /* something to do */
}

16

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

นิยามฟังก์ชั่นมีลักษณะเช่นนี้

int func(int param) { /* body */}

หากต้นแบบของมันคุณเขียน

int func(int param);

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

int func(int);

นอกจากนี้หากคุณไม่ระบุประเภทพารามิเตอร์ แต่ชื่อintจะถือว่าเป็นประเภท

int func(param);

หากคุณไปได้ไกลขึ้น

func();

คอมไพเลอร์จะถือว่าเมื่อคุณเขียนint func() func()แต่อย่าใส่func()เข้าไปในร่างกายของฟังก์ชั่น นั่นจะเป็นการเรียกใช้ฟังก์ชัน


3
รายการพารามิเตอร์ที่ว่างเปล่าไม่เกี่ยวข้องกับชนิด int โดยนัย ไม่ได้เป็นรูปแบบโดยนัยของint func() int func(int)
John Bartholomew

11

ตามที่ระบุไว้ @Krishnabhadra คำตอบก่อนหน้านี้ทั้งหมดจากผู้ใช้รายอื่นมีการตีความที่ถูกต้องและฉันต้องการทำการวิเคราะห์อย่างละเอียดมากขึ้นในบางประเด็น

ใน Old-C เช่นเดียวกับ ANSI-C " พารามิเตอร์แบบไม่พิมพ์ " ใช้ส่วนของการลงทะเบียนงานหรือความสามารถเชิงลึกของคำสั่งของคุณ (ลงทะเบียนเงาหรือวงจรสะสมคำสั่ง) ใน 8bit MPU จะเป็น int16 ใน 16 บิต MPU และอื่น ๆ จะเป็น int16 เป็นต้นในกรณีที่สถาปัตยกรรม 64 บิตอาจเลือกที่จะรวบรวมตัวเลือกเช่น: -m32

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

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

แต่ควรสังเกตว่าคอมไพเลอร์ที่ทันสมัยที่สุดไม่ทำให้ความแตกต่างระหว่างการประกาศพารามิเตอร์ทั้งสองประเภท

ตัวอย่างของการคอมไพล์ด้วย gcc ภายใต้ linux:

main.c

main2.c

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

แบบนี้:

int myfunc(int param);

5
ฉันใช้ปัญหาในการปรับภาพให้มีขนาดเป็นไบต์ของภาพ ฉันคิดว่ารูปภาพสามารถรับมุมมองอย่างรวดเร็วเกี่ยวกับการขาดความแตกต่างในโค้ดที่สร้างขึ้น ฉันได้ทำการทดสอบโค้ดแล้วสร้างเอกสารจริงของสิ่งที่มันอ้างและไม่ใช่แค่สร้างทฤษฎีเกี่ยวกับปัญหา แต่ไม่ใช่ทุกคนที่เห็นโลกในลักษณะเดียวกัน ฉันเสียใจอย่างยิ่งที่ความพยายามของฉันในการให้ข้อมูลเพิ่มเติมแก่ชุมชนเพื่อรบกวนคุณเป็นอย่างมาก
RTOSkit

1
ฉันค่อนข้างแน่ใจว่าประเภทผลตอบแทนที่ไม่ระบุเป็นเสมอintซึ่งโดยทั่วไปจะเป็นขนาดทะเบียนงานหรือ 16 บิตแล้วแต่จำนวนใดจะน้อยกว่า
supercat

@supercat +1 การหักที่สมบูรณ์แบบคุณพูดถูก! นี่คือสิ่งที่ฉันพูดถึงข้างต้นคอมไพเลอร์ที่ออกแบบโดยค่าเริ่มต้นสำหรับสถาปัตยกรรมระบุมักสะท้อนขนาดของการลงทะเบียนการทำงานของ CPU / MPU ในคำถามดังนั้นในสภาพแวดล้อมแบบฝังตัวมีกลยุทธ์การพิมพ์ซ้ำหลายครั้งบน เรียลไทม์ OS, เป็นคอมไพเลอร์เลเยอร์ (stdint.h) หรือเป็นเลเยอร์พกพาที่ทำให้พกพาระบบปฏิบัติการเดียวกันในหลาย ๆ arquitectures และได้รับโดยการจัดประเภทเฉพาะประเภท CPU / MPU (int ยาวยาว ฯลฯ ) ด้วยประเภทระบบทั่วไป u8, u16, u32
RTOSkit

@supercat หากไม่มีประเภทการควบคุมที่นำเสนอโดยระบบปฏิบัติการหรือคอมไพเลอร์เฉพาะคุณต้องมีเวลาในการพัฒนาเล็กน้อยและคุณทำให้ "การมอบหมายที่ไม่มีการกำหนด" ทั้งหมดสอดคล้องกับการออกแบบแอปพลิเคชันของคุณก่อนที่จะประหลาดใจในการค้นหา " 16 บิต int "และไม่ใช่" 32 บิต int "
RTOSkit

@RTOSkit: คำตอบของคุณแนะนำว่าชนิดเริ่มต้นของโปรเซสเซอร์ 8 บิตจะเป็น Int8 ฉันจำคอมไพเลอร์ C-ish สองตัวสำหรับสถาปัตยกรรมแบรนด์ PICmicro ซึ่งเป็นกรณีนี้ แต่ฉันไม่คิดว่าจะมีอะไรคล้ายกับมาตรฐาน C แบบระยะไกลที่เคยอนุญาตให้intพิมพ์ซึ่งไม่สามารถถือค่าทั้งหมดในช่วงได้ - 32767 ถึง +32767 (ไม่จำเป็นต้องทราบ -32768) และยังสามารถเก็บcharค่าได้ทั้งหมด(หมายความว่าถ้าcharเป็น 16 บิตต้องลงนามหรือintจะต้องใหญ่กว่า)
supercat

5

เกี่ยวกับประเภทพารามิเตอร์มีคำตอบที่ถูกต้องอยู่แล้วที่นี่ แต่ถ้าคุณต้องการฟังจากคอมไพเลอร์คุณสามารถลองเพิ่มแฟล็ก (แฟล็กมักจะเป็นความคิดที่ดีเสมอ)

รวบรวมโปรแกรมของคุณโดยใช้gcc foo.c -Wextraฉันได้รับ:

foo.c: In function func’:
foo.c:5:5: warning: type of param defaults to int [-Wmissing-parameter-type]

แปลก-Wextraไม่จับสิ่งนี้สำหรับclang(มันไม่รู้จัก-Wmissing-parameter-typeด้วยเหตุผลบางอย่างบางทีสำหรับคนในประวัติศาสตร์ที่กล่าวถึงข้างต้น) แต่-pedanticไม่:

foo.c:5:10: warning: parameter 'param' was not declared, 
defaulting to type 'int' [-pedantic]
int func(param)
         ^
1 warning generated.

และสำหรับปัญหาต้นแบบดังกล่าวข้างต้นอีกครั้งint func()อ้างถึงพารามิเตอร์โดยพลการเว้นแต่คุณจะกำหนดอย่างรวดเร็วint func(void)ซึ่งจะทำให้คุณมีข้อผิดพลาดตามที่คาดไว้:

foo.c: In function func’:
foo.c:6:1: error: number of arguments doesnt match prototype
foo.c:3:5: error: prototype declaration
foo.c: In function main’:
foo.c:12:5: error: too many arguments to function func
foo.c:5:5: note: declared here

หรือclangเป็น:

foo.c:5:5: error: conflicting types for 'func'
int func(param)
    ^
foo.c:3:5: note: previous declaration is here
int func(void);
    ^
foo.c:12:20: error: too many arguments to function call, expected 0, have 1
    int bla = func(10);
              ~~~~ ^~
foo.c:3:1: note: 'func' declared here
int func(void);
^
2 errors generated.

3

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

int func(void);

1
"ถ้าต้นแบบฟังก์ชั่นไม่มีพารามิเตอร์"นั่นไม่ใช่ฟังก์ชั่นต้นแบบเพียงแค่การประกาศฟังก์ชั่น
ผล

@effeffe แก้ไขแล้วว่า ฉันไม่ได้ตระหนักถึงคำถามนี้จะได้รับความสนใจมาก)
PP

3
ไม่ใช่ "ต้นแบบฟังก์ชัน" เป็นเพียงนิพจน์ทางเลือก (อาจเป็นแบบเก่า) สำหรับ "การประกาศฟังก์ชัน" หรือไม่
Giorgio

@Giorgio IMO ทั้งสองถูกต้อง "function prototype" ควรตรงกับ "function definition" ฉันอาจคิดว่า effeffe หมายถึงการประกาศคำถามและสิ่งที่ฉันหมายถึงคือคำตอบของฉัน
PP

@Giorgio no การประกาศฟังก์ชันถูกสร้างโดยค่าชนิดส่งคืนตัวระบุและรายการพารามิเตอร์ทางเลือก ฟังก์ชั่นต้นแบบคือการประกาศฟังก์ชั่นที่มีรายการพารามิเตอร์
บังคับใช้

0

นี่คือเหตุผลที่ฉันมักจะแนะนำให้ผู้คนรวบรวมรหัสของพวกเขาด้วย:

cc -Wmissing-variable-declarations -Wstrict-variable-declarations -Wold-style-definition

ธงเหล่านี้บังคับใช้สองสิ่ง:

  • -Wmissing-variable-declarations: มันเป็นไปไม่ได้ที่จะประกาศฟังก์ชั่นที่ไม่คงที่โดยไม่ได้รับต้นแบบก่อน สิ่งนี้ทำให้มีโอกาสมากขึ้นที่ต้นแบบในไฟล์ส่วนหัวจะตรงกับคำจำกัดความที่แท้จริง อีกทางหนึ่งคือบังคับให้คุณเพิ่มคำหลักคงที่ในฟังก์ชั่นที่ไม่จำเป็นต้องเปิดเผยต่อสาธารณะ
  • -Wstrict-variable-declarations: ต้นแบบต้องแสดงรายการอาร์กิวเมนต์อย่างถูกต้อง
  • -Wold-style-definition: นิยามฟังก์ชั่นของตัวเองจะต้องมีรายการอาร์กิวเมนต์อย่างถูกต้อง

การตั้งค่าสถานะเหล่านี้ถูกใช้เป็นค่าเริ่มต้นในโครงการโอเพนซอร์สจำนวนมาก ตัวอย่างเช่น FreeBSD เปิดใช้งานการตั้งค่าสถานะเหล่านี้เมื่อสร้างด้วย WARNS = 6 ใน Makefile ของคุณ

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