“ int main (vooid)”? ทำงานอย่างไร?


135

เมื่อเร็ว ๆ นี้ฉันต้องพิมพ์โปรแกรมทดสอบ C ขนาดเล็กและในกระบวนการนี้ฉันได้สะกดคำผิดในฟังก์ชันหลักโดยบังเอิญใช้vooidแทนvoid.

แต่มันก็ยังใช้งานได้

การลดลงเป็นเวอร์ชันสมบูรณ์ที่เล็กที่สุดฉันลงเอยด้วย:

int main (vooid) {
    return 42;
}

นี้ไม่แน่นอนรวบรวม ( gcc -Wall -o myprog myprog.c) และเมื่อทำงานก็จะส่งกลับ 42

รหัสนี้ถูกต้องแค่ไหน?


นี่คือการถอดเสียงและวางจากbashเชลล์ของฉันเพื่อแสดงสิ่งที่ฉันกำลังทำ:

pax$ cat qq.c
int main (vooid) {
    return 42;
}

pax$ rm qq ; gcc -Wall -o qq qq.c ; ./qq

pax$ echo $?
42

โดยการกำหนดหลักเดียวกับintพารามิเตอร์คุณเรียกพฤติกรรมที่ไม่ได้กำหนด อะไรก็เกิดขึ้นได้ :)
pmg

9
อันที่จริงฉันไม่แน่ใจเกี่ยวกับ UB, @pmg ISO ช่วยโดยเฉพาะสำหรับความเป็นไปได้อื่น ๆmainจากมาตรฐานสองมาตรฐาน สำหรับการพกพาคุณควรใช้หนึ่งในสองอย่างนี้ แต่ฉันไม่คิดว่า UB ใช้ที่นี่
paxdiablo

อืม: ในสภาพแวดล้อมที่โฮสต์mainจะต้องมีรูปแบบที่ยอมรับหนึ่งใน 2 รูปแบบ (2.1.2.2) แต่คุณใช่ @pax ในสภาพแวดล้อมแบบอิสระตัวระบุmainไม่ได้มีลักษณะพิเศษหากใช้เป็นฟังก์ชันอาจเป็นประเภทใดก็ได้และมีพารามิเตอร์กี่ประเภทก็ได้
pmg

2
ใน C99 มีการกำหนดการใช้งานอิสระโดยสิ้นเชิง สำหรับการเป็นเจ้าภาพส่วน 5.1.2.2.1 รัฐที่สิ้นสุด "หรือในบางลักษณะการดำเนินงานอื่น ๆ ที่กำหนดไว้" จึงต้องใช้อย่างน้อยทั้งสองรูปแบบที่เป็นที่ยอมรับ แต่จะมีคนอื่น ๆ เช่นกัน (นี้จะช่วยให้ UNIXy int main (int argc, char *argv[], char *envp[]);จะต้องสอดคล้อง ).
paxdiablo

คำตอบ:


220

เพียงแค่ใช้ไวยากรณ์การประกาศฟังก์ชัน "แบบเก่า" คุณกำลังประกาศintพารามิเตอร์ที่เรียกว่าvooid.


2
ดูเหมือนว่าจะเป็นเช่นนั้น หากคุณเพิ่ม "vooid = 42; return vooid;" ไปที่ main คุณจะได้รับผลตอบแทน 42 ด้วย
Jeff Ames

43
Aargghh คุณพูดถูก ถ้าฉันจะเพิ่มที่ฉันได้รับ-std=c99 qq.c:1: warning: type of 'vooid' defaults to 'int'
paxdiablo

70

เป็นรหัสที่ถูกต้องเนื่องจาก myprog.c มี:

int main (vooid) // vooid is of type int, allowed, and an alias for argc
{     
  return 42; // The answer to the Ultimate Question
} 

vooidมีหนึ่งบวกจำนวนอาร์กิวเมนต์ที่ส่งผ่าน (เช่นargc) ดังนั้นในผลทั้งหมดที่คุณทำคือการเปลี่ยนชื่อไปargcvooid


11
ถ้าคุณทำ "return vooid;" แทนที่จะให้ 1 + num ของ args
Jeff Ames

6
@ เจฟฟ์ชื่อของรายการจะถูกนับเป็นข้อโต้แย้งดังนั้นจึง +1
Martin Beckett

23

ใน C intประเภทเริ่มต้นสำหรับอาร์กิวเมนต์ฟังก์ชั่นคือ ดังนั้นโปรแกรมของคุณจึงใช้คำว่าvooidas int main(int vooid)ซึ่งเป็นรหัสที่ถูกต้องอย่างสมบูรณ์


20

เป็นเพียงgcc -std=c89 -Wall -o qq qq.cและgcc -std=gnu89 -Wall -o qq qq.cไม่ส่งเสียงเตือน ทุกมาตรฐานอื่น ๆ ที่ปล่อยออกมาเตือนเกี่ยวกับประเภทนัยสำหรับintvooid

int main(chart)int main (vooid)ทำงานในลักษณะเดียวกันเช่นเดียวกับ

return vooid; ส่งคืนจำนวนอาร์กิวเมนต์บรรทัดคำสั่ง

ฉันทดสอบด้วย gcc 4.4.5 บนระบบทดสอบ Debian

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