为什么要担心'undefined behavior'>>签名类型?
Why worry about 'undefined behavior' in >> of signed type?
我的问题与此有关,将包含几个问题。
对我来说,上述问题最明显的(意味着我会在我的代码中使用它)解决方案就是这个:
uint8_t x = some value;
x = (int8_t)x >> 7;
是的,是的,我听到了你们的声音....未定义的行为,这就是我没有发布我的"解决方案"的原因。
我有一种感觉(也许这只是我病态的头脑),术语"未定义的行为"在 SO 上被过度使用,只是为了证明如果问题被标记为 c/c++,则对某人投反对票是合理的。
所以 - 让我们(暂时)抛开C/C++标准,考虑日常生活/编程,真正的编译器实现以及它们为当代硬件生成的代码。
考虑到以下几点:
- 据我所知,我遇到的所有硬件都有不同的算术和逻辑转换指令。
- 我认识的所有编译器都
>>
转换为有符号类型的算术移位和无符号类型的逻辑移位。 - 我不记得有任何编译器在 C/C++ 代码中使用
>>
时发出类似div
低级指令(我们在这里不谈论运算符重载)。 - 我知道的所有硬件都使用U2。
所以。。。是否有任何行为(任何当代编译器,硬件)与上述行为不同?简单地说,我应该担心右移符号值没有转换为算术移位吗?
我的"解决方案"在许多平台上编译为一个低级指令,而其他平台则需要多个低级指令。你会在代码中使用什么?
请说实话;-)
为什么要担心符号类型>>中的"未定义行为"?
因为现在任何特定的未定义行为的定义有多好并不重要;关键是它可能会在未来的任何时候中断。您依赖于一种副作用,该副作用可能出于任何原因或无理由在任何时候被优化(或未优化)。
另外,在我使用我不应该使用的东西之前,我不想问一个对许多不同编译器的实现有详细了解的人,所以我跳过了它。
是的,有些编译器的行为与您假设的不同。
特别是编译器中的优化阶段。它们利用变量的已知可能值,并将从不存在 UB 的情况下派生这些可能的值。如果指针已取消引用,则指针必须为非 null;如果整数用作除法器,则整数必须为非零;右移值必须为非负值。
这可以追溯到过去:
if (x<0) {
printf("This is dead coden");
}
x >> 3;
真正归根结底是,你愿意冒险吗?
"标准不能保证亚达亚达"很好,但说实话,现在风险并不大。如果你打算在一些疯狂的平台上运行你的代码,你通常会提前知道。如果它让你感到惊讶,那么,这就是你承担的风险。
此外,解决方法很糟糕。如果你不需要它,它只是用毫无意义的"函数调用而不是右移"污染你的代码库,这将更难维护(因此会带来成本)。而且你永远无法将代码从其他地方"粘贴并忘记"到项目中 - 你总是必须检查代码是否有右移负有符号整数的可能性。
- ArduinoJson 6.15.2:JsonObject没有命名类型
- 防止主数据类型C++的隐式转换
- 大量序列中核苷酸类型的快速计数
- 如何从C++中的依赖类型中获得它所依赖的类型
- 有关插入适配器的错误。[错误]请求从 'back_insert_iterator<vector<>>' 类型转换为非标量类型
- 是否可以初始化不可复制类型的成员变量(或基类)
- 如何获取std::result_of函数的返回类型
- 从父命名空间重载类型
- 如果C++类在类方法中具有动态分配,但没有构造函数/析构函数或任何非静态成员,那么它仍然是POD类型吗
- 我想将一个对T类型的非常量左值引用绑定到一个T类型的临时值
- Openssl 1.1.1d无效使用不完整的类型"struct dsa_st"
- 访问者访问变体并返回不同类型时出错
- 在VS2010-VS2015下编译时,如何使用decltype作为较大类型表达式的LHS
- 处理小于cpu数据总线的数据类型.(c++转换为机器代码)
- C++ 雷神库 - 使用资源加载器类时出现问题(不命名类型)
- 模板元程序查找相似的连续类型名称
- 是否可以从int转换为enum类类型
- 构造函数正在调用一个使用当前类类型的函数
- eigen :: llt&lt;eigen :: matrixxd&gt;具有不完整的类型
- 错误c++visual studio c2227左侧'->;Init';必须指向类/结构/联合/泛型类型