4 ms·
Most languages from the past 40 years have either been interpreted or JIT'ed. While this has many benefits, it also creates a walled garden where software can o
by s_tec 9y ago
Most languages from the past 40 years have either been interpreted or JIT'ed. While this has many benefits, it also creates a walled garden where software can only talk to other software from the same ecosystem. You have to make a conscious effort to make Java code talk to Python code, for example.
Systems-level programmers are more interested in targeting the "least common denominator", writing code that runs directly on the CPU without any outside help apart from standard OS calls. This is why almost every language has an FFI bridge that can talk to plan C - C is the least common denominator on any given system, so everybody knows how to talk to it.
To have a shot at replacing C, a new language needs to operate at the same level of the stack, relying only on the raw CPU and OS. C++ can do this, but it doesn't offer much safety benefit over C. ObjectiveC is the same.
This is why Go and Rust are so exciting. They are the first languages in a long time that actually run at the same level as C. Rust has the additional benefit of not even requiring a garbage collector, so it can be used in embedded microcontrollers and OS kernels. Go's garbage is a downside, but maybe not a fatal one.
Besides, even if we had hardware bounds checking, you would still need a language that could take advantage of that. C's memory model is too loose, so there is no place to even hook the bounds-checker in. Think about this:
struct Data {
char name[20];
void *next; // Points to another `Data` instance
}
If you try writing a string longer than 20 characters to `((Data *)data.next)->name`, there is no way the compiler could ever type-check that, or tell the hardware bounds checker where the limit is. This is why C has to go.
- youdontknowtho 9y agoI get your enthusiasm, but there are libraries for c that let you use the bounds check instructions in the latest Intel cpu's. (I think there is a pretty good write up about these new instructions on anandtech.) It's not as sexy as a new language but it allows for incremental adoption and doesn't present more effort. Even if it would be a good idea, many people will adopt incremental improvements instead of going for a rewrite. Bounds checking in hardware isn't a new phenomenon, either. The Burroughs had hardware bounds checking, I think. Rust and Go are interesting, I agree. I'm just slightly more suspect about things in tech that have such vocal "evangelism". If they help, that will be seen over time as large projects adopt them. In your effort to make your point you claim that C is "too loose" to take advantage of hardware bounds checking. That kind of thing makes people mistrust the passion that advocates for these languages display. https://en.m.wikipedia.org/wiki/Intel_MPX https://en.m.wikipedia.org/wiki/Intel_MPX
- jburgess777 9y agoI think you underestimate current C compilers. GCC with -D_FORTIFY_SOURCE=2 successfully detect a buffer overflow at runtime when doing: strcpy(((struct Data *)data.next)->name, string_pointer) If the compiler knows the size of the input string at compile time then you will get also a warning during the compilation: /usr/include/bits/string3.h:110:10: warning: call to __builtin___memcpy_chk will always overflow destination buffer
- MichaelGG 9y agoGo has the same interop issues as any other language. Indeed, what's the difference between a Go binary and an AOT compiled .NET/JVM program? Besides Go making that scenario the default? Go and Rust aren't in the same class. Rust can call and be called from C with no overhead or issues (OK, panic across FFI isn't allowed). It's drop-in compatible with C libs, in addition to being a far better language.