有没有办法让32位C 编译器遵循16位整数促销规则

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

本文关键字:16位 整数 规则 编译器 32位 有没有      更新时间:2023-10-16

带有以下代码:

#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。

这是一个问题,当在台式机上使用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,但我可能不会打扰。