繁体   English   中英

有没有办法让32位C ++编译器遵循16位整数提升规则?

[英]Is there a way to get a 32bit C++ compiler to follow 16bit integer promotion rules?

使用以下代码:

#include <stdint.h>

uint16_t test() {
    uint16_t a = 1000;
    uint16_t b = 1000;
    uint16_t c = 100;
    return (a * b) / c;
}

针对32位机器的编译器将返回10000,但是针对16位机器的编译器将返回169.该行为由C的整数提升规则解释。

当在台式PC上对8或16位机器进行单元测试时,这是一个问题。

现在,要么将每次乘法转换或将其放入返回相同类型的函数中,这是我能想到的唯一选项。 理想情况下会存在一些编译器开关,但我还没有看到。

对GCC,Clang或MSVC的解决方案感到满意。

这可能是一个XY问题 取决于您的具体工作。

虽然针对不同架构的台式机上的单元测试可能有所帮助,但我怀疑这是方法。 即使你在编译器中发现了一些开关来在x86上模拟其他架构的一些规则,你仍然无法确定模拟的行为是否与真实环境中的相同。 此外,目标架构和测试架构之间的行为肯定会存在其他差异(有些可以预测,有些则无法预测)。

总而言之,对架构进行测试并期望它在另一个架构上工作是不可靠的,无论如何都不是真实的。 所以解决方案应该是在目标架构上进行测试。 获取可以在真实环境中进行单元测试的模拟器,VM或远程设备。

如果这不是一个可行的选择,而不是试图使单元测试与PC环境中的真实环境相匹配,那么您可以忍受这些差异,考虑到单元测试不是非常可靠并仅将它们用于有限的测试,并且更多地依赖于集成测试,这应该在目标架构上。

不,没有办法做你要问的事。

现在,要么将每次乘法转换或将其放入返回相同类型的函数中,这是我能想到的唯一选项。

另一种选择是避免在单个表达式中使用多个操作,隐式强制转换回uint16_t

uint16_t test() {
    uint16_t a = 1000;
    uint16_t b = 1000;
    uint16_t c = 100;
    a *= b;
    a /= c;
    return a;
}

或者,使用函数,该函数可以是重载运算符以保持代码可读:

#include <stdint.h>

template <typename T>
struct unpromoted
{
   T value;

   unpromoted() = default;
   unpromoted(T value) : value(value) { }
   explicit operator T() { return value; }

   friend unpromoted operator*(unpromoted a, unpromoted b)
   { return a.value * b.value; }

   friend unpromoted operator/(unpromoted a, unpromoted b)
   { return a.value / b.value; }

   // add other operators as well
};

using uuint16_t = unpromoted<uint16_t>;

uuint16_t test() {
    uuint16_t a = 1000;
    uuint16_t b = 1000;
    uuint16_t c = 100;
    return (a * b) / c; // returns 169
}

请注意,这需要在添加uuint16_tuuint8_t时进行uuint16_t uuint8_t 可以让它返回一个uuint16_t ,但我可能不会打扰它。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM