gpt4 book ai didi

MSVC 和 Clang/GCC 之间的 C++17 条件(三元)运算符不一致

转载 作者:行者123 更新时间:2023-12-04 04:30:20 27 4
gpt4 key购买 nike

以下代码在 C++17 标准下的 Clang/GCC 下编译,但在 MSVC 下不编译 -std:C++17 /Zc:ternary .

struct CStringPtr
{
const char *m_pString = nullptr;

CStringPtr() = default;
CStringPtr( const char *pString ) : m_pString( pString ) { }

operator const char *() const { return m_pString; }
};

int main( int argc, char ** )
{
bool b = !!argc;

const char *X = b ? CStringPtr( "inside" ) : "naked";
const char *Y = b ? "naked" : CStringPtr( "inside" );
CStringPtr Z = b ? CStringPtr( "inside" ) : "naked";
CStringPtr W = b ? "naked" : CStringPtr( "inside" );

// Silence unused-variable warnings.
return X && Y && Z && W;
}
链接到 Godbolt 的编译器资源管理器,其中包含所有三个: https://godbolt.org/z/6d5Mrjnd7
MSVC 为这四行中的每一行发出错误:
<source>(19): error C2445: result type of conditional expression is ambiguous: types 'const char [6]' and 'CStringPtr' can be converted to multiple common types
<source>(19): note: could be 'const char *'
<source>(19): note: or 'CStringPtr'
而 Clang/GCC 在所有四种情况下都为裸字符串调用 CStringPtr 构造函数。
MSVC /Zc:ternary documentation他们声称该标志支持符合标准的三元运算符解析,这意味着 MSVC 的实现中存在错误或 Clang/GCC 在这里不符合标准。
这里的另一个注意事项是 MSVC 文档在这种情况下提到了与 const char * 相关的异常(exception)情况。正在使用的类型:

An important exception to this common pattern is when the type of the operands is one of the null-terminated string types, such as const char*, const char16_t*, and so on. You can also reproduce the effect with array types and the pointer types they decay to. The behavior when the actual second or third operand to ?: is a string literal of corresponding type depends on the language standard used. C++17 has changed semantics for this case from C++14.


那么,MSVC 是否不符合 C++17 规则?还是 Clang/GCC?

最佳答案

这是 Core issue 1805 , 改变了 ?:在测试其他操作数是否可以转换为它之前,将数组和函数衰减为指针。该问题中的示例基本上是您问题中的示例:

  struct S {
S(const char *s);
operator const char *();
};

S s;
const char *f(bool b) {
return b ? s : ""; // #1
}

One might expect that the expression in #1 would be ambiguous, sinceS can be converted both to and from const char*. However, thetarget type for the conversion of s is const char[1], not const char*, so that conversion fails and the result of theconditional-expression has type S.


似乎 GCC 和 Clang 都没有实现该问题的解决方案,因此他们仍在测试 CStringPtr可以转换成数组。
如果您使用一元 + 手动衰减字符串文字,每个人都拒绝这个例子模棱两可。

关于MSVC 和 Clang/GCC 之间的 C++17 条件(三元)运算符不一致,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/67843224/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com