เหตุใด C ประเภทโมฆะจึงไม่คล้ายกับประเภทที่ว่าง / ด้านล่าง


28

Wikipedia ตลอดจนแหล่งข้อมูลอื่น ๆ ที่ฉันได้พบรายการvoidประเภทC เป็นหน่วยประเภทซึ่งตรงข้ามกับประเภทที่ว่างเปล่า ฉันพบว่ามันสับสนเพราะฉันคิดว่าvoidเหมาะกับนิยามของประเภทที่ว่าง / ล่าง

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

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

ในทางกลับกันvoidตัวมันเองไม่ใช่ประเภทย่อยของประเภทอื่นทั้งหมดซึ่งเท่าที่ฉันสามารถบอกได้ว่าเป็นข้อกำหนดสำหรับประเภทที่จะเป็นประเภทด้านล่าง


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

2
ในฐานะที่เป็นชนิดส่งคืนเป็นโมฆะเป็นประเภทหน่วย
253751

คำตอบ:


38

ใน C voidใช้สำหรับสิ่งที่ไม่เกี่ยวข้องหลายอย่าง ขึ้นอยู่กับสิ่งที่ใช้สำหรับความหมายของมันอาจเป็นประเภทของหน่วยประเภทที่ว่างเปล่าหรืออย่างอื่น

เมื่อvoidมีการใช้งานด้วยตัวเอง (ตรงข้ามกับvoid*ตัวชี้เป็นโมฆะ) มันเป็นประเภทหน่วยคือประเภทที่มีค่าเดียว ฟังก์ชั่นที่ส่งคืนvoidจะถูกกล่าวว่า“ ไม่คืนสิ่งใด” แต่สิ่งนี้หมายถึงอย่างแท้จริงว่าพวกเขาจะไม่ส่งคืนข้อมูล พวกเขาส่งกลับข้อมูลบิตซึ่งหมายความว่าพวกเขาคืนค่าประเภทที่มีค่าที่แตกต่างคือประเภทหน่วย020=1

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

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

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


หนึ่งสามารถส่งคืนโมฆะใน C ++ และ C89 stackoverflow.com/questions/35987493/…
BartekChom

2
ย่อหน้าที่ 4 ผิดอย่างเป็นทางการ ใน C จำนวนหน่วยเก็บข้อมูลสำหรับvoidไม่ได้กำหนดไม่ใช่ศูนย์ นี่ไม่ใช่เหตุผลว่าทำไมวัตถุประเภทvoidไม่ได้รับอนุญาต เหตุผลที่เป็นทางการคือvoidเป็นประเภทที่ไม่สมบูรณ์และวัตถุไม่สามารถมีชนิดไม่สมบูรณ์
MSalters

4
@MSalters ไม่สิ่งที่ฉันเขียนถูกต้องเป็นทางการ “ เพราะ” หมายถึงแรงจูงใจในการออกแบบภาษาไม่ใช่การอ้างถึงแบบลอจิคัลภายในข้อกำหนดภาษา voidประเภทต้อง 0 บิตของการจัดเก็บ นี่คือเหตุผลว่าทำไมนักออกแบบของ C ตัดสินใจที่จะทำvoidชนิดที่ไม่สมบูรณ์เมื่อเทียบกับการกำหนดว่ามันใช้พื้นที่จัดเก็บ 0 ไบต์ (ซึ่งจะมีผลกระทบอย่างมากต่อการออกแบบภาษา) หรือ 1 ไบต์ของพื้นที่จัดเก็บ .
Gilles 'SO- หยุดความชั่วร้าย'

1
@Gilles: ขออภัย แต่นั่นก็ไม่สมเหตุสมผลเช่นกัน หากได้รับอนุญาตพื้นที่ที่ใช้จะเป็น 1 ไบต์ต่อวัตถุประเภทโมฆะและแน่นอนว่าคุณไม่จำเป็นต้องใช้วัตถุหลายvoidประเภท ไม่ต้องพูดถึงว่าวัตถุเหล่านี้สามารถใช้แทนวัตถุอื่นทั้งหมดดังนั้นการใช้งานจริงจะเป็นศูนย์อยู่แล้ว
MSalters

4
@CodesInChaos: ดี, C ++ จริงช่วยให้ structs struct E { };ว่างคือ เมื่อใช้เป็นคลาสพื้นฐานสิ่งนี้อาจมีขนาดเป็นศูนย์ (ไม่มีจริง ๆ เช่น C / C ++ ทั้งสองภาษาให้เลือกของตัวเองและพวกเขาสามารถแตกต่างกันในพื้นที่เหล่านี้ C แน่นอนไม่มีชั้นฐานที่ว่างเปล่าเนื่องจากไม่มี OO ในตอนแรก)
MSalters

11

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

นี่หมายถึงฟังก์ชั่นที่ประเภทผลลัพธ์ไม่สามารถยกเลิกได้ หากมันยุติลงถ้าจะต้องส่งคืนค่าของแต่ดีค่าดังกล่าวไม่ได้อยู่

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

ในขณะที่ฟังก์ชั่น C ที่มี“ return type” สามารถส่งคืนvoidได้อย่างชัดเจนแต่ไม่ได้ให้ข้อมูลใด ๆ ในค่าส่งคืน นั่นคือลักษณะที่แม่นยำของประเภทหน่วย: ค่าของมันไม่มีข้อมูลใด ๆ เพราะมีเพียงค่าเดียว (ดังนั้นคุณสามารถบอกได้เสมอว่าค่าตอบแทนจะเป็นอย่างไรแม้ว่าจะไม่รบกวนการเรียกฟังก์ชัน)

ในการอ้างอิง Conor McBride (ทับศัพท์เป็น C):

voidหมายถึง "Boring" มันหมายถึงประเภทที่น่าเบื่อที่มีสิ่งหนึ่งที่น่าเบื่อ ไม่มีอะไรน่าสนใจที่จะได้รับจากการเปรียบเทียบองค์ประกอบหนึ่งของประเภทที่น่าเบื่อกับอีกองค์ประกอบหนึ่งเนื่องจากไม่มีอะไรที่จะเรียนรู้เกี่ยวกับองค์ประกอบของประเภทที่น่าเบื่อโดยให้ความสนใจของคุณ

มันแตกต่างจากประเภทที่ว่างเปล่า [... ] ประเภทที่ว่างเปล่านั้นน่าตื่นเต้นมากเพราะถ้าใครบางคนให้คุณค่ากับมันคุณจะรู้ว่าคุณตายไปแล้วและในสวรรค์และทุกสิ่งที่คุณต้องการคือของคุณ


ที่น่าสนใจ; ถ้านิยามของ⊥เป็นฟังก์ชันที่ชนิดส่งคืนคือ⊥ไม่สามารถยุติได้ C จะมีชนิดดังกล่าว เราเรียกมันว่าโมฆะระเหย
Joshua

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