static_cast 从 enum 到 long 根据枚举成员产生不同的输出

static_cast from enum to long yields different output depending on enum members

注意 1:在我提出问题之前我已经想通了这个问题,但我只想讨论一下我认为的这种非直觉行为

注意 2:这发生在 gcc 7.5

#include <stdio.h>

enum lulu
{
        XXX=-2,//if I comment this it considers the enum as unsigned
               //and the cast to long is telling a totally different story
        AAA=10,
        BBB,
        CCC
};

int test_long(long param)
{
        printf("param=%ld\n",param);
        return 0;
}

int main(void)
{
        lulu l1 = AAA;
        lulu l2 = lulu(-AAA);
        printf("parameters to be cast to long: <%X> <%X>\n",l1,l2);
        test_long(static_cast<long>(l1));
        test_long(static_cast<long>(l2));
        int val1 = l1;
        int val2 = l2;

        printf("%d %d\n",val1,val2);

        int i = -6;
        test_long(static_cast<long>(i));
        return 0;
}

问题是这个 static_cast 非常不直观。

在上面的例子中,如果我像下面描述的那样编译它,我会得到以下结果:

# g++ -o long_cast -Wall long_cast.cpp
# ./long_cast
parameters to be cast to long: <A> <FFFFFFF6>
param=10
param=-10
10 -10
param=-6
#

但如果我评论 XXX 定义(一个否定的枚举成员),我会得到一个完全不同的故事

# ./long_cast
parameters to be cast to long: <A> <FFFFFFF6>
param=10
param=4294967286
10 -10
param=-6
#

处理这个问题的正确方法是什么?

我做了一个将值转换为 int 的中间步骤,然后进行了静态转换。

还有其他建议吗?

如代码中所述,解决方案是临时转换为有符号整数变量,然后将 static_cast 转换为 long。

int val2 = l2;

long lval2 = static_cast<long>(val2);