2015-09-28 34 views
8

我在這裏有一些頭痛誘發問題。當int不是一個int(intX_t)

基本上我試圖讓一個庫與不同的Arduino系統兼容(不是Arduino問題)。

我有一種情況,類型不再匹配,因爲int不再等同於其相同的固定寬度類型。在提供的有限環境中(沒有stdlib等),我爲我需要的功能編寫了自己的類型特徵類。

一切工作正常使用GCC 4.8.1(AVR)& Extensa-1x106-GCC(ESP8266),但在GCC 4.8.3(SAM,SAMD核心)中沒有。

基本上我都埋頭我的代碼顯示在這個非常基本的代碼問題(int被證實有4個字節的失敗32位平臺編譯器):

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(){} 

您可以查看「 (這是在Arduino IDE中使用的基本實現):http://cpp.sh/377e

順便說一句,靜態斷言在cpp.sh編譯器中也不會觸發。

是4.8.1不正確,意思是intint32_t應該被認爲是不同的類型。或者4.8.3不正確,如果實現定義的大小相同,它們應該是等效的。

我使用下面的代碼來檢測任何類型的整數,這是我最初發現我的錯誤的地方。

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 
     }; 
}; 

當然可以改變它的我檢查charintlong等。但它仍然需要檢查所有固定寬度的變化,最有可能的int_fastX_tint_leastX_t類型,這似乎是一個超級確保最大可用性的冗餘方法。

任何想法?

乾杯,我很欣賞任何輸入!

+1

問題工具鏈是否可用? – melak47

+0

你可以在嵌入式環境中使用[boost](http://www.boost.org/doc/libs/1_59_0/libs/integer/doc/html/boost_integer/traits.html)嗎? –

+0

@ melak47是的,您可以下載[Arduino IDE](https://www.arduino.cc/en/Main/Software),然後從菜單Tools-> Board-> Board manager選擇並安裝SAM,或者其中一個故障鏈(它將完成剩下的工作)的SAMD內核,然後從Tools-> Board列表中選擇Zero(SAMD)或Due(SAM)。 (這是一種痛苦,但是爲初學者設計)。 AVR 4.8.1內核默認提供。 –

回答

4

這受C標準管轄; C++只是通過顯式引用繼承行爲。

什麼C標準說的是:

  • 如果int32_t的定義,它是指一個符號的32位2的補整數。

  • 如果實現提供了一個有符號的32位二進制補碼整數類型,它必須提供將引用它的typedef int32_t

沒有說這個32位2的補碼有符號整數類型必須是int。從技術上講,即使int是一個32位2的補碼整數類型,該實現也可能完全提供一個不同的32位2的補碼有符號整數類型,並且定義int32_t來引用該另一類型。

恐怕唯一完全通用的解決方案是列出所有基本類型,固定寬度類型,最小寬度類型和快速最小寬度類型。

對於不那麼令人生畏的事情,應該可以檢查您希望支持的工具鏈的文檔,以查找它們提供的類型以及它們的名稱。如果這組「你想支持的工具鏈」是無限的,我不認爲有一個更簡單的方法。

+1

通過製作一個特徵模板,可以使這個特徵模板生成一個給定大小和符號的快速,固定寬度,最小寬度,快速最小寬度。至少將列表分解成可管理的塊。拋出所有基本類型(和簽名)的類型列表,再加上size_t和其他類似的整數類型的undefined providence,然後一些metaprogramming在所有這些統一操作... – Yakk

+0

列出所有類型絕對會覆蓋它的一切,然而在所有測試過的編譯器(4種不同的體系結構)中,用基本類型替換固定寬度的整數已證明對我的情況很好。將來可能需要更新,但大多數使用將涉及整數文字。接受的答案。 –

0

從C11標準7.20.1.1(1)

typedef名intN_t表示具有寬度N,沒有填充 比特,一個二的補碼錶示的符號整數類型。因此,int8_t表示寬度恰好爲8位的整數類型的帶符號的 。

所以int32_t是一個有符號的整數,正好是32位寬。

int雖然被定義爲sizeof(int)大於或等於一個char(C++ 14 3.9.1(2)),並且一個符號int必須能夠表示[-32767, 32767](C11 5.2.4.2.1) 。該範圍實際上是16位。

因此,int可能永遠不會等於intN_t,因爲intN_t可以是與標準類型分開的實現定義類型。

+0

實現的'int'的寬度並不重要,我將它與所有固定寬度的變體進行比較。沒有匹配。 –

相關問題