Мой ответ приходит с опозданием, но добавляет кое-что, чего нет у других, так что начнем ....
Краткий ответ: остается неясным, позволяет ли стандарт стандартный заголовок C ++ включать стандартный заголовок C.
В других ответах правильно отмечено, что стандарт С ++
- позволяет использовать стандартный заголовок C ++
- для включения стандартного заголовка C ++.
Что остается неясным, так это является ли стандартный заголовок C стандартным заголовком C ++. Я могу предоставить доказательства обоими способами.
Почему заголовок C действительно является заголовком C ++
В GCC 6.24 со стандартной библиотекой C GNU 2.24 следующий тест не может быть скомпилирован.
#include <iostream>
namespace {
const int printf {42};
}
int main()
{
std::cout << printf << "\n";
return 0;
}
Компилятор жалуется, что «ссылка на printf неоднозначна», несмотря на то, что в тесте отсутствует явное #include <cstdio>
.
Мнение разработчиков такого крупного компилятора и стандартной библиотеки, как GCC и GNU, вряд ли следует игнорировать.
Другие ответы дали дополнительные причины, по которым мне не нужно здесь повторяться.
Почему заголовок C не является заголовком C ++
Стандарт C ++ 17 (черновик здесь), сноска 166, гласит:
[T] Заголовки C ++ для средств библиотеки C могут ... определять имена в глобальном пространстве имен.
Если бы заголовки C были заголовками C ++, тогда это было бы странным способом написать такую сноску, не так ли? Вместо этого можно было бы ожидать, что сноска будет начинаться такими словами, как «Заголовки не <*.h>
C ++ для средств библиотеки C ...»
Последнее наблюдение неубедительно, но в [res.on.headers] стандарт также гласит:
Заголовки стандартной библиотеки C должны включать только соответствующий заголовок стандартной библиотеки C ++ ....
Опять же, если бы заголовки C были заголовками C ++ по оценке человека, написавшего слова, то это могло бы показаться странным способом их написания.
Вывод: неоднозначный
К сожалению, как и другие ответчики, я не могу найти четкого ответа в стандартном тем или ином случае. В отличие от других респондентов, я бы пришел к выводу, что ответ остается неоднозначным. Соответствующие разделы в стандарте включают [content], [res.on.headers] и [depr.c.headers].
Мнение
Если вы хотите знать, какая альтернатива, на мой взгляд, имеет преимущественную силу, я бы не согласился с другими ответами. По указанным причинам я бы сказал, что стандарт не позволяет стандартному заголовку C ++ включать стандартный заголовок C. Такое включение противоречит обычному использованию C ++, во всяком случае, поскольку такое включение затрудняет использование анонимных глобальных пространств имен. [Измените printf
на foo
в моем тесте, а затем спросите, что произойдет, если будущая стандартная библиотека C добавит функцию foo()
. Такой эксперимент иллюстрирует проблему.]
С другой стороны, бороться со своим набором инструментов довольно бессмысленно, не так ли? До тех пор, пока не прояснится будущая версия C ++, я, например, хочу избегать анонимных глобальных пространств имен в исходных файлах, которые включают заголовки стандартных библиотек.
Я подозреваю, что, поскольку стандарт устарел от старых стилей, в которых используются стандартные заголовки C, комитет по стандартам, возможно, не слишком много думает о том, как исправить проблемы со старым стилем тем временем. Возможно, модули C ++ 20 дадут отличное решение. Мы увидим.
person
thb
schedule
11.03.2019