0

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?

user963241
  • 6,758
  • 19
  • 65
  • 93
  • `c++` results in `char`. Why do you want to check it at runtime? – L. F. May 26 '19 at 11:20
  • I believe `char` is converted to `int` before that. – user963241 May 26 '19 at 11:21
  • @user963241 _"I believe char is converted to int before that."_ No, that's not the case. – πάντα ῥεῖ May 26 '19 at 11:26
  • 4
    @user963241 `c + 1` is `int`, but `c++` is `char` :-) Also, `char` can be weird when doing arithmetic. See: https://blog.knatten.org/2019/05/24/no-one-knows-the-type-of-char-char/ – Nikos C. May 26 '19 at 11:27
  • You should be able to know for sure that it is an overflow. – Eljay May 26 '19 at 12:17
  • 1
    Even if the result of 'c++' is a float, c itself is a char. There is no chance in c++ at all that a type will change. As a type of anything can't change in c++, it can not change in compile and or runtime. As this, it makes no sense to check it! If you write : `auto x = c++` you can check for the result type which is the type of x. For this you can use 'std::is_same' or other stuff – Klaus May 26 '19 at 13:49

2 Answers2

3

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 cv bool, or a pointer to a complete object type. The value of the operand object is modified by adding 1 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++.

eerorika
  • 232,697
  • 12
  • 197
  • 326
L. F.
  • 19,445
  • 8
  • 48
  • 82
2

Can I know if 'c++' results in int or char

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 becomes int result and then in is assigned to c 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.

eerorika
  • 232,697
  • 12
  • 197
  • 326
  • Can I ever make `signed char` overflow? E.g. when I say: `signed char c = CHAR_MAX + 1` then `CHAR_MAX + 1` becomes `int` result and then this `int` result is assigned to `c` which is implementation-defined and gets converted. – user963241 May 26 '19 at 13:46
  • @user963241 that's described in standard. increment is an IB if value cannot fit. – Swift - Friday Pie May 26 '19 at 13:54
  • In my example was it an overflow, yes? Because I suppose increment operator `++` is different from `c = c + 1`? When you said `You can know for sure that it is an overflow` it means 'yes, it is overflow'? – user963241 May 26 '19 at 14:24