Created
November 11, 2023 19:15
-
-
Save rntz/0c753d8ea24972bd81a675881f63725b to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/* Examples of ways in which 'void' is not a unit type in C: */ | |
void baz(void p) { /* error: argument may not have 'void' type */ | |
return p; /* error: void function 'baz' should not return a value [-Wreturn-type] */ | |
} | |
struct foo { | |
void field; /* error: field has incomplete type 'void' */ | |
}; | |
void foo(void *p) { | |
return *p; /* warning: ISO C does not allow indirection on operand of type 'void *' [-Wvoid-ptr-dereference] */ | |
} | |
void bar(void *p) { | |
void x = *p; /* error: variable has incomplete type 'void' */ | |
return x; /* warning: ISO C does not allow indirection yadda yadda */ | |
} | |
/* The way in which void acts as a "unit" type is that functions returning void | |
* | |
* a) can return at all - which would be impossible if "void" were an empty type; | |
* b) return no distinguishable information. | |
* | |
* which are how a proper unit type would behave. However, I doubt any C programmer not | |
* primed by exposure to type theory would think of void as a type with one value. After | |
* all, _what value_? You cannot have a variable of type void, an argument of type void, | |
* or a field of type void. You cannot express the singular "value" inhabiting void except | |
* by circuitous indirection, eg noop() below. I suspect your average C programmer would | |
* respond to "how many values are there of type void" either with "none, void has no | |
* values", or find the question itself questionable. The idea that void in C is a unit | |
* type stems from the intuition that a function with return type T should return a value | |
* of type T. But probably a better intuition for how C is actually specified is that, as | |
* a special-case, a function with return type 'void' returns _no values at all_; it is an | |
* exceptional case. This may not be pretty - but who said C was pretty? | |
*/ | |
void noop() {} | |
/* For instance, the following works - note that comma in C is sequencing, not tupling. */ | |
void blah() { return (noop(), noop(), noop()); } |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment