即将推出的C ++ 0x标准的最终委员会草案说:
每个C头,每个头都有一个 表单name.h的名称,表现得好像 每个名称都放在标准中 库名称空间由相应的 cname标头放在 全局命名空间。它是 未指明这些名称是否是 首先在其中宣布或定义 命名空间范围(3.3.6) 命名空间std然后注入 进入全局命名空间范围 显式使用声明(7.3.3)。
早期的C ++标准类似。
我的问题是,当C ++标头#include<cname>
使用重载函数时,#include<name.h>
引入了所有重载,因为重载不是单独的“名称”吗?
以下代码的行为是否应该在符合标准的C和C ++编译器之间有所不同?
#include<stdio.h>
#include<stdlib.h>
#include<math.h>
int main(void)
{
double arg = -2.5;
double result = abs(arg) / 3;
printf("%f\n", result);
return 0;
}
编译就绪测试用例:
math.h
和stdlib.h
:http://ideone.com/pmD4t math.h
和stdlib.h
:http://ideone.com/Sflpn cmath
和cstdlib
:http://ideone.com/yI07m cmath
:http://ideone.com/KrS3W 从这个测试来看,C ++ math.h
的行为与C类似,而不像C ++ cmath
。
但是在Visual C ++ 2010上,C ++ math.h
就像C ++ cmath
一样。
用于Comeau try-it-out的编译时金丝雀:
#include<stdio.h>
#include<stdlib.h>
#include<math.h>
template<typename T> struct typecheck {};
template<> struct typecheck<int> { enum { value = 1 }; };
template<typename T>
typecheck<T> f(const T& t) { return typecheck<T>(); }
int main(void)
{
double arg = -2.5;
auto result = abs(arg) / 3;
printf("%d\n", f(result).value);
return 0;
}
结果:
Comeau C/C++ 4.3.10.1 (Oct 6 2008 11:28:09) for ONLINE_EVALUATION_BETA2
Copyright 1988-2008 Comeau Computing. All rights reserved.
MODE:strict errors C++ C++0x_extensions
"ComeauTest.c", line 15: error: class "typecheck<double>" has no member "value"
printf("%d\n", f(result).value);
^
1 error detected in the compilation of "ComeauTest.c".
Comeau同意Visual C ++。
答案 0 :(得分:3)
是的,所有重载都应该进入全局命名空间。我的理解是math.h
标题看起来像是:
// math.h:
#include <cmath>
using std::abs;
// etc.
所以,是的:当编译为C程序时,示例程序的行为与编译为C ++程序时的行为不同。作为C ++程序,它将从std::abs(double)
调用<math.h>
。作为C程序,它将从abs(int)
调用<stdlib.h>
(这是C标准库中唯一的abs
函数,因为C不支持函数重载。)