Deprecate implicit conversion
from bool to character types
- Document number:
- P3765R0
- Date:
2025-07-12 - Audience:
- EWG
- Project:
- ISO/IEC 14882 Programming Languages — C++, ISO/IEC JTC1/SC22/WG21
- Reply-to:
- Jan Schultke <janschultke@gmail.com>
- Co-authors:
- Hana Dusíková <hanicka@hanicka.net>
- GitHub Issue:
- wg21.link/P3765/github
- Source:
- github.com/Eisenwave/cpp-proposals/blob/master/src/deprecate-bool-conv.cow
to character types
serve little purpose in the language, and invite bugs.
We propose to deprecate them.
Contents
Introduction
Proposal
Explicit casts should be allowed
Impact on existing code
Implementation experience
Wording
References
1. Introduction
is equivalent to ,
and the overload is called with .
Surprisingly, every compiler accepts this code at the time of writing,
with no warning and no errors.
That is because → conversion
is neither a narrowing conversion, nor does it change the sign of the operand,
so it does not trigger any checks.
Semantically (assuming ASCII-compatible encoding),
in → conversion,
is converted to U+0000 is converted to U+0001
Seeing that these implicit conversions also invite bugs like the one above, that makes them not just useless, but actively harmful to the language, qualifying them for removal. Similarly, [P1120R0] deprecated array-to-pointer conversion in equality comparison of two arrays, a bug-prone and virtually useless conversion.
2. Proposal
The goal of this proposal is to deprecate implicit conversion
from to character types.
That is, to , , , , and .
Conversions to and are not affected.
That is because these types are used for numerics and not to represent characters,
so e.g. → represents a conversion from
to and from to ,
which is sometimes used in branchless programming:
is incremented if is odd.
Note that branchless programming is generally not affected by a → deprecation.
For example, in the expression ,
both operands are converted to due to the usual arithmetic conversions
and integral promotion.
→ conversion actually takes place when calling
a function with parameter with a argument,
when storing a value in a variable, and
other such "direct" scenarios.
2.1. Explicit casts should be allowed
While an implicit → conversion is likely a bug,
we want users to have a way to suppress deprecation warnings
and to retain the old behavior, in the unlikely event they wanted the conversion to happen.
There are various other conversion, like
→ or
→ which follow this pattern of
"explicit conversions only".
In summary, the intended semantics are as follows:
While most of these are obvious, some decisions require rationale:
-
should be deprecated because direct-initialization, unlike casts, does not generally opt into all possible conversions. For example,d2 is valid, whilestatic_cast < int * > ( void_ptr ) , for someint * p ( void_ptr ) .void * void_ptr -
should be deprecated because list-initialization is generally more restrictive. For instance, it does not permit narrowing conversions, andd5 is ill-formed whileI { void_ptr } is okay, whereI ( void_ptr ) isI .int * -
andk1 should be okay because they are defined in terms ofk2 .static_cast
3. Impact on existing code
During discussion of this proposal with various members of the C++ community, no one was able to produce an example of where this conversion is used in existing code. However, we did not yet perform an extensive survey of large code bases.
Furthermore, there are GCC targets that do not comply with the C99 standard,
where is defined to be (not ).
The following snippet includes GCC definitions for Solaris 2 ([GccSolaris2]):
/* ??? This definition of int8_t follows the system header but does not conform to C99. Likewise int_fast8_t, int_least8_t. */ #define INT8_TYPE "char"
Since → conversion could plausibly happen
in branchless programming,
hypothetically,
some code on such non-compliant platforms is affected.
In any case,
deprecation warnings are easily resolved by performing an explicit conversion,
or by prepending to the operand,
which would trigger integral promotion
and result in → conversion instead.
4. Implementation experience
A [ClangWarning] has been implemented in a fork, which triggers in the deprecated cases.
5. Wording
The wording changes are relative to [N5008].
Change [conv.integral] paragraph 1 as follows:
A prvalue of an integer type
can be converted to a prvalue of another integer type .
The conversion is deprecated ([depr.conv.bool.char]) if
-
isS andbool is a character type ([basic.fundamental]) andD -
the conversion is not necessitated by a
([expr.static.cast]).static_cast
A prvalue of an unscoped enumeration type can be converted to a prvalue of an integer type.
Insert a new paragraph immediately following [conv.integral] paragraph 1:
A prvalue of an unscoped enumeration type can be converted to a prvalue of an integer type.
Insert a new subclause in [depr] between [depr.local] and [depr.capture.this], containing a single paragraph:
Conversion from bool to a character type [depr.conv.bool.char]
Integral conversion ([conv.integral])
from a prvalue of type
to a prvalue of character type ([basic.fundamental]) is deprecated,
unless it was necessitated by a .