C++ 引用未知边界数组的不同编译器的奇怪行为
案例1 以下代码在MSVC和GCC中产生截然不同的结果:C++ 引用未知边界数组的不同编译器的奇怪行为,c++,visual-c++,g++,clang++,c++17,C++,Visual C++,G++,Clang++,C++17,案例1 以下代码在MSVC和GCC中产生截然不同的结果: #include <iostream> template <typename T> void foo(const T&) { #ifdef _MSC_VER std::cout << "foo(const T&): " << __FUNCDNAME__ << std::endl; #else std::cout << __PRETTY
#include <iostream>
template <typename T>
void foo(const T&) {
#ifdef _MSC_VER
std::cout << "foo(const T&): " << __FUNCDNAME__ << std::endl;
#else
std::cout << __PRETTY_FUNCTION__ << std::endl;
#endif
}
void foo(const char*) {
std::cout << "foo(const char*)" << std::endl;
}
int main() {
extern char s[];
foo(s);
}
char s[] = "abc";
GCC 5.3.0,Clang 3.7.0():
案例2
现在,让我们删除模板:
#include <iostream>
void foo(const char(&)[]) {
std::cout << "foo(const char(&)[])" << std::endl;
}
void foo(const char*) {
std::cout << "foo(const char*)" << std::endl;
}
int main() {
extern char s[];
foo(s);
}
char s[] = "abc";
GCC产生另一个错误(同时出现-std=c++14
和-std=c++1z
):
对于第一种情况,在我对C++14的看法中,专门化
void foo(const T&)[with T=char[]]
首先不应该产生,因此MSVC是正确的。但在C++1z中,GCC和Clang是正确的
对于第二种情况,我认为使用C++14 GCC是正确的,使用C++1z Clang是正确的
(这里C++14和C++1z之间的重要区别是)
所以问题是,在C++14(N4140)和C++1z(N4567)中,哪种编译器在第一种和第二种情况下是正确的 另一个问题是,我应该为哪个编译器(如果有的话)提交错误?
const char(&)[]
是CWG 393的有效参数;就在一周前,我为GCC提交了相应的文件
至于VC++和Clang中哪一个是正确的,首先看;如果
s
被声明为const
,则MSVC是正确的。然而,由于不是这样,我们必须在char const*
情况下执行指向指针的数组和限定转换,这使得其他SCS成为这个SCS的子序列(限定调整,而不是左值转换,不被忽略!),即在这两种情况下,Clang都是正确的。const char(&)[]
??如果您将s
设置为const char[]
,则在这三种情况下都会收到类似的错误消息compilers@melak47这就是问题所在,到const
的限定转换在这里很重要。但在这两种情况下都会执行限定转换,而且转换是不同的(char*
->char const*
和char(&)[]
->char const(&)[]
),那么一个序列怎么可能是另一个序列的子序列呢?限定转换只对指针进行。数组引用直接绑定,这就是最重要的。
void foo(const T&) [with T = char []]
#include <iostream>
void foo(const char(&)[]) {
std::cout << "foo(const char(&)[])" << std::endl;
}
void foo(const char*) {
std::cout << "foo(const char*)" << std::endl;
}
int main() {
extern char s[];
foo(s);
}
char s[] = "abc";
error C2668: 'foo' : ambiguous call to overloaded function
could be 'void foo(const char *)'
or 'void foo(const char (&)[])'
main.cpp:3:29: error: parameter '<anonymous>' includes reference to array of unknown bound 'const char []'
void foo(const char(&)[]) {
foo(const char(&)[])