Стандарт языка C ++ говорит в Д.5
2 Каждый заголовок C, каждый из которых имеет имя вида
name.h
ведет себя
как если бы каждое имя помещалось в пространство имен стандартной библиотеки
соответствующийcname
заголовок находится в глобальном пространстве имен
объем. Не указано, были ли эти имена впервые объявлены или
определено в рамках пространства имен (3.3.6) пространства именstd
и являются
затем вводится в глобальную область имен
декларации использования (7.3.3).3 [Пример: заголовок
<cstdlib>
безусловно, предоставляет свои декларации и определения в рамках
Пространство именstd
, Он также может предоставить эти имена в глобальном
Пространство имен. Заголовок<stdlib.h>
гарантированно обеспечивает то же самое
объявления и определения в глобальном пространстве имен, так же как и в
Стандарт С Он также может предоставлять эти имена в пространстве имен
std
, — конец примера]
Это, кажется, довольно явно заявляет («… каждое имя …», «… те же объявления …»), что в старом стиле <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 просто игнорирует стандартное требование в отношении устаревших заголовков старого стиля? Или я как-то неверно истолковал формулировку в стандарте?
Благодаря комментариям @ hvd я увидел свет, оказалось, что MSVC верен, и GCC должен также жаловаться на неоднозначность.
Единственные различия между в том числе <cmath>
против <math.h>
где имена изначально ограничены, что находится в namespace std
для первого и глобальное пространство имен для второго (реализации могут предоставлять имена и в другом пространстве имен, но это не обязательно), а также тот факт, что включение .h
варианты заголовков C не рекомендуется.