31 ms·
C is an ~untyped language so this comparison isn't very helpful.
by JeremyBanks 6y ago
C is an ~untyped language so this comparison isn't very helpful.
- kazinator 6y agoThough a popular meme, it is false. C has an extensive static type system, requiring programs to be checked and diagnosed. This is quite helpful in catching bugs and refactoring and all that. That type system doesn't encode everything that some people would like, such as preventing a program from retaining and using a pointer to a datum that no longer exists. It allows implicit conversions that some people would like to be explicit (e.g. integer to floating-point and vice versa), but in those situations, the static type of every operand, and of the result, is known and the compiler chooses the conversion accordingly.
- kazinator 6y agoAddendum: C is untyped in linkage: the combination of multiple translated units into a single program. All of the type checking in C translation happens within a single translation unit. The language standard makes no requirements regarding the retention of type information in the translated code. An identifier declared as "double foo" in one translation unit at the file scope, as an external name, could be misused in another translation unit via "extern int foo". Similar reasoning applies to function arguments and structure definitions. We can easily write a program in which two translation units have a completely different idea about what is "struct foo", such that one creates a struct foo and passes a pointer to that into the other. This could happen by accident, at least in the development environment even if the declaration is written in one place (a header file) and everything else includes it. How? Quite simply, the build system could have broken dependencies, and fail to recompile the second translation unit when a declaration has changed. In practice, adherence to program organization conventions, additional diagnostics available in compilers, and reliable compiler-driven dependency generation fill this gap, though imperfectly. Plus related CI, QA and delivery practices, like never giving a build to testers or customers that was an incremental build from a developer's system; every officially tested build must be a clean rebuild. There are related issues in the maintenance of libraries, which give rise to situations that dependent code simply will not and cannot be recompiled, so binary compatibility must be maintained.