我可以在运行时检查内置类型吗?

时间:2019-05-26 11:19:05

标签: c++ c++17 typechecking

例如,

如果我写:

char c = CHAR_MAX;
c++;

我可以知道'c ++'是int还是char的结果,所以我确定它不是溢出吗?

2 个答案:

答案 0 :(得分:3)

我不知道“运行时检查”是什么意思,但是我可以肯定地告诉您c++的结果是char类型,而c是始终charc永远不会转换为int

[expr.post.incr]/1

  

后缀++表达式的值是其操作数的值。   [注意:获得的值是原始值的副本   —尾注]操作数应为可修改的左值。的   操作数的类型应为 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溢出吗?

是的。使用增量运算符。据我所知,该标准并未提及增量运算符中的提升。但是,这可能需要解释。