4 ms·
Not that odd if you know the evolution of the language... and what it actually means for modern programmers. The very first C compilers ran on a PDP-11 in just
by bodyfour 5y ago
Not that odd if you know the evolution of the language... and what it actually means for modern programmers.
The very first C compilers ran on a PDP-11 in just a few dozen kilobytes of memory. The entire emphasis was on minimalism, and that meant that things like type enforcement was left to the human.
One of the things the earliest language was missing was the "void" type. If you didn't give a return type to a function, it just defaulted to returning "int". Therefore it was totally normal to have a function fail to return anything.
Since there was no distinction between "function returning int" and "function returning nothing", there was nothing stopping your program from using the value returned... it just meant you got whatever happened to be in the right register.
What does it mean for us today? Basically nothing. "void" was added 30+ years ago when ANSI C appeared. The language couldn't just break the old behavior but in any rational environment you enable enough compiler warnings to avoid these ancient quirks entirely:
$ gcc -Wall -c a.c
a.c:1:1: warning: return type defaults to ‘int’ [-Wimplicit-int]
1 | foo() {}
| ^~~
a.c: In function ‘foo’:
a.c:1:8: warning: control reaches end of non-void function [-Wreturn-type]
1 | foo() {}
| ^
- ironmagma 5y agoOK, but this doesn’t do wonders as a counterargument that C is just a big pile of historical baggage.
- TillE 5y agoLike the article says, this got cleaned up over 20 years ago in C99. But sure, I wouldn't recommend anyone choose C as a language for new software unless they have an extremely good reason, or if you really love stuff like implementing every data structure you use from scratch and using void* as a kind of wildly unsafe generic.
- Tehdasi 5y ago> I wouldn't recommend anyone choose C as a language for new software Unless you are doing firmware where all those constraints are still around, and you have to deal with whatever compiler the vendor supplies for their microcontroller, which will almost certainly be some variant of C.
- pjmlp 5y agoThankfully there are vendors that still bother to sell Basic, Pascal compilers for tiny microcontrollers. But yeah doing so is being a special snowflake, still they are in business to this day.
- int_19h 5y agoBut of course it is; did you expect anything else from a language that's almost 50 years old by now? It's not any different from, say, Common Lisp in that regard. This particular quirk is a few years older than C itself, actually! C was based on a similar language called B. Now B was originally written for PDP-7 and similar machines, which could only address words in memory, not individual bytes. So it was designed "typeless" - the only and always-implicit type in that language is the machine word, so e.g. (a+b) always adds two ints, and (*a) always dereferences a pointer. Otherwise, the syntax was very similar to C: max(a, b) { if (a > b) return a; else return b; } swap(a, b) { auto c = *a; *a = *b; *b = c; } main() { auto a, b; swap(&a, &b); } Since all functions took zero or more words as arguments, and returned a word, there was no need for function prototypes, either, or for function pointer types - if you used () on something, it was treated as a function / function pointer with the corresponding number of parameters. Even labels / goto worked like that. When they got a PDP-11, which had byte-addressed memory, this simplistic approach no longer worked - they had to distinguish char/int and char*/int*. So C added types and pointers - but kept int as the default type, as well as the keyword "auto" (which is completely redundant in C if you specify the type), so that existing B code could be easily ported. For the same reason, they allowed calling functions without declaring them, assuming int as return type. This is also presumably why pre-ANSI K&R C had that weird syntax for parameter types: max(a, b) int a; int b; { ... } If you omit the types, they all default to ints, and it becomes identical to the B declaration! That implicit int rule made it into the ANSI C89 / ISO C90 standard, since it was still common enough in K&R C code floating around at the time, and they were trying to not break things too much. It eventually got removed in C99, except that "short" and "long" still allow to omit the following "int". The useless "auto" is still around, though, although it might eventually get repurposed the same way it was in C++.
- ironmagma 5y agoYou might be surprised. Half the time I say that, I get a comment like yours. The other half of respondents go on about how it’s nonsense and that C is perfectly [modern/simple/usable/reasonable].