For example,
If I write:
char c = CHAR_MAX;
c++;
Can I know if 'c++' results in int
or char
so I know for sure if its not an overflow?
For example,
If I write:
char c = CHAR_MAX;
c++;
Can I know if 'c++' results in int
or char
so I know for sure if its not an overflow?
I don't know what you mean by "check at runtime", but I can tell you for sure that c++
results in a prvalue of type char
, and c
is always char
. c
is never converted to int
.
Per [expr.post.incr]/1:
The value of a postfix
++
expression is the value of its operand. [ Note: The value obtained is a copy of the original value — end note ] The operand shall be a modifiable lvalue. The type of the operand shall be an arithmetic type other than cvbool
, or a pointer to a complete object type. The value of the operand object is modified by adding1
to it. The value computation of the++
expression is sequenced before the modification of the operand object. With respect to an indeterminately-sequenced function call, the operation of postfix++
is a single evaluation. [ Note: Therefore, a function call shall not intervene between the lvalue-to-rvalue conversion and the side effect associated with any single postfix++
operator. — end note ] The result is a prvalue. The type of the result is the cv-unqualified version of the type of the operand. If the operand is a bit-field that cannot represent the incremented value, the resulting value of the bit-field is implementation-defined. See also [expr.add] and [expr.ass].
As mentioned by Nikos C. in comment, you should check if c == CHAR_MAX
prior to incrementing. For more about checking for signed overflow, see Detecting signed overflow in C/C++.
Can I know if 'c++' results in
int
orchar
As per standard quote in L.F.'s answer, you can know that it results in char
.
so I know for sure if its not an overflow?
You can know for sure that it is an overflow. On systems where char
is a signed type, the behaviour of the program will be undefined as far as I can tell.
Can I check built-in type at runtime?
You cannot check built-in types at runtime, but you can check them already at compiletime. For example:
static_assert(std::is_same_v<decltype(c++), char>);
when I say:
signed char c = CHAR_MAX + 1 then CHAR_MAX + 1
becomesint
result and then in is assigned toc
which is implementation-defined.
Indeed. Except on exotic systems where sizeof(signed char) == sizeof(int)
in which case there is no promotion, and the arithmetic causes overflow which is undefined behaviour.
And only until C++20. Since C++20, signed initialisation with unrepresentable value is defined by the standard.
Can I ever make signed char overflow?
Yes. Using the increment operator. As far as I can tell, the standard says nothing about promotion within the increment operator. However, this may be open to interpretation.