2014-11-06 2 views
5
стандартный язык

C++ говорит в D.5Наследство стандартной библиотеки C заголовки и перегруженные функции C++

Каждый C заголовок, каждый из которых имеет имя вида name.h, ведет себя , как если бы каждое имя, помещенное в стандартное пространство имен библиотек на соответствующий заголовок cname, помещается в область глобального пространства имен . Неизвестно, объявлены ли эти имена сначала или , определенные в области пространства имен (3.3.6) пространства имен std, и являются , а затем введены в область глобального пространства имен явным образом с использованием-деклараций (7.3.3).

[Пример: Заголовок <cstdlib> уверенно предоставляет свои декларации и определения в пространстве имен std. Он также может предоставлять эти имена в глобальном пространстве имен . Заголовок <stdlib.h>, безусловно, предоставляет те же декларации и определения в глобальном пространстве имен, как и в C-стандарте. Он также может предоставлять эти имена в пространстве имен std. -end пример]

Это, кажется, утверждать довольно явно («... каждое имя ...„“... один и то же заявление ...»), что старый стиль <name.h> заголовков должны предоставить тот же набор объявлений, что и заголовки <cname> нового стиля, но в глобальном пространстве имен. Исключение для C++ - специфических перегруженных версий различных функций C, например, не делается.

Это, как представляется, означает, что <math.h> должен предоставить три версии sin функции: sin(float), sin(double) и sin(long double) в глобальном пространстве имен. Это, в свою очередь, означает, что следующий C++ код должен обязательно разрешение

#include <math.h> 

int main() { 
    sin(1); 
} 

перегрузки Это не разрушаться под компилятором MSVC++, но он успешно компилируется под GCC и Clang. Итак, GCC просто игнорирует стандартное требование в отношении устаревших заголовков старого стиля? Или я как-то неправильно истолковал формулировку в стандарте?

+0

Раздел 17.6.2.3.1 позволяет реализации предоставлять «extern» C «привязку к именам из стандартной библиотеки C, объявленной с внешней связью (хотя она не рекомендует этого делать). Если бы реализация сделала это, он не смог бы определить три разные версии 'sin()'. –

+0

Я думаю, вы хотели сказать должны предоставить три версии. , , так как math.h - это заголовочный файл C. Поэтому, имея в виду, проблем с перегрузкой не будет, поскольку существует только одна версия греха, но три из std :: sin. – iheanyi

+0

@iheanyi: файлы заголовков могут быть легко перекрестно скомпилированы между C и C++.Если ничего не работает, '#ifdef __cplusplus' всегда может сохранить день. – AnT

ответ

2

Благодаря комментариям @ hvd я видел свет, оказывается, что MSVC является правильным, и GCC также должен жаловаться на двусмысленность.

Единственное различие между включая <cmath> против <math.h> находится там, где имена изначально области видимости, которая находится в namespace std для первого, и глобального пространства имен для последних (реализаций могут свободно предоставлять имена в другом пространстве имен, а также, но это не является обязательным), и тот факт, что включение вариантов заголовков C не соответствует требованиям .h.

+0

Да, но как это согласуется с тем, что говорит D.5? В основном он говорит, что 'math.h' должен предоставлять те же объявления, что и' cmath'. – AnT

+0

@AndreyT [заголовки] "4 ** За исключением случаев, указанных в пунктах с 18 по 30 и приложении D **, содержимое каждого заголовка cname должно быть таким же, как содержимое соответствующего заголовка name.h, [...]" , Я предполагаю, что формулировка неоднозначна в D.5. – user657267

+0

@AndreyT Подумайте об этом, это не двусмысленно: «В дополнение к двойным версиям математических функций в « перегрузки не являются технически частью '' вообще. Наверное, они волшебным образом включены в препроцессорную фею. – user657267

Смежные вопросы