Date: Sun, 31 Dec 2017 21:03:09 -0800 From: Mark Millard <markmi@dsl-only.net> To: "Rodney W. Grimes" <freebsd-rwg@pdx.rh.CN85.dnsmgr.net>, phk@phk.freebsd.dk, FreeBSD Hackers <freebsd-hackers@freebsd.org> Subject: Re: Is it considered to be ok to not check the return code of close(2) in base? Message-ID: <5AD2D86A-2515-4D4D-91B2-1919531F7CC3@dsl-only.net> In-Reply-To: <559541DD-3287-4473-B7DE-B4DDC6860DF7@dsl-only.net> References: <201801010305.w0135luG084158@pdx.rh.CN85.dnsmgr.net> <559541DD-3287-4473-B7DE-B4DDC6860DF7@dsl-only.net>
next in thread | previous in thread | raw e-mail | index | archive | help
On 2017-Dec-31, at 7:17 PM, Mark Millard <markmi at dsl-only.net> wrote: > On 2017-Dec-31, at 7:05 PM, Rodney W. Grimes = <freebsd-rwg@pdx.rh.CN85.dnsmgr.net> wrote: >=20 >>> Poul-Henning Kamp phk at phk.freebsd.dk wrote on >>> Sat Dec 30 20:35:35 UTC 2017 : >>>=20 >>>> But if you just close a file, and you're 100% sure that will work, >>>> you should write it as: >>>>=20 >>>> assert(close(fd) =3D=3D 0); >>>>=20 >>>> To tell the rest of us about your assumption and your confidence in = it. >>>=20 >>> Quoting the FreeBSD assert man page: >>>=20 >>> QUOTE >>> The assert() macro may be removed at compile time by = defining NDEBUG as a >>> macro (e.g., by using the cc(1) option -DNDEBUG). >>> ENDQUOTE >>>=20 >>> This makes required-actions inside asserts dangerous, >>> at least without guarantees that NDEBUG will be >>> undefined. Trying to guarantee that NDEBUG will be >>> undefined would generally be a bad idea. >>>=20 >>> So, >>>=20 >>> assert(close(fd) =3D=3D 0); >>>=20 >>> is a bad coding practice in my view. >>=20 >> Less bad than either of >> (void)close(fd)); >> close(fd); >=20 > Hmm. If one is not to check the status code, > then just do not close the file, at least for > NDEBUG style compiles. Seems odd to me. >=20 > "assert" indicates optional code, not required > code. (This is despite its name.) >=20 > In my view: Both errors need to be avoided and > my point still stands: the example is not a > reasonable way to code. >=20 > One could invent an alternate to assert under > a related name that does not make code > disappear (not even for NDEBUG). "assert" > is just not the right facility to express > just: >=20 > tell the rest of us about your assumption and your confidence in it >=20 > without also indicating: optional code. Going in another direction for when NDEBUG is undefined: assert(expression_evaluating_to_false) is, in part, defined to call abort(). abort() in turn is defined such that: "functions passed to atexit() are not called" also, "[w]hether open resources such as files are closed is implementation defined". (Quoted from http://en.cppreference.com/w/c/program/abort . I can get the standard's wording if needed.) Open Group Base Specifications Issue 7 states in its description of abort: "The functionality described on this reference page is aligned with the ISO C standard. Any conflict between the requirements described here and the ISO C standard is unintentional. This volume of POSIX.1-2008 defers to the ISO C standard". Before Issue 6 the wording apparently required an attempt to fclose all streams --but that made abort necessarily not async-signal-safe. C99 requires the async-signal-safe status. ( http://pubs.opengroup.org/onlinepubs/9699919799/functions/abort.html ) As for C++: "Destructors of variables with automatic, thread local (since C++11) and static storage durations are not called. Functions registered with std::atexit() and std::at_quick_exit (since C++11) are also not called. Whether open resources such as files are closed is implementation defined." ( http://en.cppreference.com/w/cpp/utility/program/abort ) asserts that call abort are difficult to guarantee specific program-exit behavior for, based on just the standards anyway. =3D=3D=3D Mark Millard markmi at dsl-only.net
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?5AD2D86A-2515-4D4D-91B2-1919531F7CC3>