2011-12-05 24 views
10

は、例えば-1uは有効なC++ですか?

size_t x = -1u; 

if (x == -1u) 
    ... 

有効ですか?

これが有効な場合は、警告が表示されません。 もちろん32ビットシステムではxは0xffffffffでなければならず、64ビットの システムでは0xffffffffffffffffでなければなりません。

-Jochen

+7

リテラルは常に負ではありません。これは ' - (1u)'として解析されます。 –

+0

@KerrekSBはそれを変えますか? –

+0

これは、結果に署名を付けるので、Uの目的を害するものです。 – StilesCrisis

答えて

6

1uは、タイプunsigned intです。これは、単項演算子-を使用して無効にされます。動作は以下の通りである:nは促進オペランドのビット数(C++ 11 5.3.1 /である場合、2 Nからその値を減算することにより

符号なしの量の負計算されます8)。

-1uは、unsigned intで表される最大値を保証します。

任意の符号なしタイプで表現可能な最大値を得るには、-1をその型にキャストできます。たとえば、std::size_tの場合は、 static_cast<std::size_t>(-1)とします。

0

これは技術的に有効なコードですが、あなたは、実装に依存する動作に依存している:符号なしに負の数を変換するオーバーフロー処理を。しかし、あなたが使用しているAPI呼び出しがそれを必要とするため、size_tと-1との意味を比較する必要がある場合は、システムはすでに台無しになっていますが、コードは他の側で同じことをしなければならないためAPIの

+0

私はC++エキスパートではありませんが、符号付き整数型から符号なし整数型への変換は、C99で定義されているため、C++で実装定義されているとは限りません。 –

+0

よく定義されています。 32ビットの 'x%2^32'のようなものだと思います。 – Pubby

+1

負の数は符号なしに変換されません。 '1u'は' unsigned int'型の正数であり、その正数は単項 '-'演算子を使って否定されます。 –

5

私は常に "符号なし、すべてのビット"の目的で〜0Uを使用しています。

+4

... 64ビットの 'size_t'では動作しません。 –

+1

その場合はSIZE_MAXがおそらく良いでしょうし、フォールバックとして〜0ULLでしょう。 – StilesCrisis

+0

しかし、 '〜0'を書き込まないように注意してください。ここの「U」は非常に重要です。詳細については、http://stackoverflow.com/questions/809227/is-it-safe-to-use-1-to-set-all-bits-to-true –

1

コンパイラの実装に依存する動作は厄介です。あなたは、しかし、これを行うことができるようになります。

size_t x = 0; 
x--; 

if ((x+1) == 0) 
+0

これは未定義の動作です。彼が投稿したコードはそうではありません。 – Pubby

+0

@Pubby:この答えでは、未定義の動作をどのように示していると思いますか? –

+1

パブビーどこにUBがありますか?符号なし型(およびsize_tは符号なし型)は、オーバーフロー時によく定義され、ラップアラウンドします。 (符号付きオーバーフローはUBです)。 – AProgrammer

0

これは何をしたいそうです:

size_t x = -1ull; 

if (x == -((size_t)-1ull)) 
    ... 

xは、設定されたすべてのビットではない可能性がある、可能な最大の整数に設定されます。そのために〜0を使用してください。

+0

'size_t'が' unsigned long long'よりも広い時代から、 'size_t x = -1ull;'(たぶん 'wide_t 'をワイド' uintmax_t'の型定義として 'size_t')で' x'を初期化できません最大値。 'size_t x = SIZE_MAX;'はまだ動作します。 – chux

関連する問題