例如,
如果我写:
char c = CHAR_MAX;
c++;
我可以知道'c ++'是int
还是char
的结果,所以我确定它不是溢出吗?
答案 0 :(得分:3)
我不知道“运行时检查”是什么意思,但是我可以肯定地告诉您c++
的结果是char
类型,而c
是始终char
。 c
永远不会转换为int
。
后缀
++
表达式的值是其操作数的值。 [注意:获得的值是原始值的副本 —尾注]操作数应为可修改的左值。的 操作数的类型应为 cv 以外的算术类型bool
,或指向完整对象类型的指针。 通过向其添加1
来修改操作对象。值计算++
表达式的序列在修改 操作对象。关于不确定顺序的函数 调用,后缀++
的操作只是一个评估。 [注意: 因此,函数调用不得干预 左值到右值转换以及与任何相关的副作用 单个后缀++
运算符。 — 尾注],结果是 prvalue。 结果类型是Cv-不合格版本的 操作数的类型。如果操作数是不能 代表增加的值,位域的结果值 是实现定义的。另请参见[expr.add]和[expr.ass]。
正如Nikos C.在评论中提到的,您应该在递增之前检查c == CHAR_MAX
是否有效。有关检查签名溢出的更多信息,请参见Detecting signed overflow in C/C++。
答案 1 :(得分:2)
我可以知道'c ++'是
int
还是char
根据L.F.'s answer中的标准引号,您可以知道它会导致char
。
所以我确定它不是溢出吗?
您可以确定它是溢出的。据我所知,在char
是带符号类型的系统上,程序的行为将是不确定的。
我可以在运行时检查内置类型吗?
您不能在运行时中检查内置类型,但可以在 compiletime 中检查它们。例如:
static_assert(std::is_same_v<decltype(c++), char>);
当我说:
signed char c = CHAR_MAX + 1 then CHAR_MAX + 1
成为int
的结果,然后将in分配给实现定义的c
。
的确。除非在异国系统上sizeof(signed char) == sizeof(int)
在这种情况下没有提升,并且该算法导致溢出是不确定的行为。
直到C ++ 20。从C ++ 20开始,该标准定义了具有无法表示的值的带符号初始化。
我可以使签名的char溢出吗?
是的。使用增量运算符。据我所知,该标准并未提及增量运算符中的提升。但是,这可能需要解释。