5 ms·
How do languages which aim to replace C (such as Rust) deal with this issue? Now I agree, your average webapp won't see any benefit by removing checks and will
by dispose13432 10y ago
How do languages which aim to replace C (such as Rust) deal with this issue?
Now I agree, your average webapp won't see any benefit by removing checks and will see security features by keeping them in, so I'm all for it.
But in OSs (or browsers), speed does matter. And there's no way to optimize it (every + or array operation involves an if).
Is this just one of the "costs of doing business"?
- iainmerrick 10y agoYou optimize by using "&+" instead of "+", or by compiling with "-Ounchecked". You figure out if you need to optimize by testing and benchmarking.
- maxpolun 10y agoRust has overflow checking in debug mode, but release mode does not have any overflow checking. The thinking here is that you'll hopefully catch most of your overflows while testing the app, but get no performance penalty in production use. If you want to overflow there are special types that you can use.
- mikeash 10y agoIn Swift, you have total control over this. If you want checks, use +. If you don't want checks, use &+. In Rust, the operators check in debug builds, and wrap in release builds. Calls are provided so you can always have them check, or always have them wrap, if you need it. Note that C has some really ugly behavior here. Signed overflow is undefined behavior, which means that the compiler doesn't need to check for it, but also that it can assume it never happens and optimized based on that. Many programmers don't realize this, or don't notice that they've accidentally written code that depends on overflow behavior, which can lead to many entertaining bugs: https://lwn.net/Articles/511259/ https://lwn.net/Articles/511259/
- deleted 10y ago[deleted]
- dispose13432 10y ago>Note that C has some really ugly behavior here. Signed overflow is undefined behavior, which means that the compiler doesn't need to check for it, but also that it can assume it never happens and optimized based on that. Many programmers don't realize this, or don't notice that they've accidentally written code that depends on overflow behavior, which can lead to many entertaining bugs: https://lwn.net/Articles/511259/ https://lwn.net/Articles/511259/ That's because different CPUs behave differently. To avoid undefined behavior, you have to have an "if" at every +.
- tomovo 10y agoSarcarsm? In some cases you can just do sanity checks on your inputs and use larger number formats for doing sums. Depends on the use case.
- jandrese 10y agoYou would also be hard pressed to find a modern architecture that doesn't use twos complement for signed integers. That said, rolling over on a signed integer is almost always an error, although luckily it is usually one of the easier ones to detect in the debugger. Big negative numbers are a dead giveaway.
- dispose13432 10y agoIt's easy to detect in the debugger. The danger is signed int x; cin>>x; if(x+1<x){return OVERFLOW;} will, in modern optimizing compilers, never return OVERFLOW There were quite a few security holes introduced by the compiler with that. ----- The only problem is to make a standard, one has to define that MAX_INT+1 = 0 or something. Then, whenever one does signed int x; cin>> x; signed int y = x+1; really turns into signed int = 0; if ( x < MAX_INT) y= x+1 else y = 1;
- ArkyBeagle 10y ago"Many programmers don't realize this..." ( bangs head with ball-peen hammer; rends garment )
- gok 10y ago&+ isn't quite the same as + in C though. It's defined to perform wrapping overflow everytime, so more like integer + in Java. I don't think there's an addition operator in Swift that means "not only don't do overflow checking, but also consider overflow impossible and optimize accordingly". Not entirely clear that such an operator is ever what you really want, I suppose...
- mikeash 10y agoI believe you can get that behavior by using + in a file that you compile with -Ounchecked. I don't believe there's any built-in way to do it at an individual call site, short of writing a wrapper that you compile with -Ounchecked and then calling the wrapper where you want that behavior.
- gok 10y agoI think you're right, yeah.
- deleted 10y ago[deleted]
- steveklabnik 10y agoTo elaborate slightly on what my sibling commentors have said: Rust has a feature called "debug assertions". This is a compile-time option to configure, well, debug assertions. Rust-the-language says that when debug assertions are turned on, overflow checks must be in place, and will panic. When debug assertions are not on, overflow is considered a "program error", and while implementations are not required to do the check, they may. if they do not, they must implement two's compliment wrapping. rustc currently does not check when debug assertions are off. Cargo has the concept of "build profiles", and there are a number of different ones. By default, "cargo build" executes a "debug profile" build, which, by default, has debug assertions on. "cargo build --release" executes a "release profile" build, which, by default, as debug assertions off. If you want wrapping behavior, use https://doc.rust-lang.org/stable/std/num/struct.Wrapping.html https://doc.rust-lang.org/stable/std/num/struct.Wrapping.htm...
- pjmlp 10y ago> How do languages which aim to replace C (such as Rust) deal with this issue? Just like languages older than C did, by providing the option to explicitly request to disable safety checks. For example in ESPOL and NEWP (1961), running unsafe modules requires admin permission, user code cannot make use of unsafe. Something like setuid in UNIX. You don't need 100% unsafe code, rather write it in a safe way, profile it, and then only on the sections that really matter you might turn those checks off, after trying everything else to optimize it.