1. ホーム
  2. c++

[解決済み] ビットフィールドに値を代入しても、同じ値が戻ってこないのはなぜですか?

2023-01-23 23:58:05

質問

以下のコードを このQuoraの投稿 :

#include <stdio.h>

struct mystruct { int enabled:1; };
int main()
{
  struct mystruct s;
  s.enabled = 1;
  if(s.enabled == 1)
    printf("Is enabled\n"); // --> we think this to be printed
  else
    printf("Is disabled !!\n");
}

Camp &; C++のどちらにおいても、コードの出力は 予期せぬ ,

無効です!

その投稿に符号ビット関連の説明がありますが、設定したのにそのまま反映されないということがあり得るのか、理解できません。

どなたか、もう少し詳しい説明をお願いします。


注意 : どちらのタグも c &になります。 c++ が必要なのは、ビットフィールドの記述の規格が微妙に異なるためです。の回答を参照してください。 C言語仕様 C++仕様 .

どのように解決するのですか?

の通りです。 C++規格n4713 と同じように、非常によく似たコード・スニペットが提供されています。使用されている型は BOOL (カスタム)ですが、どのようなタイプにも適用できます。

12.2.4

4 のビットフィールドに true または false の値が格納されている場合、そのフィールドは bool 型のビットフィールドに格納されている場合(1ビットのビットフィールドも含む)、元の bool の値とビットフィールドの値は等しく比較されなければならない。 列挙子の値が同じ列挙型のビットフィールドに格納され、ビットフィールドのビット数がその列挙型のすべての値を保持するのに十分な大きさであれば の値を保持するのに十分なビット数である場合(10.2)、元の列挙子の値とビットフィールドの値とを等しく比較しなければならない。 の値を等しく比較しなければならない。 . [ 例

enum BOOL { FALSE=0, TRUE=1 };
struct A {
  BOOL b:1;
};
A a;
void f() {
  a.b = TRUE;
  if (a.b == TRUE)    // yields true
    { /* ... */ }
}

- 終了例 ]。


一見すると、太字の部分は解釈の余地があるように見えます。しかし、正しい意図は enum BOOL から派生した int .

enum BOOL : int { FALSE=0, TRUE=1 }; // ***this line
struct mystruct { BOOL enabled:1; };
int main()
{
  struct mystruct s;
  s.enabled = TRUE;
  if(s.enabled == TRUE)
    printf("Is enabled\n"); // --> we think this to be printed
  else
    printf("Is disabled !!\n");
}

上記のコードでは -Wall -pedantic :

警告: 'mystruct::enabled' は 'enum BOOL' のすべての値を保持するには小さすぎます。 struct mystruct { BOOL enabled:1; };

出力されるのは

は無効です ! (このとき enum BOOL : int )

もし enum BOOL : int が単純化され enum BOOL とすると、上記の標準パッセージが指定するとおりの出力になります。

が有効であること( enum BOOL )


したがって、他の回答がほとんどないように、次のように結論づけることができます。 int 型は、たった 1 ビットのビットフィールドに値 "1" を格納するのに十分な大きさではありません。