I read that when calling process::exit(), the drop is not automatically called for variables.Means if you call process::exit() before the end,and the variables are dropped at the end. This means that no destructors for local variables will be called?
fn main(){
let b=100;//create b
//b is still really
process::exit(1); //exit
//drop b
}
Does this mean that no local variables will be dropped?
Yes, process::exit will terminate the program immediately and destructors will not run. Depending on the type, this may be fine, or it might be undesired. For example when the destructor was only for cleaning up memory or closing files, that’s something that the operating system would do for you anyways, after the process closes. In the example you gave, the value b is an integer (i32) and that type does not come with a destructor in the first place, so there’s no destructor that could be skipped anyways.
If you are looking merely for a way to set a specific exit code, without also immediately terminating the program, but via an ordinary return from main that executes all destructors normally, you can use e.g. something like
use std::process::ExitCode;
fn main() -> ExitCode {
let b = 100;
ExitCode::from(1)
// local variables will be dropped upon this return
}
or
use std::process::ExitCode;
fn main() -> ExitCode {
let b = 100;
// I'm not an expert, but this might be more cross-platform than just using `1`:
ExitCode::FAILURE
// local variables will be dropped upon this return
}
I recommend @steffahn's solution, however, if you need to call exit in a deeply nested function call, it might be easier to call panic instead which will make sure all the drop functions get called.
You can panic more cleanly by calling std::panic::catch_unwind in your main function and returning an exit code.
Although you shouldn't worry if your drops just release memory as this memory will be released when the process exits. If your thread holds locks it's better for them to be "poisoned" by a panic if the underlying data might be in an invalid state.
Sockets and system resources obtained by your process might not be cleaned up as quickly with a process exit, but the OS will clean them up eventually.
Panics are not for general error handling. The better way to do the equivalent would be to have functions return Result. Main can return a result, too, which will correctly make the process exit with a non-zero status if it's an Err.
Indeed. Please note that in my previous post, I recommended the solution posted by @steffahn, where it's demonstrated that the main function can return an exit status code.
If you need to exit from a deeply nested function call and all functions in your call stack return a type of Result (which is good design) then you can exit this way.
However, if this isn't the case and you don't wish to rewrite your functions, then panicking is your next best option. But there are other ramifications from panicking in your code as it may prevent some optimizations from being performed.
You have no guarantee that destructors will run in general. process::exit is a special case for this, but the general case includes things like power failures, oomkill, operator intervention (kill -9/end task/etc), physical faults on the computer, and plenty of other things that violate Rust's model of computation.
Rust makes a weaker guarantee: the caller of a function will never resume before values owned by a called function are dropped (and their destructors run). Even this is kind of contingent on practical issues, but at least you can use it to build useful programs - so long as you accept the possibility that your program can be stopped mid-execution at any time. process::exit is how you cause your program to inflict this kind of sudden death on itself.
Regarding local variables, everything should be dropped. There might still be minor differences. E.g. I’m not certain, off the top of my head, of how thread-locals for the main thread behave, but with process::exit those are definitely not dropped, whereas it might be (maybe it was platform-dependent? Someone should check the docs…) the case that they are dropped upon normal exit from main.
Edit:Here’s another thing happening after main, buffers for standard output being flushed.