15

多くのC/C ++プログラマーが、次のようなものを使用してフラグのセットを実装していることに気づきました。

#define FLAG_1 (1 << 0)
#define FLAG_2 (1 << 1)
#define FLAG_3 (1 << 2)

unsigned int my_flags = 0; /* no flag set */
my_flags |= FLAG_2; /* set flag 2 */

しかし、このアプローチは実際に正しいのでしょうか?C /C++言語標準の一部ではないunsignedintのバイナリ表現について仮定しているように私には思えます。たとえば、その「0」は実際には0x0000です。

私が間違っている?または、理論的には正しいのですが、現在の標準的なハードウェアを考えると実際にはそうではありませんか?

4

4 に答える 4

20

C++

C++11 標準の重要な部分は §3.9.1/7 ( ISO/IEC 14882:2011(E) ) です。

整数型の表現は、純粋な 2 進表記法を使用して値を定義する必要があります。

これは脚注で明確にされています。

49) 2 進数の 0 と 1 を使用する整数の位置表現。連続するビットで表される値は加算され、1 で始まり、2 の連続する整数乗で乗算されます。おそらく最も高い位置のビットを除きます。 . (American National Dictionary for Information Processing Systems から採用。)

シフト演算子の結果は数学的に定義されます。たとえば、次の場合E1 << E2:

E1 が unsigned 型の場合、結果の値は E1 × 2 E2であり、結果の型で表現可能な最大値より 1 を法として減じられます。それ以外の場合、E1 が符号付きの型で負でない値を持ち、E1 × 2 E2が結果の型で表現できる場合、それが結果の値です。それ以外の場合、動作は未定義です。

ビット単位の演算子は、ビット単位として明確に定義されています。たとえば、ビットごとの OR の場合:

通常の算術変換が実行されます。結果は、オペランドのビットごとの排他的 OR 関数です。

もちろん、as-if ルールの下では、表現は純粋な 2 進数システムである必要はありません。コンパイラは、あたかもそうであるかのように動作するプログラムのみを生成する必要があります。

C

C99 ( ISO/IEC 9899:TC3 ) では、純粋なバイナリ表記はビットフィールドと型のオブジェクトに対してのみ保証されていますunsigned char(§6.2.6.1/3):

unsigned ビットフィールドに格納された値と unsigned char 型のオブジェクトは、純粋なバイナリ表記を使用して表現されます。

脚注で再度明確にします。

2 進数の 0 と 1 を使用する整数の位置表現。連続するビットで表される値は加算され、1 から始まり、2 の連続する整数乗で乗算されます。ただし、おそらく最も高い位置のビットは除きます。(American National Dictionary for Information Processing Systems から採用。)

標準では、ビット単位の操作が内部表現に依存することを具体的に指摘しています (§6.5/4)。

一部の演算子 (単項演算子 ~ と、2 項演算子 <<、>>、&、^、および | を総称してビット単位演算子と呼びます) は、整数型のオペランドを持つ必要があります。これらの演算子は、整数の内部表現に依存する値を生成し、符号付き型の実装定義および未定義の側面を持ちます。

于 2012-10-02T18:24:39.903 に答える
13

非 2 の累乗演算を使用するアーキテクチャで C または C++ を実行することは理論的には可能ですが|、、、、&および^演算子はビット単位の動作を持つように定義されているため、そのようなマシンではバイナリ演算をエミュレートする必要があります。

したがって、完全に安全で持ち運び可能です。

于 2012-10-02T18:21:50.400 に答える
7

現在の C および C++ 標準は両方とも、符号なし整数表現を純粋なバイナリ表現に制限しているため、上記のものは完全に安全であり、動作することが保証されています。

于 2012-10-02T18:21:32.887 に答える
2

右にビットをシフトすると常に整数の値が減少しますが、左にビットをシフトすると常に値が増加します。これはマシンのエンディアンに関係なく、あなたの質問に答えるには: 「はい、システムのエンディアンに関係なくビットシフトが同じように機能するため、これは適切です」

それはあなたの質問に答えていますか?

于 2012-10-02T18:21:33.120 に答える