Re:Notes on Programming in C (1989)
by kazinator on Wednesday October 04, 2017 @02:40PM
(#15403122)
C being a "compiled language" refers to a cluster of concepts which goes perhaps something like this:
* The semantics is simple. For instance, local variables vaporize when a block terminates; compiling a lexical scope in C means not even having to know what "closure" means, and thus not having to deal with a whole class of code generation problems like treating optimizing trivial closures, and non-escaping ones.
* A correct binary call to a C function can be generated if we just parse and analyze a simple prototype declaration. Very little information is needed to generate the calls to functions in a separately compiled file.
* The declaration of any complete data type specifies how it is laid out in memory and accessed.
* In general, anything which would make compiling difficult is either off limits to the programmer entirely, or "undefined behavior". For instance, functions aren't objects and cannot be manipulated at run time in any portable way. There are almost no introspective features whatsoever. A C interpreter can easily have all sorts of introspection features as extensions, but those are kept out of the language because they would interfere with the concept of it being a "compiled language".
* The type system is static and supports type erasure: most C implementations throw away all type info (except as part of "debug info") when translating C programs. No requirement in the standard requires any type info to be retained. Even though anything can be interpreted, static typing with erasure tends to make languages geared toward compiling.
* The semantics is simple. For instance, local variables vaporize when a block terminates; compiling a lexical scope in C means not even having to know what "closure" means, and thus not having to deal with a whole class of code generation problems like treating optimizing trivial closures, and non-escaping ones.
* A correct binary call to a C function can be generated if we just parse and analyze a simple prototype declaration. Very little information is needed to generate the calls to functions in a separately compiled file.
* The declaration of any complete data type specifies how it is laid out in memory and accessed.
* In general, anything which would make compiling difficult is either off limits to the programmer entirely, or "undefined behavior". For instance, functions aren't objects and cannot be manipulated at run time in any portable way. There are almost no introspective features whatsoever. A C interpreter can easily have all sorts of introspection features as extensions, but those are kept out of the language because they would interfere with the concept of it being a "compiled language".
* The type system is static and supports type erasure: most C implementations throw away all type info (except as part of "debug info") when translating C programs. No requirement in the standard requires any type info to be retained. Even though anything can be interpreted, static typing with erasure tends to make languages geared toward compiling.