16 ms·
Curious about the other language. What other language that doesn't add another layer between the code and system instructions were you thinking about?
by thinkMOAR 9y ago
Curious about the other language. What other language that doesn't add another layer between the code and system instructions were you thinking about?
- pjmlp 9y agoMost programming languages with compilers to native code (JIT/AOT), the myth of high level Assembler for C only applies if your computer is a PDP-11 or a basic 8-bit CPU like a 6502 or Z80. The ANSI C and C++ standards define the concept of abstract machine for the language semantics, just like in most languages. Additionally you have the concepts of sequence points, the new memory model semantics for multi-threaded code and the beloved UB. UB which doesn't exist in most languages, because their rather leave it implementation defined or lose the opportunity to target some strange CPU not able to support the language semantics. Also Assembly doesn't has UB, making it ironic that it is safer to write straight Assembly at the expense of portability than C or C derived languages.
- bandook_raja 9y ago> Also Assembly doesn't has UB, making it ironic that it is safer to write straight Assembly at the expense of portability than C or C derived languages. You just need to know your compiler flags/configuration to produce exact assembly output (if you want that). And about assembly not having UB, BSF and BSR are pretty good examples for that.
- pjmlp 9y agoThat just is quite ironic, because it is even version dependent across releases of the same compiler, which means anything fine tuned for version X can break on version X + 1, due to changes on the optimizer. And I doubt anyone is regularly reviewing the produced Assembly every single time they change compilers. Assembly doesn't have more than 200 documented cases that hardly any human is capable of remembering.
- TheAceOfHearts 9y agoAren't all undocumented instructions / opcodes actually UB? If you execute an undocumented instruction the processor has to do something.
- bananaboy 9y agoYou can't really accidentally or unintentionally arrive at undefined behaviour in assembly language though. You would have to explicitly use an undocumented instruction or opcode and the result would probably be a hardware interrupt or exception every time.
- SAI_Peregrinus 9y agoNot quite every time though: https://github.com/xoreaxeaxeax/sandsifter https://github.com/xoreaxeaxeax/sandsifter
- bananaboy 9y agoWoah that's pretty neat! Thanks!
- SidiousL 9y agoPeople should understand that undefined behavior allows you to squeeze the last bit of performance, so it can actually be very useful (if you know what you're doing). Here's a cute example: suppose you want to index in an array of things, each having a size which is not a power of two. In this case, to find the address the compiler has to generate code to divide by this size and, since the division is not by a power of two, it can be quite costly, depending on your CPU. So instead, since we can assume that the division can be done exactly, the compiler can generate code to multiply by the modular inverse of the size (which is generically some huge number) and since the multiplication is in general much faster than division, this can be a huge performance gain. This optimization is enabled by undefined behavior. What is damaging is not the notion of undefined behavior, but the fact that the compilers are not so good at telling us when they take advantage of it. Hopefully this will improve with time.
- daemin 9y agoYou could argue that each processor's errata is UB in assembly. I remember that programming for the XScale we had a whole manual of errata that we had to program around. Though because it's documented it's not "Undefined", it's just "Incorrect but we know how incorrect".
- Ded7xSEoPKYNsDd 9y agoThe ARM Architecture Reference Manuals are full of "if you do X, the instruction is UNPREDICTABLE".
- willtim 9y agoOCaml was used recently by the MirageOS folks to implement a better TLS than OpenSSL.
- moosingin3space 9y agoTLS != crypto. TLS is actually very well-suited for a higher-level language like Rust or OCaml, especially due to how state machine patterns can be expressed safely in those languages. Crypto, on the other hand, often relies on low-level intrinsics to get good performance and cache timing attack resistance.
- willtim 9y agoTLS depends on crypto and the mirage team implemented it using OCaml. It supports low-level intrinsics for timing attack resistance. See: https://github.com/mirleft/ocaml-nocrypto https://github.com/mirleft/ocaml-nocrypto
- reikonomusha 9y agoC adds a layer between your code and the system. It abstracts away memory layout, locations, as well as function call semantics, and a many other things. For example, given a C program, you will not be able to tell me with certainty that a variable will occupy memory on the stack, any of your particular processor registers, etc. Formally, C is a language to control the C Abstract Machine, as described in the standard. The sort of direct control one might look for is, as far as I know, only practically found in your processor's assembly language, and your operating system's collection of syscalls. I think Rust, Common Lisp, OCaml, D, Haskell, and other languages give you a lot of benefits that are simply not worth giving up in a new crypto library, like safety.
- bandook_raja 9y agoRust doesn't even exist on a plethora of platforms which C targets. I have high hopes with D and give or take ~2 years, it'll be able to progress forward in lots of domains. Not sure about other languages.
- simias 9y agoOne big long term advantage of Rust is that it leverages LLVM. Basically anywhere LLVM gets ported Rust follows. I could run Rust code on a PlayStation and PocketStation (although I had to cheat a bit on the former because LLVM doesn't support MIPS I). LLVM is not as widely ported as GCC (especially on older, deprecated hardware) but it's getting there. https://svkt.org/~simias/rustation/pockestation-rust.jpg https://svkt.org/~simias/rustation/pockestation-rust.jpg
- pjmlp 9y agoThat is a matter of tooling, though. Until the early 90's C had hardly any meaning outside big expensive UNIX boxes. And it was already on its way out on Windows and OS/2, if it wasn't for the rise of FOSS software and its dependency on C.
- SidiousL 9y agoI think it might be a bit more than that. As far as I can see, all the primitive data types in Rust have sizes which are multiples of eight. However, there are still architectures out there with 9 bit bytes, or 36-bit words. Maybe it's good that all the primitive data types have an explicit size (encoded in their name), but this comes at a cost (in case a byte is 9 bits long, one of the bits will effectively not be used). On the other hand, C and C++ are less explicit about the sizes of their data types so they can accommodate these more weird architectures more easily (and, if you need an explicit size, you can explicitly ask for it).
- JohnStrange 9y agoI'd say that Ada would be well-suited for this. Particularly for implementing crypto. It has a steep learning curve, though. Edit: Sorry, wrote this too hastily and want to put it in perspective. While Ada is well-suited for cryptography and has some good implementations, it is probably not as secure as C crypto libraries in practice. The reason is that the implementations I know don't do OS-specific things like locking memory or preventing core dumps, and doing this in Ada is a bit harder than in C.