在 C++ 三元运算符中使用字符串常量是对非左值数组的无效使用吗?
Posted
技术标签:
【中文标题】在 C++ 三元运算符中使用字符串常量是对非左值数组的无效使用吗?【英文标题】:Is using a string constant in C++ ternary operator an invalid use of non-lvalue array? 【发布时间】:2019-06-30 23:22:59 【问题描述】:我的代码使用三元运算符检查条件,然后返回指向 c 字符串常量的指针或引发异常。
奇怪的是,只有当我从三元运算符的一个路径throw
时,编译才会失败。如果我在两边都放一个字符串常量,一切都会编译。
// this line gives no compilation error
auto str = condition ? "foo" : "bar";
// this line gives "error: invalid use of non-lvalue array"
auto str = condition ? "foo" : throw std::runtime_error"bad";
这个问题在 gcc 9.1 中开始出现。我多年来一直使用上述两种模式的行,它们在 clang 和早期版本的 gcc 中编译时没有警告。
上述模式实际上是无效的,还是 gcc 9.1 中的编译器错误?
【问题讨论】:
我认为很明显使用字符串文字不是问题,但抛出异常是。所以这个问题的答案是否定的,但实际的问题是在三元的一个分支中抛出异常是否合法。 @Slava 的问题是字符串文字是doesn't work,但是int
s、it does。不过,我怀疑存在编译器错误,因为我同意问题可能在于条件运算符本身的throw
ing。
@Fureeish 我明白了,但是当有 2 个字符串文字时,它的工作原理与 OP 显示的一样好,所以问题仍然不是字符串文字本身,而是它与抛出异常的组合。所以主题是误导恕我直言。
"foo"
的类型是const char[4]
,编译器显然将其用作str
的类型,然后想将值从一个数组复制到另一个数组。我(还)不知道这是一个错误,还是语言变化(或语言解释)的原因,但作为一种解决方法,您可以将"foo"
转换为const char *
。 (const char *) "foo"
.
有趣的是,cppreference.com 几乎使用了我遇到问题的确切行作为示例 (en.cppreference.com/w/cpp/language/operator_other)。
【参考方案1】:
你是对的。如果另一个操作数是 throw 表达式,则三元运算符传播一个操作数的类型和值类别。条件表达式是const char[4]
类型的左值。 auto
然后推导出 const char*
。这里没有“无效使用非左值数组”。
此外,代码使用 clang 编译 fine。我会说这是 GCC 的一个错误。
【讨论】:
感谢您的确认。我将其作为 GCC 开发人员的错误提出。以上是关于在 C++ 三元运算符中使用字符串常量是对非左值数组的无效使用吗?的主要内容,如果未能解决你的问题,请参考以下文章