2017-07-18 6 views
0

データのバイトが 'char'メンバ変数に格納されています。おそらく、代わりに 'unsigned char'として格納する必要がありますが、変更することはできません。私は 'int'変数を通してそれを取得する必要がありますが、符号ビットを伝播する必要はありません。C++での符号ビット伝播のないcharのintへの変換

私のソリューションは、この(UINTとUCHARが明白なタイプです)した

void Foo::get_data(int *val) 
{ 
    if(val) 
     *val = (int)(UINT)(UCHAR)m_data; // 'm_data' is type 'char' 
} 

これは私には最適なソリューションを見えました。キャストの代わりに

を使用できますが、これは読みやすいとは思われません。どちらの方が良いのでしょうか?今表現(UCHAR)m_dataは、符号なしの型でもない符号ビットが伝播されますがありますとおり

+4

あなたは最も頻繁に使用されています(おそらく最も明白です): 'unsigned char'にキャストし、' int'に直接結果を保存してください。 – WhozCraig

+0

@WhozCraig:ああ、確かに - それは魅力的です。 +1。答えに変換し、私は受け入れます。 – MPW

+1

なぜabs()を使用しないのですか?それは間違いなくそれを行う最もクリーンな方法です。また、良いコンパイラを使用している場合、可能な限り効率的な方法で実行される可能性があります。 – patatahooligan

答えて

2

だけ

*val = (UCHAR)m_data; 

を書きます。

1

一部のコンパイラ(例:clang)が実際にはbitwiseとbitのための余分なコードを生成するため、キャストが優れています。もちろん、キャストされたキャストが必要なのはunsigned charです。

キャストはあなたの意図をよりよく表しています。データは実際にはintに移動する符号なしの文字です。だから私は同じコードを生成するコンパイラでもそれをより良く呼ぶでしょう。

1

ここでの変換のタイプはIntegral promotionです。

より広い整数型に昇格するときは、符号が符号付きの値の新しい上位ビットに伝播されるように、符号付きで常に値が「拡大」されます。符号伝播を避けるには、符号付きの値を最初に対応する符号なしの型に変換します。

これは明示的に*val = static_cast<UCHAR>(m_data)で行うことができます。 *val = as_unsigned(m_data)としてas_unsigned機能を使用して


あるいは、より安全な、。機能as_unsignedは、次のようになります。as_unsignedを使用して

inline unsigned char as_unsigned(char a) { return a; } 
inline unsigned char as_unsigned(unsigned char a) { return a; } 
inline unsigned char as_unsigned(signed char a) { return a; } 
// And so on for the rest of integer types. 

、メンテナンス後に間違ってなってきている明示的なキャストのリスクを排除m_dataそれが手動式を更新するために、メンテナを必要とせずに自動的にas_unsignedの別のオーバーロードを使用するより広い整数になる必要があります。逆関数as_signedも便利です。

関連する問題