web-dev-qa-db-ja.com

aとbの結果は何ですか?

これは厄介ですが、ビットごとのAND演算子はC++標準で次のように定義されています(強調は私のものです)。

通常の算術変換が実行されます。 結果は、そのオペランドのビットごとのAND関数です。演算子は、整数またはスコープのない列挙型オペランドにのみ適用されます。

これは、私には一種の無意味に見えます。 「ビットごとのAND関数」は、私が見る限り、標準のどこにも定義されていません。

AND関数はよく理解されているので、説明は必要ないかもしれません。 「ビット単位」という語の意味もかなり明確である必要があります。関数はそのオペランドの対応するビットに適用されます。ただし、オペランドのビットを構成するものは明確ではありません。

何ができますか?

39

これは指定不足です。規格がビット単位の操作に言及するときに何を意味するかという問題は、いくつかの欠陥レポートの対象です。

欠陥レポート1857:ビットに関する追加の質問

5.11 [expr.bit.and]、5.12 [expr.xor]、および5.13 [expr.or]でのビット単位演算の仕様では、値であるかどうかを指定せずに、演算の説明で「ビット単位」という未定義の用語を使用しています。表示されているオブジェクト表現。

これの解決の一部は、「ビット」(それ以外の場合は現在C++では未定義)を2の累乗の値として定義することです。

そして応答は:

CWGは、ビットへの参照を回避するために操作自体の説明を再公式化することを決定し、「ビット」などの定義に関するより大きな質問を分割して、さらに検討するために1943年を発行しました。

そして 欠陥報告194 は言う:

CWGは2014-06(Rapperswil)会議で、問題1857および1861によって提起された質問の限られたサブセットのみに対処することを決定しました。この問題は、残りの質問のプレースホルダーであり、たとえば、 2、ビットフィールドに符号ビットがあるかどうかなどを指定します。

これから見ることができます 欠陥レポート1796:null文字のall-bits-zeroは意味のある要件ですか? 、この標準が意味する問題は、ビットに言及するときに他のセクションにも影響する/影響することを意味します:

2.3 [Lex.charset]パラグラフ3によれば、

基本実行文字セットと基本実行ワイド文字セットには、それぞれ基本ソース文字セットのすべてのメンバーに加えて、アラート、バックスペース、およびキャリッジリターンを表す制御文字、およびnull文字(それぞれnullワイド文字)が含まれます。その表現はすべてゼロビットです。

移植可能なプログラムが表現のビットを検査できるかどうかは明らかではありません。代わりに、値の表現に対応する数値のビットの検査に限定されているように見えます(3.9.1 [basic.fundamental]段落1)。表現のビットパターンを指定するよりも、null文字値を0または '\ 0'と比較することを要求する方が適切な場合があります。

シフト、ビット単位、およびビット単位または演算子の定義にも同様の問題があります。これらの仕様は、表現のビットパターン、またはそれらのパターンを数値として解釈した結果の値に制約がありますか?

この場合の解決策は次のとおりです。

表現はすべてゼロビットです

に:

値は0です。

ecatmurの回答で述べたように C++標準のドラフトは、セクション5.2.4.2.1[basic.fundamental]のC標準セクション3.9.1に従います。 段落3では、C標準の6.5/4を参照していないため、少なくとも結果は実装定義であることがわかります。以下のコメントで、C++標準は規範的な参照のテキストのみを明示的に組み込むことができることを説明します。

40
Shafik Yaghmour

[basic.fundamental]/3はC 5.2.4.2.1に従います。 C++のビットごとの演算子が指定不足であることは、Cを同様に据え置くことが合理的であるように思われます(この場合は6.5.10/4)。

バイナリ&演算子の結果は、オペランドのビット単位のANDです(つまり、結果の各ビットは、変換されたオペランドの対応する各ビットが設定されている場合にのみ設定されます)。

C 6.5/4には以下が含まれることに注意してください。

一部の演算子(単項演算子~、および二項演算子<<>>&^|、まとめてビットごとの演算子)と記述されている場合、整数型のオペランドが必要です。これらの演算子は、整数の内部表現に依存する値を生成し、符号付き型の実装定義および未定義の側面を持っています。

整数の内部表現は、もちろん6.2.6.2/1、/2で説明されています。

9
ecatmur

C++標準では、storageを特定のビット数として定義しています。実装は、特定のビットに起因する意味を決定する場合があります。そうは言っても、バイナリANDは特定の型の表現を形成する概念的な0と1に作用するはずです。

.9.1.7。(...)整数型の表現は、純粋な2進記数法を使用して値を定義するものとします。49 (...)

.9.1、脚注49) 2進数の0と1を使用する整数の位置表現。連続するビットで表される値は加算され、1で始まり、連続する整数乗で乗算されます。おそらく、最高位のビットを除いて、2

つまり、使用される物理表現の場合、バイナリANDはAND関数の真理値表に従って動作します(各ビット番号iについて、ビットAをとります) とB 適切なオペランドから、両方が1の場合にのみ1の値を生成し、それ以外の場合はビットRに0を生成します..結果の値は実装によって解釈されますが、選択されたものは何でも、ORおよびXORのような他のバイナリ演算に関して他の期待と一致している必要があります。

6

法的には、すべてのビット単位演算は実際には定義されていないため、未定義の動作と見なすことができます。

より合理的には、常識を適用し、これらの演算の一般的な意味を参照して、それらをオペランドのbitsに適用することが期待されます(したがって、「ビット単位」という用語)。

しかし、実際にそれを述べているものはありません。残念なことに、私の答えは規範的な言葉遣いとは言えません。