Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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

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++.

like image 569
Ben Voigt Avatar asked Dec 10 '10 05:12

Ben Voigt


1 Answers

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).

like image 195
James McNellis Avatar answered Nov 09 '22 22:11

James McNellis