【问题标题】:Detection of overflow溢出检测
【发布时间】:2023-03-22 19:40:02
【问题描述】:

如何检测c++中unsigned char变量的溢出?

【问题讨论】:

  • 首先,unsigned char 的范围是 0 到 255,而你已经分配了 260。
  • 使用默认设置编译,gcc和g++会发出warning: large integer implicitly truncated to unsigned type [-Woverflow]

标签: c++ char overflow unsigned


【解决方案1】:

无符号数始终在 0 到 255 之间为正数。并遵守 2^n(n = 类型中的位数);如果 char 8 位,则 unsigned char 变量的值介于 0 和 255 之间,而有符号字符的值介于-128 和 127。

【讨论】:

  • 我猜,你的意思是 unsigned char 的值在 0 到 255 的范围内,但即使这样也是错误的:没有限制将 char 的大小限制为 8 位。只要求char 至少有8 位(unsigned char 中的位数与char 中的位数相匹配)。
  • @SudipDas 实际上有符号的字符不需要在 [-128...127] 范围内,范围是实现定义的(请注意,并非所有架构都表示 C2 中的负数)。那就是说这如何回答问题?
【解决方案2】:

无符号字符测试 = 260;

因为260 是一个整数文字,您的编译器应该发出警告。如何处理? 不要忽略编译器警告(或使用替代语法来避免自动转换或将此警告作为错误启用)。另请注意,整数文字始终为正数(无符号):-1 不是整数文字:它是 i.l. 1 和一元运算符 -。对于 gcc,我建议使用 -Wstrict-overflow=2(或更多,根据您的代码策略)并可能启用 -Werror=strict-overflow。对于 MS VC++,您可以使用 /we4307/W14307 启用警告 C4307,如果您将警告保持在 1 级(!!!)(您也可以使用 #pragma warning 指令执行此操作)。

如何检测c++中unsigned char变量的溢出?

在编译时编译器警告是你的朋友,但在运行时

没有可移植的方式(例如,C# 中的 checked)可以做到这一点,更好的技术取决于您想要监控的操作类型>。对于简单 赋值(使用运行时已知的值),您可以编写如下内容:

int32_t bigNumber = 260;
uint8_t smallNumber = static_cast<uint8_t>(bigNumber);
if (static_cast<int32_t>(smallNumber) != bigNumber) {
    // Overflow...
}

您也可以在分配前检查:

int32_t bigNumber = 260;
if (bigNumber > UINT8_MAX) {
    // Overflow
}

请注意,您还可以使编译器的编写工作更轻松(在赋值之后):

if (smallNumber != bigNumber) {
    // Overflow
}

之所以有效,是因为自动升级会将 smallNumber 转换为 bigNumber 类型(除非您执行有符号/无符号比较,在这种情况下,您应该避免使用这种替代方法)。

如果您经常需要它,您可以编写一个小的帮助函数来执行此转换。对于一些想法和可能的实现,如果您使用的是 MS 编译器,您可以查看 SafeInt 系列函数(但请注意,在这种情况下,赋值和强制转换不会抛出)。

【讨论】:

  • 这可能对我有帮助。谢谢
【解决方案3】:

您可以使用大括号来初始化您的值以强制出现编译时错误(假设您使用 C++11 或更高版本):

unsigned char Test{260};

大括号初始化不允许缩小转换范围。

当然,这仍然不允许将值 260 粘贴到 unsigned char 中,但它会引起人们对尝试的注意。您需要更大的数据类型,例如 unsigned short,来表示 260。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2011-12-11
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-07-10
    • 1970-01-01
    相关资源
    最近更新 更多