19

これが指定されているC標準のどこにも見つかりません。たとえば、

struct { signed int x:1; } foo;

タイプのfoo.x左辺値intですか、それとも何か他のものですか? int型の値を 0 または -1 しか格納できないため、型の左辺値であることは不自然に思えますがint、別の型を割り当てる言語が見つかりません。もちろん、ほとんどの式で使用され、intいずれにせよ昇格されますが、実際の型は C11 with_Genericで違いを生み、ビットフィールドがどのように相互作用する_Genericかについて標準で言語を見つけることができません。

4

7 に答える 7

5

Jonathan が既に引用したように、p5 はビットフィールドの型を明確に示しています。

intまた、6.3.1.1 にはビットフィールドの算術変換に関する特別なルールがあり、基本的に、anがすべての値を表すことができる場合、そのようなビットフィールドはほとんどの式でanに変換されることを述べていることにも留意する必要があります。int

_Generic算術変換が適用されないというコンセンサスがあるように見えるので、 a の型は宣言された型 (符号のグリッチを法とする) である必要があります。そう

_Generic((X), int: toto, unsigned: tutu)
_Generic(+(X), int: toto, unsigned: tutu)

Xすべての値が に収まる幅の符号なしビットフィールドである場合、異なる結果が得られる可能性がありますint

于 2012-10-28T07:59:03.887 に答える
3

C11 仕様は確かにこれを明確にしておらず、おそらく不十分です。

foo.x以外の型の左辺値だと思いますintが、私の正当化はかなり弱いです:

6.2.7 パラグラフ 1 は次のように述べています。

型が同じ場合、2 つの型には互換性のある型があります。

6.3 パラグラフ 2 は次のように述べています。

オペランド値を互換性のある型に変換しても、値や表現は変更されません。

foo.xが type の左辺値である場合、他の sintと互換性があるため、value を持つことになります(6.3p2 による)。と互換性がないことを示唆し、 type の左辺値ではないことを示唆しています。intfoo.x = 5foo.x5foo.xintfoo.xint

foo.xと互換性がないのは本当に意味がありませんint。おそらく、(6.3.1 の意味での) 変換foo.xは行われず、標準で説明されていない何らかのメカニズムを介してその値が取得されます。あるいは、「算術オペランド」の意味を誤解していて、6.3.1 が左辺値に適用されないことを誤解しているのかもしれません。

6.3.1.1 パラグラフ 1 の箇条書き 2 もあります。

  • 符号付き整数型のランクは、精度の低い符号付き整数型のランクより大きくなければなりません。

foo.x通常よりも精度が低いためint(6.3.2.1p2 で説明されているように「指定されたオブジェクトに格納されている値に変換される」場合ではなく、左辺値として使用される場合)、異なる整数変換ランクが必要です。これは、 ではないことも示唆していintます。

しかし、私の解釈が有効であるか、委員会の意図と一致しているかはわかりません。

これについては、欠陥レポートを提出することをお勧めします。

于 2013-07-20T06:26:58.903 に答える
3

修飾子を含めた場合signed、1 ビットのビット フィールドに格納できる値は実際には -1 と 0 だけです。修飾子を省略した場合、「プレーンな」intビット フィールドが署名または署名なし。もちろん、指定した場合unsigned int、値は 0 と +1 になります。

規格の関連セクションは次のとおりです。

§6.7.2.1 構造体と共用体の指定子

¶4 ビットフィールドの幅を指定する式は、コロンと式を省略した場合に指定される型のオブジェクトの幅を超えない非負の値を持つ整数定数式でなければなりません。122)値がゼロの場合、宣言には宣言子がありません。

¶5 ビットフィールドは、 、 、 、またはその他の実装定義型の修飾または非修飾バージョンである型を持つものと_Boolsigned intますunsigned int。アトミック型が許可されるかどうかは実装定義です。

¶10 ビットフィールドは、指定されたビット数で構成される符号付きまたは符号なしの整数型を持つものとして解釈されます。125)値 0 または 1 がタイプ の非ゼロ幅ビットフィールドに格納される場合_Bool、ビットフィールドの値は格納された値と等しくなります。_Bool ビットフィールドには のセマンティクスがあります_Bool

122)オブジェクトのビット数は_Bool少なくとも ですが、aCHAR_BITの幅 (符号と値のビット数) は_Boolちょうど 1 ビットかもしれません。

125)上記の 6.7.2 で指定されているように、使用される実際の型指定子がintまたは として定義された typedef-nameintである場合、ビットフィールドが符号付きか符号なしかは実装定義です。

脚注 125 は次のことを示しています。

§6.7.2 型指定子

¶5 コンマで区切られた各マルチセットは同じ型を指定しますが、ビットフィールドの場合、指定子が と同じ型を指定するか、または とint同じ型を指定する かは処理系定義です。signed intunsigned int

于 2012-10-28T00:34:45.817 に答える
2

C11 標準は 6.7.2.1p5 で次のように述べています。

ビットフィールドは、_Bool、signed int、unsigned int、またはその他の実装定義型の修飾または非修飾バージョンである型を持つものとします。

これは制約です。つまり、プログラムが上記のカテゴリのいずれにも該当しない型のビット フィールドを宣言する場合、診断を出力する必要があります。

ただし、6.7.2.1p10 で次のように述べています。

ビットフィールドは、指定されたビット数で構成される符号付きまたは符号なしの整数型を持つものとして解釈されます。

彼らが意味することは、ビットフィールドを次のようsigned int x:nに宣言する必要がある一方で、左辺値式の型はfoo.x他の符号付き整数型であり、それを T と呼びます。T は n ビットで構成される符号付き整数型であり、準拠する必要があるということです。 Sec. で与えられたすべての符号付き整数型に対する制約。6.2.6. ただし、 T は、 という名前の標準の符号付き整数型と必ずしも互換性があるわけではありませんsigned int。(実際、T がその標準型と互換性がある唯一の状況は、n が signed int のビット数と等しい場合です。)

_Generic残念ながら、標準は型 T に名前を付ける手段を提供していないため、少なくともポータブルな方法ではなく、 でどのように使用できるかわかりません。C 言語の特定の実装では、この型に名前を付けるメカニズムが提供されている場合がありますが、標準では強制されていません。

于 2014-07-21T23:50:43.997 に答える
1

ビットフィールドのタイプは次のとおりです。

タイプのビットフィールドT

ここで、は、、、、Tまたは実装で定義されたタイプのいずれかです。_Boolintsigned intunsigned int

あなたの例でfoo.xは、はタイプです:タイプのビットフィールドsigned int

これはsigned int、2つのタイプが同じ制約と要件を共有していないためとは異なります。

例えば:

/* foo.x is of type bit-field of type signed int */
struct { signed int x:1; } foo; 

/* y is of type signed int */
signed int y;                     

/* valid, taking the size of an expression of type signed int */
sizeof y;

/* not valid, taking the size of an expression of type bit-field
 * of signed int */
sizeof foo.x;  

/* valid, taking the address of a lvalue of type signed int */
&y;            

/* invalid, taking the address of a lvalue of type bit-field
 * of signed int */
&foo.x;        
于 2012-10-28T10:19:23.347 に答える
0

これは次の要素に依存すると思います。

  1. コンパイラ
  2. 最適化設定
  3. ビットフィールドの最大ビット数
于 2012-10-28T00:37:00.167 に答える