Когда стандарт C ++ предоставляет заголовки C, переносящие имена в глобальное пространство имен, включает ли это перегрузки? - PullRequest
6 голосов
/ 10 декабря 2010

В окончательном проекте комитета нового стандарта C ++ 0x говорится:

Каждый заголовок C, каждый из которых имеет имя формы name.h, ведет себя так, как если бы каждое имя помещалось встандартное пространство имен библиотеки с помощью соответствующего заголовка cname помещается в глобальную область имен.Не определено, будут ли эти имена сначала объявлены или определены в пределах области имен (3.3.6) пространства имен std, а затем введены в глобальную область имен с помощью явных объявлений using (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 ++ 2010C ++ 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".

Комо соглашается с Visual C ++.

1 Ответ

3 голосов
/ 10 декабря 2010

Да, все перегрузки должны быть перенесены в глобальное пространство имен.Насколько я понимаю, заголовок math.h должен выглядеть примерно так:

// math.h:
#include <cmath>

using std::abs;
// etc.

Итак, да: поведение вашей примерной программы отличается при компиляции как C-программы, чем при компиляции как C ++-программы,Как программа на C ++, она будет вызывать std::abs(double) из <math.h>.Как программа на C она будет вызывать abs(int) из <stdlib.h> (это единственная функция abs в стандартной библиотеке C, поскольку C не поддерживает перегрузку функций).

...