Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Document the effect of main's return value? #1196

Open
mattheww opened this issue Apr 19, 2022 · 8 comments
Open

Document the effect of main's return value? #1196

mattheww opened this issue Apr 19, 2022 · 8 comments

Comments

@mattheww
Copy link
Contributor

#1194 (comment) suggests documenting how main()s return value affects the process's exit status.

I think the Reference doesn't currently have anything to say about what happens after main() returns.

I suggest adding a section in runtime.md saying roughly the following:

  • When (if) main() returns, the runtime calls report() on its result (which necessarily implements Termination), which gives an ExitCode.

  • The runtime uses that ExitCode in a platform-specific way to report information to the environment hosting the Rust program.

  • Note: on Unix-like systems and Windows, the ExitCode determines the process's exit status

Further, I think some part of Rust's documentation ought to be saying that, on Unix-like systems and Windows, ExitCode::SUCCESS leads to exit status 0, and ExitCode::FAILURE leads to exit status 1 (because we have to expect that users will rely on that behaviour). I think that part would be better in the standard library docs, but it isn't currently there.

I think it's important to say that report() is called, because that's what has the side-effect of printing a message to standard error (in the case where the returned value was a Result<_, Debug>).

So I think ideally the standard library docs would have entries for the specific Termination impls, saying how each of them behaves.

I think this approach would avoid the worry expressed in rust-lang/rust#93448: a no_std binary won't be using the Termination impls for Result<_, Debug>, because those are in std.

@ehuss
Copy link
Contributor

ehuss commented Apr 21, 2022

This sounds reasonable to me. The reference has historically not touched on platform-specifics like this, and has also somewhat ignored life before/after main as well. But I think making these statements about Termination seem like a good, small step.

@rust-lang/lang I would appreciate if someone could weigh in here. Are you OK with the reference specifying the exit-status behavior with respect to the Termination trait as discussed above?

@joshtriplett
Copy link
Member

Despite Termination being a library trait, it's used in the language "runtime" code that runs after main, so I think it should be documented in the reference.

And we should explicitly document how we pass through values.

@yaahc
Copy link
Member

yaahc commented May 3, 2022

Also, a bit more context from the lang team meeting. When we discussed this we agreed that we want the reference to include documentation about the runtime half of the return from main system. Such as specifying how it interacts with the Termination trait (calling report) and how it passes along the ExitCode, but that we should leave the documentation about the library APIs being consumed in the library API docs. Such as any indication of what report does for specific types or what values ExitCode::FAILURE/ExitCode::SUCCESS map to on specific platforms should live in the API docs, and the reference should only include a small section indicating that this additional information lives in the API docs with cross links to those docs.

@chorman0773
Copy link
Contributor

RE. the above (w/ the context from reading the minutes of that aformentioned meeting after the fact), C requires that a status code 0 (and incidentally also EXIT_SUCCESS which may be the same or distinct) mean "successful" termination, though it doesn't require anything other than EXIT_FAILURE to mean "failed" termination.

@yaahc
Copy link
Member

yaahc commented May 3, 2022

RE. the above (w/ the context from reading the minutes of that aformentioned meeting after the fact), C requires that a status code 0 (and incidentally also EXIT_SUCCESS which may be the same or distinct) mean "successful" termination, though it doesn't require anything other than EXIT_FAILURE to mean "failed" termination.

I don't think we'd necessarily want to copy C here, but we did discuss whether the u8 value an ExitCode is constructed from in rust should be distinct from the value it gets translated to for any specific platform. More concretely, the idea being that constructing an ExitCode from 0u8 will always give you ExitCode::SUCCESS, and any other value would always give you ExitCode::FAILURE or something equivalent, but ExitCode::SUCCESS doesn't necessarily need to map to 0 on any specific platform. The ultimate goal here is that we want to be as flexible as possible over what platform APIs we can abstract over, should , for example, some future rust based OS come along with a radically different interpretation of exit codes, we don't want to restrict their possible design space.

@chorman0773
Copy link
Contributor

chorman0773 commented May 4, 2022 via email

@yaahc
Copy link
Member

yaahc commented May 4, 2022

I think there's been some confusion here. I didn't mean to imply that ExitCode::from(20u8) would always map directly to ExitCode::FAILURE. I am just trying to make sure that cross platform assumptions around constructing ExitCodes hold up as best as possible when using the cross platform interface. I don't want people's code that assumes ExitCode::from(0) is always success to completely fail to work on platforms where they decided to have a different sentinel value represent success. In your example, the only time I expect ExitCode::from(20) would produce ExitCode::FAILURE is when you're running on a platform where ExitCode::SUCCESS == ExitCode(20), otherwise I'd just expect us to forward along the ExitCode(20) as intended.

Then, if we run into a situation where someone is running on a platform where ExitCode(0) represents a specific failure that they need to be able to represent we can add a platform specific API for constructing exit codes directly from that platform's expected representation, with docs detailing the exact ways the codes differ on that platform, and do so in a way that ensures that non-cross-platform code never compiles on other platforms.

@joshtriplett
Copy link
Member

We discussed this again in today's @rust-lang/lang meeting, and we want to confirm that we'd be happy to have the lang/runtime aspects of this documented in the reference. (The library semantics should remain in the library docs.)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

5 participants