มีความแตกต่างระหว่าง foo (void) และ foo () ใน C ++ หรือ C หรือไม่


253

พิจารณานิยามฟังก์ชันทั้งสองนี้:

void foo() { }

void foo(void) { }

มีความแตกต่างระหว่างสองคนนี้ไหม? ถ้าไม่เป็นเช่นนั้นทำไมจึงมีการvoidโต้แย้ง? เหตุผลด้านความงาม?


สำหรับ C คำถาม / คำตอบอยู่ที่นี่
Antti Haapala

คำตอบ:


317

ในC :

  • void foo()หมายถึง "ฟังก์ชั่นที่fooรับจำนวนอาร์กิวเมนต์ที่ไม่ระบุชนิดที่ไม่ระบุ"
  • void foo(void)หมายถึง "ฟังก์ชั่นที่fooไม่มีข้อโต้แย้ง"

ในC ++ :

  • void foo()หมายถึง "ฟังก์ชั่นที่fooไม่มีข้อโต้แย้ง"
  • void foo(void)หมายถึง "ฟังก์ชั่นที่fooไม่มีข้อโต้แย้ง"

โดยการเขียนfoo(void)ดังนั้นเราบรรลุความหมายเดียวกันในทั้งสองภาษาและทำให้ส่วนหัวของเราพูดได้หลายภาษา (แม้ว่าเรามักจะต้องทำบางสิ่งบางอย่างมากขึ้นในส่วนหัวจะทำให้พวกเขาอย่างแท้จริงข้ามภาษา ได้แก่ ห่อไว้ในextern "C"ถ้าเรารวบรวมกำลัง C ++)


10
แต่ถ้า C ++ จำเป็นต้องใช้voidมันจะสามารถหลีกเลี่ยงปัญหา "การทำให้กระจ่างที่สุด" ได้
Adrian McCarthy

5
จริง แต่มีเสี้ยวเส็งเคร็งอื่น ๆ อีกมากมายใน C ++ ไม่มีจุดจริงในการตรวจสอบเกี่ยวกับหนึ่งในนั้น
DrPizza

16
สำหรับคำถามล่าสุด @James Kanze โพสต์ชิ้นอาหารอันโอชะที่น่าสนใจ โพสต์ใหม่ที่นี่เพื่อหลีกเลี่ยงการสูญเสีย: เวอร์ชันแรกของ C ไม่อนุญาตให้ระบุจำนวนพารามิเตอร์ที่ฟังก์ชันอาจใช้จึงvoid foo()เป็นเพียงไวยากรณ์เดียวที่ประกาศฟังก์ชัน เมื่อมีลายเซ็นที่แนะนำคณะกรรมการ C จะต้องทำให้กระจ่างไม่มีพารามิเตอร์จากไวยากรณ์เก่าและแนะนำvoid foo(void)ไวยากรณ์ C ++ ใช้เพื่อความเข้ากันได้
Matthieu M.

3
คุณช่วยยกตัวอย่าง C C90 และรุ่นที่ใหม่กว่าที่ใช้void foo()แทนvoid foo(void)จะสร้างความแตกต่างในการทำงาน คือฉันเคยใช้เวอร์ชั่นโดยไม่มีช่องว่างเป็นเวลาหลายปีและไม่เห็นปัญหาใด ๆ ฉันขาดอะไรไปหรือเปล่า?
chacham15

6
@ chacham15 void foo() { if ( rand() ) foo(5); } รวบรวมและเรียกใช้ (ก่อให้เกิดพฤติกรรมที่ไม่ได้กำหนดเว้นแต่ว่าคุณโชคดีมาก) ในขณะvoid foo(void)ที่เนื้อหาเดียวกันจะทำให้เกิดข้อผิดพลาดในการรวบรวม
MM

39

ฉันรู้ว่าคำถามของคุณเกี่ยวข้องกับ C ++ แต่เมื่อพูดถึง C คำตอบสามารถพบได้ใน K&R หน้า 72-73:

นอกจากนี้หากการประกาศฟังก์ชั่นไม่รวมถึงข้อโต้แย้งตามที่

double atof();

นั่นก็หมายความว่าไม่มีอะไรที่จะต้องคิดเรื่องการโต้เถียงของ atof; การตรวจสอบพารามิเตอร์ทั้งหมดถูกปิด ความหมายพิเศษของรายการอาร์กิวเมนต์ว่างนี้มีวัตถุประสงค์เพื่ออนุญาตให้โปรแกรม C รุ่นเก่าคอมไพล์ด้วยคอมไพเลอร์ใหม่ แต่มันเป็นความคิดที่ดีที่จะใช้กับโปรแกรมใหม่ หากฟังก์ชันรับอาร์กิวเมนต์ให้ประกาศ; หากไม่มีข้อโต้แย้งให้ใช้โมฆะ


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

9

ร่างมาตรฐาน C ++ 11 N3337

ไม่มีความแตกต่าง

http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2012/n3337.pdf

ภาคผนวก C "ความเข้ากันได้" C.1.7 ข้อ 8: ผู้ประกาศบอกว่า:

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

ตัวอย่าง:

int f();
// means int f(void) in C ++
// int f( unknown ) in C

เหตุผล: เพื่อหลีกเลี่ยงการเรียกใช้ฟังก์ชันที่ผิดพลาด (เช่นการเรียกใช้ฟังก์ชันที่มีหมายเลขหรือประเภทของอาร์กิวเมนต์ที่ไม่ถูกต้อง)

ผลต่อคุณสมบัติดั้งเดิม: เปลี่ยนความหมายของคุณสมบัติที่กำหนดไว้อย่างดี สถานที่นี้ถูกทำเครื่องหมายว่า "ล้าสมัย" ใน C

ฟังก์ชั่น 8.5.3พูดว่า:

4. พารามิเตอร์-declaration-clause กำหนดอาร์กิวเมนต์ที่สามารถระบุได้และการประมวลผลของมันเมื่อเรียกใช้ฟังก์ชัน [... ] หาก parameter-declaration-clause ว่างเปล่าฟังก์ชันจะไม่มีข้อโต้แย้ง รายการพารามิเตอร์ (void) เทียบเท่ากับรายการพารามิเตอร์เปล่า

C99

ตามที่กล่าวไว้โดย C ++ 11 ไม่ได้int f()ระบุอะไรเกี่ยวกับข้อโต้แย้งและล้าสมัย

มันสามารถนำไปสู่รหัสการทำงานหรือ UB

ฉันได้ตีความรายละเอียดมาตรฐาน C99 ที่: https://stackoverflow.com/a/36292431/895245


2

ใน C คุณใช้ช่องว่างในการอ้างอิงฟังก์ชันว่างเพื่อให้คอมไพเลอร์มีต้นแบบและต้นแบบนั้นไม่มี "อาร์กิวเมนต์" ใน C ++ คุณไม่ต้องบอกคอมไพเลอร์ว่าคุณมีต้นแบบเพราะคุณไม่สามารถออกจากต้นแบบได้


1
"ต้น" หมายถึงการประกาศรายการอาร์กิวเมนต์และประเภทผลตอบแทน ฉันพูดแบบนี้เพราะ "ต้นแบบ" ทำให้ฉันสับสนในสิ่งที่คุณหมายถึงตอนแรก
Zan Lynx
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.