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

From: Gleb Smirnoff <glebius_at_freebsd.org>
Date: Wed, 27 Oct 2021 04:49:58 UTC
On Wed, Oct 27, 2021 at 07:39:38AM +0300, Konstantin Belousov wrote:
K> > K> Both rw_rlock and rw_wlock are in tail context.  You cannot _return_ void.
K> > 
K> > You actually can return void to hint compiler for a tail call optimization.
K> > It is not a wrong syntax.
K> > 
K> > Other code that is working with true void functions (e.g. with WITNESS) and
K> > doesn't work with "do {} while" is:
K> > 
K> > void
K> > something(bool clue)
K> > {
K> > 	return (clue ? rw_rlock(lock) : rw_wlock(lock));
K> > }
K> > 
K> > This is explicitly allowed in 6.5.15 of the C11 standard.
K> > 
K> > Of course all this code can be written in some other way, so constraint
K> > of KPI not being true functions can be worked around, but I believe better
K> > it be fixed.
K> 
K> Hum.  I know about ternary operator allowing void-typed expressions on both
K> sides of ':'.  What I replied to is the following, from C17
K> 
K> 6.8.6.4 The return statement
K>       Constraints
K> 1 A return statement with an expression shall not appear in a function
K> whose return type is void. A return statement without an expression
K> shall only appear in a function whose return type is void.
K> 
K> So syntax above is explicitly prohibited by the standard.  I was quite
K> surprised that both gcc and clang silently accept this, unless -pedantic
K> is specified.  There is no mention of this extension in gcc manual.
K> Compiler explorer demonstrates that compilers like msvc do warn about
K> the construct, and some even error out (tendra):
K> https://godbolt.org/z/xqcPssTcY
K> 
K> Another part of the confusion, perhaps, is that
K> 	return <void expression>;
K> is explicitly allowed by the C++ standard (I looked at 2020 version),
K> unlike C.

Hmm, so I mistakenly transferred my knowledge about the tail call
optimization hint from C++ to C.

Okay, let's put return aside. This would compile with true
functions (e.g. WITNESS), otherwise not:

void
something(bool clue)
{
	clue ? rw_rlock(lock) : rw_wlock(lock);
}

And this is correct code per 6.5.15.

-- 
Gleb Smirnoff