6

即将到来的 C++0x 标准的最终委员会草案说:

每个 C 标头(每个都有一个名为 name.h 的名称)的行为就好像每个由相应的 cname 标头放置在标准库命名空间中的名称都放置在全局命名空间范围内一样。未指定这些名称是否首先在命名空间 std 的命名空间范围 (3.3.6) 内声明或定义,然后通过显式使用声明 (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;
}

编译就绪的测试用例:

从这个测试来看,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++。

4

1 回答 1

3

是的,所有重载都应该被带入全局命名空间。我的理解是,math.h标题旨在看起来像:

// math.h:
#include <cmath>

using std::abs;
// etc.

所以,是的:示例程序在编译为 C 程序时的行为与编译为 C++ 程序时的行为不同。作为一个 C++ 程序,它会std::abs(double)<math.h>. 作为一个 C 程序,它将调用abs(int)<stdlib.h>这是absC 标准库中唯一的函数,因为 C 不支持函数重载)。

于 2010-12-10T05:17:47.163 回答