Re: rwlock(9) and mutex(9) definitions

From: Konstantin Belousov <kostikbel_at_gmail.com>
Date: Wed, 27 Oct 2021 04:39:38 UTC
On Tue, Oct 26, 2021 at 09:17:27PM -0700, Gleb Smirnoff wrote:
> On Wed, Oct 27, 2021 at 05:06:52AM +0300, Konstantin Belousov wrote:
> K> > counters.
> K> 
> K> That said, you seems to use wrong syntax for your example.  Might be, it
> K> is enough to fix that, and not change the definition?
> K> 
> K> void
> K> something(bool clue)
> K> {
> K>  	if (clue) {
> K>  		rw_rlock(lock);
> K>  	else
> K> 		rw_wlock(lock);
> K> }
> K> Both rw_rlock and rw_wlock are in tail context.  You cannot _return_ void.
> 
> You actually can return void to hint compiler for a tail call optimization.
> It is not a wrong syntax.
> 
> Other code that is working with true void functions (e.g. with WITNESS) and
> doesn't work with "do {} while" is:
> 
> void
> something(bool clue)
> {
> 	return (clue ? rw_rlock(lock) : rw_wlock(lock));
> }
> 
> This is explicitly allowed in 6.5.15 of the C11 standard.
> 
> Of course all this code can be written in some other way, so constraint
> of KPI not being true functions can be worked around, but I believe better
> it be fixed.

Hum.  I know about ternary operator allowing void-typed expressions on both
sides of ':'.  What I replied to is the following, from C17

6.8.6.4 The return statement
      Constraints
1 A return statement with an expression shall not appear in a function
whose return type is void. A return statement without an expression
shall only appear in a function whose return type is void.

So syntax above is explicitly prohibited by the standard.  I was quite
surprised that both gcc and clang silently accept this, unless -pedantic
is specified.  There is no mention of this extension in gcc manual.
Compiler explorer demonstrates that compilers like msvc do warn about
the construct, and some even error out (tendra):
https://godbolt.org/z/xqcPssTcY

Another part of the confusion, perhaps, is that
	return <void expression>;
is explicitly allowed by the C++ standard (I looked at 2020 version),
unlike C.