Таким образом, это - что-то, что я всегда задавался вопросом, но никогда не было совершенно уверено в. Таким образом, это - строго вопрос любопытства, не настоящая проблема.
Насколько я понимаю, whenyou делают что-то как #include <cstdlib>
все (кроме макросов, конечно) объявляется в std::
пространство имен. Каждая реализация, которую я когда-либо видел, делает это путем выполнения чего-то как следующее:
#include <stdlib.h>
namespace std {
using ::abort;
// etc....
}
Который, конечно, имеет эффект вещей, находящихся и в глобальном пространстве имен и в std
. Это поведение гарантируется? Или действительно ли возможно, что реализация могла вставить эти вещи std
но не в глобальном пространстве имен? Единственным путем я могу думать, чтобы сделать, который должен был бы иметь Ваш libstdc ++, реализуют каждую функцию c саму размещение их в std
непосредственно вместо только включая существующие libc заголовки (потому что нет никакого механизма для удаления чего-то из пространства имен). Который является, конечно, большим усилием с мало ни к какому преимуществу.
Сущность моего вопроса, следующая программа строго соответствует и гарантируемая работать?
#include <cstdio>
int main() {
::printf("hello world\n");
}
Править: Самое близкое, которое я нашел, является этим (17.4.1.2p4):
За исключением отмеченного в пунктах 18 - 27, контент каждого заголовка cname должен совпасть с контентом соответствующего заголовка name.h, как указано на Языках программирования ISO/IEC 9899:1990 C (Пункт 7) или Языки программирования ISO/IEC:1990 — C ПОПРАВКА 1: C Целостность, (Пункт 7), как соответствующий, как будто включением. В C + + Стандартная Библиотека, однако, объявления и определения (за исключением имен, которые определяются как макросы в C) в объеме пространства имен (3.3.5) из станд. пространства имен.
чтобы быть честным, я мог интерпретировать так или иначе. "контент каждого заголовка cname должен совпасть с контентом соответствующего заголовка name.h, как указано на Языках программирования ISO/IEC 9899:1990 C" говорит мне, что они могут требоваться в глобальном пространстве имен, но "В C + + Стандартная Библиотека, однако, объявления и определения (за исключением имен, которые определяются как макросы в C) в объеме пространства имен (3.3.5) из станд. пространства имен," говорят они, находятся в станд. (но не указывает, что любой другой определил объем, они находятся в).
Вот хороший синопсис ситуации (с некоторыми реляциями по сравнению с тем, что говорит стандарт) от Stephan T. Lavavej из команды MSVC (http://blogs.msdn.com/vcblog/archive/2008/08/28/the-mallocator.aspx#8904359):
>
также,,
, и
std::size_t
и т.д. должны быть использованы!Раньше я был очень внимателен к этому. В C++98 был великолепный сон, в котором
объявлял все в пространстве имен std, а
включал
и затем перетаскивал все в глобальное пространство имен с помощью using-declarations. (Это D.5 [depr.c.headers].)
Это было проигнорировано многими реализаторами (некоторые из которых имели очень мало контроля над заголовками стандартной библиотеки C). Таким образом, C++0x был изменен, чтобы соответствовать реальности. Начиная с рабочего документа N2723, http://open-std.org/jtc1/sc22/wg21/docs/papers/2008/n2723.pdf , теперь
гарантированно объявляет все в пространстве имен std, и может или не может объявлять вещи в глобальном пространстве имен.
наоборот: он гарантированно объявляет все в глобальном пространстве имен, и может объявлять или не объявлять вещи в пространстве имен std.
В реальности и в C++0x включение
не является гарантией от того, что все будет объявлено в глобальном пространстве имен. Вот почему я перестаю заморачиваться с
.
Это был Library Issue 456, http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-defects.html#456 .
(C++0x все еще устаревает заголовки из стандартной библиотеки C, что просто умора.)
Мне самому никогда не нравились заголовки
, и я обнаружил, что всегда использовал
. Теперь я чувствую, что могу перестать беспокоиться о своей недостаточной "чистоте" C++ в этом отношении.
Я не могу говорить о стандартах, так как я их не читал, но можно было представить среда C ++, которая не построена поверх среды C, или где среда C является уровнем совместимости поверх базовых API C ++. В таком случае эти гарантии не могут быть предоставлены. Я был бы удивлен, если бы такой реализации запретили быть совместимой реализацией.
В настоящее время нет. Фактически, хотя код будет работать со всеми компиляторами, которые я сейчас использую, на самом деле он не должен работать вообще - #include
только один из заголовков c * предполагается чтобы предоставить вам доступ к именам внутри пространства имен std.
Поскольку реализация этого была такой сложной задачей (для правильного решения потребовалось дублировать всю библиотеку C как библиотеку C ++ в правильном пространстве имен), в C ++ 0x требования немного изменились - теперь ваш код позволил работать, хотя (по крайней мере, если не изменяет память) он все еще не работал.