When the C++ standard provides C headers bringing names into the global namespace, does that include overloads?

三世轮回 提交于 2019-12-19 06:57:13

问题


The final committee draft of the upcoming C++0x standard says:

Every C header, each of which has a name of the form name.h, behaves as if each name placed in the standard library namespace by the corresponding cname header is placed within the global namespace scope. It is unspecified whether these names are first declared or defined within namespace scope (3.3.6) of the namespace std and are then injected into the global namespace scope by explicit using-declarations (7.3.3).

Earlier C++ standards read similarly.

My question is, when the C++ header #include<cname> uses overloaded functions, are all overloads brought in by #include<name.h>, since overloads aren't separate "names"?

And should the behavior of the following code differ between standard-compliant C and C++ compilers?

#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;
}

Compile-ready test cases:

  • C++ math.h and stdlib.h: http://ideone.com/pmD4t
  • C math.h and stdlib.h: http://ideone.com/Sflpn
  • C++ cmath and cstdlib: http://ideone.com/yI07m
  • C++ cmath only: http://ideone.com/KrS3W

From this test, C++ math.h acts like C and not like C++ cmath.

But on Visual C++ 2010, C++ math.h acts like C++ cmath.

And a compile-time canary for use with 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;
}

Result:

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 agrees with Visual C++.


回答1:


Yes, all overloads should be brought into the global namespace. My understanding is that the math.h header is intended to look something like:

// math.h:
#include <cmath>

using std::abs;
// etc.

So, yes: the behavior of your example program is different when compiled as a C program than when compiled as a C++ program. As a C++ program, it will call std::abs(double) from <math.h>. As a C program it will call abs(int) from <stdlib.h> (this is the only abs function in the C Standard Library, since C does not support function overloading).



来源:https://stackoverflow.com/questions/4405887/when-the-c-standard-provides-c-headers-bringing-names-into-the-global-namespac

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!