Sometimes the file descriptor 1 is closed when a program is executed (cf. [1]). Due to buffering [2] a write error is not detected until the buffers are flushed. But the flushing occurs after the return from main:
int main ()
{
import std.stdio;
writeln ("OK.");
return 0;
}
(1>&-
or >&-
can be used to close stdout in BASH, likewise descriptor 1 can be closed in the D program using extern (C) int close (int); close (1);
.)
$ dmd return0.d
$ ./return0 1>&-; echo $?
Failed to flush stdout: Bad file descriptor
1
$
Surprisingly when the return value is anything but 0 the exit code of the program becomes rv & 255
. So in order to return 0 one can return 256:
int main ()
{
import std.stdio;
writeln ("OK.");
return 256; // returns (256 & 0xff) == 0
}
Even more surprising is the fact that is behavior strongly resembles the Perl since v5.24.4 [3]
[1] Goodbye World! The perils of relying on output streams in C [PDF], p. 15 https://www.gnu.org/ghm/2011/paris/slides/jim-meyering-goodbye-world.pdf
[2] What do fully buffered, line buffered and unbuffered mean in C? [closed] https://stackoverflow.com/questions/36573074/what-do-fully-buffered-line-buffered-and-unbuffered-mean-in-c
[3] https://stackoverflow.com/questions/50507849/weird-error-after-perl-upgrade-unable-to-flush-stdout/52106594#52106594