1. Motivation
When using a logical operator to combine two conditions and then inverting it, the user must enclose the combined condition in parentheses.
if ( ! ( cond1 && cond2 ))
This pattern appears about 1500 times in LLVM, and about 2300 times in GCC. Excessive parentheses is annoying, some users might opt to use macros to simplify this, but macros are clearly not an ideal solution: they lack scope, and their names based on personal preferences:
#define NOT(cond) (!(cond)) // or #define IFN(cond) if (!(cond)) // or #define IFNOT(cond) if (!(cond))
Therefore, it’s better to address it using a core language feature instead of a macro.
In Ruby, there is an
statement:
x = 1 unless x > 2 puts"x lesser than 2" else puts"x greater than 2" end
In C++, we also have [P1938]
and [P2334]
:
// P2334 introduced elifndef to C++23 std :: size_t my_strlen ( char const * str ) { #ifndef __cpp_lib_freestanding_cstring auto end { str }; for (; * end != '\0' ; ++ end ); return static_cast < std :: size_t > ( end - str ); #else return std :: strlen ( str ); #endif } // https://zh.cppreference.com/w/cpp/language/if constexpr bool is_runtime_evaluated () noexcept { if not consteval { return true; } else { return false; } }
This pattern is common and easy to understand.
2. Proposal
I propose adding
to eliminate redundant parentheses.
Annoying parentheses might deter some developers from using
, even when it makes the logic flow better. Therefore, we can anticipate that the potential usage could exceed its current performance.
Of course, since
is equivalent to
in C++, this proposal would also allow
.
Moreover, some might prefer
over
. I think the former, compared to the latter, makes the negation emphasis clearer in certain situations:
// libc++ __tree if ! ( __x -> __is_black_ ) // rather than if ( ! __x -> __is_black_ ) { if ( __x -> __left_ && ! __x -> __left_ -> __is_black_ ) return 0 ; if ( __x -> __right_ && ! __x -> __right_ -> __is_black_ ) return 0 ; }
3. Syntax
if !opt constexpropt ( init-statementopt condition ) statement
if !opt constexpropt ( init-statementopt condition ) statement else statement
An if statement of the form
if ! constexpropt ( init-statementopt condition ) statement
is equivalent to
if constexpropt ( init-statementopt !(condition) ) statement
and an if statement of the form
if ! constexpropt ( init-statementopt condition ) statement else statement
is equivalent to
if constexpropt ( init-statementopt !(condition) ) statement else statement
4. Impact on existing code
This is a pure extension; it doesn’t affect any existing code.