Tại sao loại khoảng trống của C không giống với loại trống / đáy?


28

Wikipedia cũng như các nguồn khác mà tôi đã tìm thấy voidloại C là một loại đơn vị trái ngược với loại trống. Tôi thấy điều này khó hiểu vì dường như với tôi voidphù hợp hơn với định nghĩa về loại trống / đáy.

  • Không có giá trị cư trú void, như tôi có thể nói.
  • Hàm có kiểu void return xác định rằng hàm không trả về bất cứ thứ gì và do đó chỉ có thể thực hiện một số hiệu ứng phụ.
  • Một con trỏ kiểu void*là một kiểu con của tất cả các loại con trỏ khác. Ngoài ra, chuyển đổi đến và từ void*trong C là ẩn.

Tôi không chắc chắn nếu điểm cuối cùng có bất kỳ giá trị nào như là một đối số cho voidviệc là một loại trống, void*ít nhiều là một trường hợp đặc biệt không liên quan nhiều đến void.

Mặt khác, voidbản thân nó không phải là một kiểu con của tất cả các loại khác, mà theo như tôi có thể nói là một yêu cầu cho một loại phải là loại dưới cùng.


10
Bởi "không trả lại bất cứ thứ gì" mà bạn thực sự có nghĩa là "không trả lại bất cứ thứ gì quan tâm", trong khi đó một hàm có đầu ra trống hoàn toàn không trả về (nghĩa là sự cố hoặc vòng lặp vô hạn).
Turion

2
Là một loại trả về, void là một loại đơn vị.
user253751

Câu trả lời:


38

Trong C, voidđược sử dụng cho nhiều thứ không liên quan. Tùy thuộc vào mục đích sử dụng của nó, ý nghĩa của nó có thể là một loại đơn vị, một loại trống hoặc một cái gì đó khác.

Khi voidđược sử dụng bởi chính nó (trái ngược với void*, một con trỏ để trống), đó là một loại đơn vị, tức là một loại có một giá trị duy nhất. Các chức năng trả về voidđược cho là không trả về bất cứ thứ gì, nhưng điều này thực sự có nghĩa là chúng không trả về bất kỳ thông tin nào. Chúng trả về bit thông tin, có nghĩa là chúng trả về một giá trị của một loại có chứa giá trị riêng biệt, tức là một loại đơn vị.2 0 = 1020= =1

Đây không phải là loại trống: một hàm trả về loại trống không thể trả về giá trị, vì không có giá trị của loại đó. Một hàm có kiểu trả về trống chỉ có thể lặp mãi mãi hoặc hủy bỏ chương trình hoặc đưa ra một ngoại lệ ( longjmp) hoặc nếu không thì sắp xếp không trả về, ví dụ bằng cách chuyển điều khiển sang luồng khác hoặc xử lý bằng chức năng ngoài C tiêu chuẩn). Để giữ cho mọi thứ khó hiểu, người ta thường sử dụng C voidthay cho loại trống (C không có loại trống).

Các voidloại đòi hỏi bit dung lượng lưu trữ. Vì C khăng khăng mọi đối tượng chiếm toàn bộ, số lượng byte lưu trữ khác nhau, nên không được phép tạo một đối tượng kiểu và có một cú pháp đặc biệt để trả về giá trị (một câu lệnh bị bỏ qua giá trị). Không có cú pháp nào mang lại giá trị của loại , nhưng giá trị đó tồn tại bất cứ khi nào một hàm có kiểu trả về được trả về.0voidvoidreturnvoidvoid

C không có loại dưới cùng theo nghĩa cho phép bất kỳ loại có thể. Ngay cả các loại không đầy đủ xác định bản chất chung của các giá trị của nó, ví dụ con trỏ hoặc cấu trúc hoặc công đoàn hoặc hàm. Nhưng void*là một con trỏ tới bất kỳ loại phi hàm nào: nó là phần tử nhỏ nhất của đại số của các loại con trỏ đối tượng, tức là nó là loại con trỏ đối tượng dưới cùng. Không giống như các trường hợp chung của T*nơi Tlà một số không kiểu void, void*không phải là loại con trỏ đến một giá trị của loại hình void, nhưng kiểu của con trỏ đến một giá trị kiểu không xác định.


Người ta có thể trả về void trong C ++ và C89. stackoverflow.com/questions/35987493/
Mạnh

2
Đoạn thứ 4 chính thức sai. Trong C, lượng lưu trữ cho voidkhông xác định, không phải bằng không. Đây không phải là lý do tại sao các đối tượng loại voidkhông được phép. Lý do chính thức là voidlà một loại không đầy đủ , và các đối tượng không thể có một loại không đầy đủ.
MSalters

