具有(带符号)枚举值的按位运算

时间:2015-08-03 05:31:48

标签: c enums static-analysis iar misra

我正在使用标志的枚举器值:

<LinearLayout
                android:orientation="horizontal"
                android:layout_width="fill_parent"
                android:layout_height="match_parent"
                android:background="@drawable/line_white"
                android:layout_marginBottom="25dp"
                android:paddingBottom="16dp"
                android:gravity="center_horizontal">

                <EditText
                    android:id="@+id/loginEmailField"
                    android:layout_width="match_parent"
                    android:layout_height="wrap_content"
                    android:autoText="false"
                    android:ems="10"
                    android:hint="Choose an email adress"
                    android:inputType="textEmailAddress"
                    android:paddingLeft="2dp"
                    android:singleLine="false"
                    android:textColor="#ffffff"
                    android:textColorHint="#9377ab"
                    android:textSize="19sp"
                    android:textStyle="bold"
                    android:background="#00000000"
                    android:layout_marginRight="2dp"
                    android:gravity="center"/>
            </LinearLayout>

根据MISRA-C:2004,不应使用签名类型进行按位操作。不幸的是,我的编译器IAR使用 signed int(或short或char)作为枚举的基础类型,我能找到的唯一选项与大小有关,而不是签名(“--enum-is- INT“)。

2 个答案:

答案 0 :(得分:2)

如果只为枚举使用正值,则基础类型是否为无符号类型无关紧要,因为正值应具有与有符号或无符号类型相同的表示形式。 Standard在6.2.6.2表示类型/整数类型§5:有效(非陷阱)对象表示 符号位为零的有符号整数类型的有效对象表示 相应的无符号类型,并且应代表相同的值。

因此,如果您愿意,可以安全地进行无符号转换。无论如何,如果底层类型是char(或者是unsigned char),它可以在任何计算之前(静默地)提升为int。

恕我直言,MISRA-C:2004表示bitwize操作不应该使用带符号的类型,因为标准明确表示负数的表示是实现定义的:

对于有符号整数类型,对象表示的位应分为三个 groups:值位,填充位和符号位。不需要任何填充位;只有一个符号位......如果符号位为1,则该值应为 通过以下方式之一进行修改:

  • 符号位0的相应值被否定(符号和幅度);
  • 符号位的值为 - (2N)(二进制补码);
  • 符号位的值为 - (2N - 1)(1'补码)。

  • 以下哪项适用于实施定义 (强调我的)

TL / DR:如果你没有警告(并且你不应该按|按位),你可以安全地使用任何投射。如果您将无符号类型转换为正值,则表示形式将保持不变,因此如果您(或您的公司规则)选择遵循MISRA-C,您也可以执行转换,因此您还可以安全地转换为无符号类型

答案 1 :(得分:2)

根据link2,第169和211页,如果您启用了IAR语言扩展(enum命令行选项,或者<,则可以定义-e的类型em>项目&gt; 选项&gt; C / C ++编译器&gt; 语言&gt; 允许IAR扩展在IDE中。

特别是,你应该定义一个额外的&#34; sentinel&#34; value,以确保编译器选择正确的类型。它更喜欢有符号类型,并使用尽可能小的整数类型,因此sentinel应该是相应的无符号整数类型可以描述的最大正整数。例如,

typedef enum {
    /* ... */
    enum_u8_sentinel = 255U
} enum_u8;

typedef enum {
    /* ... */
    enum_u16_sentinel = 65535U
} enum_u16;

typedef enum {
    /* ... */
    enum_u32_sentinel = 4294967295UL
} enum_u32;