Jef*_*rey 14 c++ standards xcode token-name-resolution
我测试在C++标准ISO/IEC 14882-03 14.6.1/9上的Xcode 4.1和Visual Studio 2008两个编译器的输出都是从标准的预期的结果不同的代码.
代码粘贴在下面.
#include <stdio.h>
#include <iostream>
using namespace std;
void f(char);
template <class T > void g(T t)
{
f(1);
f(T(1));
f(t);
}
void f(int);
void h()
{
g(2);
g('a');
}
void f(int)
{
cout << "f int" << endl;
}
void f(char)
{
cout << "f char" << endl;
}
int main() {
h();
return 0;
}
Run Code Online (Sandbox Code Playgroud)
作为标准的描述.预期的产出应该是
f char
f int
f int
f char
f char
f char
Run Code Online (Sandbox Code Playgroud)
在Xcode 4.1上构建并运行代码.输出如下.在构建设置中,我尝试将"Compiler for C/C++/Object-C"更改为Apple LLVM Compiler 2.1,Gcc 4.2和LLVM GCC 4.2.输出是相同的.
f char
f char
f char
f char
f char
f char
Run Code Online (Sandbox Code Playgroud)
在Microsoft Visual Studio 2008上构建并运行代码.输出如下.
f int
f int
f int
f int
f char
f char
Run Code Online (Sandbox Code Playgroud)
标准的描述(14.6.1/9)粘贴在下面.
如果名称不依赖于模板参数(如14.6.2中所定义),则该名称的声明(或声明集)应在名称出现在模板定义中的范围内; 该名称绑定到此时发现的声明(或声明),并且此绑定不受在实例化时可见的声明的影响.[例:
void f(char);
template<class T> void g(T t)
{
f(1); // f(char)
f(T(1)); // dependent
f(t); // dependent
dd++; // not dependent
}
void f(int);
double dd;
void h()
{
// error: declaration for dd not found
g(2); // will cause one call of f(char) followed // by two calls of f(int)
g(’a’); // will cause three calls of f(char)
Run Code Online (Sandbox Code Playgroud)
- 末端的例子]
代码很好地编写了编译器,但输出是不同的.将此代码移植到不同平台是非常危险的.
有人有这些编译器不符合标准的背景吗?
编辑2011年10月11日
根据http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#197,标准中的示例是错误的.我在Clang和Gcc上测试下面的代码.
#include <stdio.h>
#include <iostream>
using namespace std;
void f(char);
template <class T > void g(T t)
{
f(1);
f(T(1));
f(t);
}
enum E{ e };
void f(E );
void h()
{
g(e);
g('a');
}
void f(E )
{
cout << "f E" << endl;
}
void f(char)
{
cout << "f char" << endl;
}
int main() {
h();
return 0;
}
Run Code Online (Sandbox Code Playgroud)
输出符合预期.
f char
f E
f E
f char
f char
f char
Run Code Online (Sandbox Code Playgroud)
谢谢,
杰弗里
小智 3
正如第一个示例中所指出的,这是一个两阶段名称查找的实例,GCC 和 Clang 都实现了,但 MSVC 没有。在这种情况下,GCC 和 Clang 都是正确的:实际上是错误的标准,如 C++核心缺陷报告 #197中所述。C++11 标准包含一个不同的示例。
这是我们从 MSVC(从未实现两阶段名称查找)或 GCC(直到最近才统一实现两阶段名称查找)将代码移植到 Clang 时看到的最常见问题之一。
归档时间: |
|
查看次数: |
292 次 |
最近记录: |