4
@MSalters Không, những gì tôi viết là chính xác. Vì vì đề cập đến động lực cho thiết kế ngôn ngữ, chứ không phải là những suy luận logic bên trong đặc tả ngôn ngữ. Các voidloại đòi hỏi 0 bit dung lượng lưu trữ. Đây là lý do tại sao các nhà thiết kế của C quyết định tạo ra voidmột loại không hoàn chỉnh, trái ngược với việc xác định nó lấy 0 byte dung lượng lưu trữ (sẽ ảnh hưởng nhiều đến thiết kế ngôn ngữ) hoặc 1 byte lưu trữ (sẽ lãng phí không gian) .
Gilles 'SO- ngừng trở nên xấu xa'

1
@Gilles: Xin lỗi, nhưng điều đó cũng không có ý nghĩa. Nếu được phép, không gian được sử dụng sẽ là 1 byte cho mỗi đối tượng thuộc loại void và rõ ràng bạn không cần nhiều đối tượng voidloại. Chưa kể rằng các đối tượng này có thể bí danh tất cả các đối tượng khác, vì vậy việc sử dụng thực tế sẽ bằng không.
MSalters

4
@CodesInChaos: Chà, C ++ thực sự cho phép các cấu trúc trống, tức là struct E { };. Khi được sử dụng như một lớp cơ sở, nó có thể có kích thước bằng không. (Thực sự không có thứ gì như C / C ++, hai ngôn ngữ đưa ra lựa chọn của riêng chúng và chúng có thể khác nhau ở những khu vực này. C rõ ràng không có các lớp cơ sở trống, vì nó không có OO ở vị trí đầu tiên)
MSalters

11

Cái tên kiểu trống rỗng có lẽ khó hiểu. Điều này có nghĩa là, như bạn tự nói, loại không chứa giá trị . Các sản phẩm trống rỗng không đề cập đến bất kỳ giá trị riêng lẻ nào của loại này, nó đề cập đến toàn bộ loại, được coi là một tập hợp các giá trị có thể. Vì vậy, điều này không nói lên một điều gì đó giống như một hàm trả voidvề không trả về thông tin nào, nhưng đó không tồn tại giá trị của loại .

Điều này có nghĩa là một hàm có loại kết quả không bao giờ có thể kết thúc. Nếu nó chấm dứt, nếu phải trả về giá trị , nhưng, tốt, giá trị đó không tồn tại.

Điều đó cũng có nghĩa là, thậm chí không thể thảo luận về việc một giá trị của loại trống sẽ chứa bao nhiêu thông tin, bởi vì không có giá trị đó. (Hoặc nếu bạn sẽ, một tuyên bố vô nghĩa như bất kỳ giá trị nào của loại trống chứa chính xác 35093658 bit thông tin thì hoàn toàn đúng.) Thật hữu ích (mặc dù không thực sự chính xác) khi nghĩ rằng các giá trị chứa một lượng thông tin vô hạn .

Trong khi đó, một hàm C với kiểu trả về của Wap voidrõ ràng có thể trả về, nhưng không cung cấp cho bạn bất kỳ thông tin nào trong giá trị trả về của nó. Chà, đó chính xác là những gì đặc trưng cho một loại đơn vị: các giá trị của nó không chứa bất kỳ thông tin nào, bởi vì chỉ có một giá trị như vậy (do đó bạn luôn có thể nói giá trị trả về sẽ là gì, ngay cả khi không cần gọi hàm).

Để trích dẫn Conor McBride (phiên âm sang C):

voidcó nghĩa là "Chán". Nó có nghĩa là loại nhàm chán chứa một thứ, cũng nhàm chán. Không có gì thú vị để đạt được bằng cách so sánh một yếu tố của loại nhàm chán với loại khác, bởi vì không có gì để tìm hiểu về một yếu tố của loại nhàm chán bằng cách đưa ra bất kỳ sự chú ý nào của bạn.

Nó rất khác với loại trống [...]. Loại trống rất thú vị, bởi vì nếu ai đó từng cho bạn một giá trị thuộc về nó, bạn biết rằng bạn đã chết và ở trên Thiên đường và bất cứ điều gì bạn muốn là của bạn.


Hấp dẫn; nếu định nghĩa của là hàm có kiểu trả về là không bao giờ có thể kết thúc, thì C có kiểu như vậy. Chúng tôi gọi nó là khoảng trống dễ bay hơi.
Joshua

Thật thú vị, tôi không biết điều đó. Tôi dường như không thực sự tuân thủ tiêu chuẩn .
leftaroundabout
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.