4 ms·
Rust would need severe changes to replace C where C shines, being able to cobble object files together into something that works. I can run malloc from userspac
by zid 9y ago
Rust would need severe changes to replace C where C shines, being able to cobble object files together into something that works. I can run malloc from userspace and 14 different previous invocations of a C compiler later I have registers with my parameters in touching page tables.
ABIs, APIs etc have to be able to propagate size and type information that is basically how C defines them if you want anything to work (pointers, integers, floats).
C embeds a remarkable amount of cross-object-file information about a function just with 'int f();'. We know the range of valid values, we know how big the object is, etc.
Rust literally has none of these mechanisms and likely never will, interfacing Rust to other Rust, such that you will get any benefit at all from using it would require megs of type, scope, size, etc information to crawl across the calling convention.
There's a reason C++ names look like CintFuncf!!!@34$902, Rust doesn't have or plan to have anything like this yet, and it'd need to be 20x more complicated.
If you get rid of Rust's magic about being able to remove guards and checks by infering things about the data to make it conform to calling conventions instead of using types, you have just invented C.
- kibwen 9y ago> Rust literally has none of these mechanisms and likely never will It's true that Rust has no stable ABI, but "likely never will" is hyperbole. If people demand it in sufficient quantity then it will happen in time. I personally hope it does someday, but I'm in no hurry. > There's a reason C++ names look like CintFuncf!!!@34$902, Rust doesn't have or plan to have anything like this yet, and it'd need to be 20x more complicated. Rust does have name mangling already. It may not be standardized (again, no stable ABI), but C++'s name mangling isn't standardized either. And I see no justification for why name mangling in Rust would need to be "20x more complicated" than in C++; AFAIK Rust symbols pretty much already imitate C++ symbols in order to play nicely with existing tooling. This would be more informative if you gave some concrete examples. Any hypothetical Rust ABI would be more extensive than the de facto C ABIs, undoubtedly, but the concern here seems unjustified.
- simias 9y agoWell, you get what you pay for. Rust can call and expose C-style ABI functions natively so you can always do what C does. If you want a safer Rust API you can also have that but it makes interfacing with 3rd party code more difficult. I disagree somewhat with your assertion that: > C embeds a remarkable amount of cross-object-file information about a function just with 'int f();'. We know the range of valid values, we know how big the object is, etc.". First of all this is not embedded in the object file but rather in the header, Rust doesn't need that. The object only tells you the name of the symbol and that's about it. In particular that means that the C linker can't detect ABI mismatch if the prototype of a function or the layout of a struct changed, as long as the symbol is found it'll link just fine. Furthermore even with the header available a lot of the time C prototypes are not sufficient to know how to use a method. Take for instance: sometype_t *some_function(someothertype_t *param, int flag); Is param an input or output parameter? Do I own the return value or is it allocated by the function? Or maybe it's just a member of param so it has the same lifetime? I know that flag is an int but that doesn't really tell me which are the valid values I can put in there. In Rust function signatures tell you all of that and it's enforced by the compiler. So yeah, there's a significant overhead in Rust here, but it's for a good reason IMO. It does make it harder to make quick hacks with the linker though. > There's a reason C++ names look like CintFuncf!!!@34$902, Rust doesn't have or plan to have anything like this yet, and it'd need to be 20x more complicated. Are you talking about name mangling? Rust does that too but that's not really the same issue, it's just about generating unique "flat" names for objects that include namespacing and generic info. Like if you have a "fn foo<T>(t: &T)" and you instanciate it with T = i32 and T = String you need to generate two symbols. C doesn't need that because it doesn't have namespaces, generics or overloading.
- kibwen 9y ago> C doesn't need that because it doesn't have namespaces, generics or overloading. Overloading as in operator overloading? Because I don't see how that would affect symbols. Though along with namespaces and generics, there is one thing that Rust also bakes into symbols: versioning information. This is how, in the case of deep dependency graphs, it's possible for a finished binary to include multiple copies of the same library in the event that multiple versions are transitively depended upon. But that doesn't add any complexity to symbol mangling on its own, because if you already have namespaces then you can just treat it as a namespace that only the compiler can see.
- zid 9y agoIt would need it if it had it. How do I find your code that adds bananas together using a banana adding operator via a text name?
- kibwen 9y agoIf you're referring to the ability to define entirely new symbolic operators like you can do in Haskell and Scala, then you'll be happy to hear that Rust doesn't support such a thing. (Frankly, I'm happy about it too. :P ) Rust only allows you to overload a fixed set of operators, and that overloading is all done via traits with well-known names (e.g. overloading the plus symbol "+" is done via implementing std::ops::Add for a type), and traits too can be effectively treated like namespaces as far as symbols are concerned.
- simias 9y agoNo I meant parameter-based function overloading like C++ has (or is it not the wrong term? I forget). So like: int do_something(int param); int do_something(double param, char *param2); I don't see how you can avoid some form of name mangling since obviously you can't just define two duplicate "do_something" symbols.
- steveklabnik 9y ago
- pornel 9y agoI use Rust daily to cobble it together with C object files. rustc --crate-type staticlib file.rs -o rusty.a gcc file.c rusty.a ./a.out It totally works (and debug symbols, C debuggers, profilers, code coverage — all works in the mixed executable). Of course C can't directly call Rust's ABI, but Rust can call and export `extern "C"` functions, and there are tools to automate this. You can declare C function prototypes in Rust using references instead of raw pointers, so you even get basics of borrow checking for the C code.