繁体   English   中英

gcc7中的枚举和三元奇怪行为

[英]Enums and ternary strange behavior in gcc7

现在,我们正在测试使用Ubuntu 18中提供的较新gcc 7.3在QtCreator下编译一些Qt代码(我们以前在Ubuntu 16下使用gcc 4.9.3)。

Qt提供了一个enum因此:

enum CheckState {
    Unchecked,
    PartiallyChecked,
    Checked
};

现在,当我们将三元运算符与此一起使用时:

QVariant MyClass::MyFunc(const QModelIndex &index, int role) const {
    return (someCondition ? Qt::Checked : Qt::Unchecked);
}

然后gcc抱怨(带有警告,但我们将警告视为错误):

prog.cpp:999:99:
    error: passing ‘Qt::CheckState’ chooses ‘int’
        over ‘uint {aka unsigned int}’ [-Werror=sign-promo]

我们可以通过以下方法解决此问题:

return (someCondition ? Qt::Checked : static_cast<int>(Qt::Unchecked));

但我不确定为什么必须这样做。

由于它们来自完全相同的enum ,因此它们应该是相同的类型,不是吗? 我知道这两个可能的值是不同类型存在潜在的问题,但是我不明白为什么在这种情况下需要进行这种类型转换。

值是来自enum {0, 1, 2} ,我认为完全相同的类型会排除转换的可能性。

我能想到的唯一可能性是,由于某种原因,枚举的零值被视为无符号。

代替MCVE,我假设上下文类似于:

struct S
{
    S(int);
    S(unsigned int);
};

S foo()
{
    return (1 ? Qt::Checked : Qt::Unchecked);
}

在gcc 7.3中产生警告

警告:传递Qt::CheckState选择int而非unsigned int [-Wsign-promo]


该警告与将enum CheckState类型的值隐式转换为整数有关。 intunsigned int都有有效的隐式转换,并且重载决议选择int

显然,发出警告的理由是,在这种情况下,某些旧版本的gcc选择了unsigned int ,但gcc 7遵循了Standard并选择了int

您的修复之所以有效,是因为在发生重载解析之前,第二个和第三个操作数被带到一个普通的int类型(这与您选择的枚举数无关)。

也许适当的解决方法是将static_cast<int>应用于整个条件,而不仅仅是一个操作数。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM