Стандарт языка C ++ говорит в D.5
2 Каждый заголовок C, каждый из которых имеет имя в форме
name.h
, ведет себя так, как если бы каждое имя, помещенное в пространство имен стандартной библиотеки соответствующим заголовкомcname
, помещалось в область глобального пространства имен. Не указано, объявляются ли эти имена сначала или определяются в пределах области действия пространства имен (3.3.6) пространства именstd
, а затем вводятся в глобальную область пространства имен явными объявлениями using (7.3.3).3 [Пример: заголовок
<cstdlib>
несомненно предоставляет свои объявления и определения в пространстве именstd
. Он также может предоставлять эти имена в глобальном пространстве имен. Заголовок<stdlib.h>
, несомненно, предоставляет те же объявления и определения в глобальном пространстве имен, как и в стандарте C. Он также может предоставлять эти имена в пространстве имен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 стандартное требование в отношении устаревших заголовков в старом стиле? Или я как-то неправильно интерпретирую формулировку в стандарте?
extern "C"
связь с именами из стандартной библиотеки C, объявленной с внешней связью (хотя он рекомендует этого не делать). Если бы реализация сделала это, она не смогла бы определить три разные версииsin()
. - person Crowman   schedule 07.11.2014#ifdef __cplusplus
всегда может спасти положение. - person AnT   schedule 07.11.2014std::sin
? Во-первых, вопрос касаетсяsin
вmath.h
, а неstd::sin
. Во-вторых, хотя это и не тема, стандарт C ++ фактически заявляет, чтоmath.h
разрешено дополнительно предоставлять эти имена в пространстве именstd
(см. Стандартную цитату выше) - person AnT   schedule 07.11.2014<name.h>
. На самом деле это даже отдаленно не так. - person AnT   schedule 07.11.2014