C++ 当int为';t一个整数(整数)
我这里有些头痛的问题 基本上,我试图使一个库与不同的Arduino系统兼容(这不是Arduino的问题) 我遇到了一种类型不再匹配的情况,例如C++ 当int为';t一个整数(整数),c++,c++11,gcc,gcc4.8,C++,C++11,Gcc,Gcc4.8,我这里有些头痛的问题 基本上,我试图使一个库与不同的Arduino系统兼容(这不是Arduino的问题) 我遇到了一种类型不再匹配的情况,例如int不再等同于其相同的固定宽度类型。在提供的有限环境中(没有stdlib之类的),我已经为我需要的特性编写了自己的类型特征类 使用GCC 4.8.1(avr)和Extensa-1x106-GCC(ESP8266)时,一切都可以正常工作,但在GCC 4.8.3(SAM、SAMD内核)中则不行 基本上,我已经用我的代码来说明这个非常基本的代码中的问题(int
int
不再等同于其相同的固定宽度类型。在提供的有限环境中(没有stdlib之类的),我已经为我需要的特性编写了自己的类型特征类
使用GCC 4.8.1(avr)和Extensa-1x106-GCC(ESP8266)时,一切都可以正常工作,但在GCC 4.8.3(SAM、SAMD内核)中则不行
基本上,我已经用我的代码来说明这个非常基本的代码中的问题(int
被确认在失败的32位平台编译器上有4个字节):
我当然可以将其更改为检查char
、int
、long
等。。但它仍然需要检查所有固定宽度变化,最有可能的是int\u fastX\u t
和int\u leastX\u t
类型,这似乎是一种超级冗余的方法,以确保最大的可用性
有什么想法吗
干杯,我感谢任何意见 这由C标准管理;C++的一个就是通过显式引用继承行为。 C标准所说的是:
- 如果定义了
,则它表示有符号32位2的补码整数int32\u t
- 如果实现提供有符号32位2的补码整数类型,则必须提供引用它的typedef
int32_t
int
。从技术上讲,即使int
是32位2的补码整数类型,实现也完全可能提供不同的32位2的补码有符号整数类型,并定义int32\t
以引用该其他类型
恐怕唯一完全通用的解决方案是列出所有基本类型、固定宽度类型、最小宽度类型和快速最小宽度类型
对于一些不那么令人畏惧的东西,应该可以检查您希望支持的工具链的文档,以找到它们提供的类型以及它们如何命名。如果这组“您希望支持的工具链”是无限的,我认为没有更简单的方法。来自C11标准7.20.1.1(1) typedef name intN_t指定宽度为N的有符号整数类型,无填充 位和2的补码表示。因此,int8_t表示这样一个符号 宽度正好为8位的整数类型 因此,
int32\u t
是一个有符号整数,正好是32位宽
int
虽然定义为sizeof(int)
大于或等于char
(C++143.9.1(2)),并且有符号的int必须能够表示[-32767,32767]
(C11 5.2.4.2.1)。这个范围实际上是16位
因此,
int
可能永远不会等同于intN\u t
,因为intN\u t
可以是实现定义的类型,与标准类型不同。有问题的工具链在哪里可用吗?你能在嵌入式环境中使用吗?顺便说一句,GCC的版本可能没有区别(4.8.1 vs 4.8.3),相反,它可能是架构(avr vs SAM)。我还没有检查,但是GCC在一个小版本中进行这种更改是不寻常的,也是不方便的。然而,不同的体系结构的整数类型设置不同是完全正常的。根据编译器,int毕竟必须在那里:根据,int似乎是int\u fast8\t
,int\u fast16\u t
和int\u fast32\u t
在这个特定平台上:)实现的int
的宽度无关紧要,我将其与所有固定宽度的变体进行比较。不匹配。你可以通过制作一个特征模板,为给定的大小和符号生成快速、固定宽度、最小宽度、快速最小宽度,从而使这一点不那么疯狂。这至少可以将列表分解为可管理的块。输入所有基本类型(和符号)的类型列表,加上大小和其他类似的未定义providence的整数类型,然后使用一些元编程来统一操作所有这些类型…列出所有类型肯定会涵盖所有内容,但是在所有测试的编译器中(4种不同的体系结构)事实证明,用基本类型替换固定宽度的整数适合我的情况。它将来可能需要更新,但大多数使用都会涉及整数文本。接受答案。
template < typename T, typename U > struct is_same{ enum { value = false }; };
template < typename T > struct is_same< T, T > { enum { value = true }; };
void setup() {
static_assert( is_same<int,int32_t>::value, "Not integer");
}
void loop(){}
template< typename T >
struct is_integer{
enum{
V8 = is_same< T, uint8_t >::value || is_same< T, int8_t >::value,
V16 = is_same< T, uint16_t >::value || is_same< T, int16_t >::value,
V32 = is_same< T, uint32_t >::value || is_same< T, int32_t >::value,
V64 = is_same< T, uint64_t >::value || is_same< T, int64_t >::value,
value = V8 || V16 || V32 || V64
};
};