2015-09-28 19 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は失敗し、32ビットプラットフォームコンパイラの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(){} 

あなたは 'を表示することができますここでの「通常の」C++実装は、上記の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 
     }; 
}; 

もちろん、私はなど、intcharをチェックするlongそれを変更することができます..しかし、それはまだスーパーのように思われる、すべての固定幅の変動と最も可能性の高い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)をダウンロードすることができ、ツール - >ボード - >ボードマネージャからSAMを選択してインストールするか、 SAMDコアを使用して、残りの作業を行います。次に、ツール - >ボードリストからゼロ(SAMD)または期限(SAM)を選択します。 (それは痛みですが、初心者のために設計されています)。 AVR 4.8.1コアはデフォルトで提供されています。 –

答えて

4

これはC標準によって管理されています。 C++のものは明示的な参照によって振る舞いを継承します。

C標準である言う:

  • int32_tが定義されている場合、それは符号付き32ビットの2の補数整数を指します。

  • 実装が符号付き32ビット2の補数の整数型を提供する場合は、これを参照するtypedef int32_tを提供する必要があります。

この32ビットの2の補数符号付き整数型は、intである必要があります。技術的には、intの32ビットの2の補数の整数型であっても、実装で別個の32ビットの2の補数符号付き整数型を提供し、他の型を参照するためにint32_tを定義することは完全に可能です。

完全に包括的な唯一の解決策は、すべての基本型、固定幅型、最小幅型、および高速最小幅型をリストすることです。

何か難解なことは、サポートしたいツールチェーンのドキュメントを調べて、そのツールチェーンが提供するタイプとその名前付け方法を見つけることができるはずです。あなたがサポートしたい "ツールチェーン"のセットが無制限であれば、より簡単な方法がないと思います。

+1

与えられたサイズと署名のために、高速、固定幅、最小幅、高速最小幅を生成する特性テンプレートを作成することで、このことを少し難解にすることができます。それは少なくとも、リストを管理可能な塊に分解する。すべての基本型(および符号付き)の型リスト、さらにはsize_tと他の同様の整数型の未定義摂理、そしてそれらのすべてを均一に処理するメタプログラミング... – Yakk

+0

すべての型を明確にリストするなら、しかし、テストされたすべてのコンパイラ(4種類のアーキテクチャ)では、固定幅の整数を基本型に置き換えても、私の状況では問題ないことが判明しました。将来は更新が必要かもしれませんが、ほとんどの場合、整数リテラルが使用されます。受け入れられた答え。 –

0

C11標準7.20.1.1(1)

からのtypedef名intN_t幅N、無パディング ビット、2の補数表現符号付き整数型を指定します。したがって、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ビットです。

intintN_tと等しくない場合があります。intN_tは標準タイプとは別の実装定義タイプです。

+0

実装された 'int'の幅は重要ではありません。固定幅のすべてのバリアントと比較します。一致するものはありません。 –

関連する問題