функции C объявлены взаголовки гарантированно находятся в глобальном пространстве имен, а также std? - PullRequest
16 голосов
/ 06 апреля 2010

Так что это то, что я всегда удивлялся, но никогда не был полностью уверен в этом. Так что это просто вопрос любопытства, а не настоящая проблема.

Насколько я понимаю, когда вы делаете что-то вроде #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, а указано в ИСО / МЭК 9899: 1990 Языки программирования C (раздел 7) или ISO / IEC: 1990 Языки программирования - C ПОПРАВКА 1: C Целостность, (пункт 7), в зависимости от обстоятельств, как будто путем включения. В Стандартная библиотека C ++, однако, декларации и определения (за исключением имен, которые определены как макросы в C) находятся в пространстве имен область действия (3.3.5) пространства имен std.

Честно говоря, я мог бы интерпретировать так или иначе. «содержимое каждого заголовка cname должно быть таким же, как и содержимое соответствующего заголовка name.h, как указано в ISO / IEC 9899: 1990 Языки программирования C», говорит мне, что они могут потребоваться в глобальном пространстве имен, но «В C ++ Standard Library, однако, объявления и определения (кроме имен которые определены как макросы в C) находятся в пределах области имен (3.3.5) пространства имен std. "говорит, что они находятся в std (но не указывает никакой другой области видимости, в которой они находятся).

Ответы [ 3 ]

9 голосов
/ 07 апреля 2010

Вот хороший краткий обзор ситуации (с некоторой зависимостью от того, что говорит стандарт) от Стефана Т. Лававея из команды MSVC (http://blogs.msdn.com/vcblog/archive/2008/08/28/the-mallocator.aspx#8904359):

> также следует использовать <cstddef>, <cstdlib> и std::size_t и т. Д.!

Раньше я был очень осторожен с этим. У C ++ 98 был великолепный сон, в котором <cfoo> объявлял бы все в пространстве имен std, а <foo.h> включал бы <cfoo>, а затем перетаскивал все в глобальное пространство имен с помощью деклараций использования. (Это D.5 [depr.c.headers].)

Это было проигнорировано многими разработчиками (некоторые из которых имели очень слабый контроль над заголовками стандартной библиотеки C). Итак, C ++ 0x был изменен, чтобы соответствовать реальности. Что касается рабочего документа N2723, http://open -std.org / jtc1 / sc22 / wg21 / docs / documents / 2008 / n2723.pdf , теперь <cfoo> гарантированно объявляет все в пространстве имен std, и может или не может объявить вещи в глобальном пространстве имен. <foo.h> - наоборот: он гарантированно объявляет все в глобальном пространстве имен и может или не может объявлять вещи в пространстве имен std.

На самом деле и в C ++ 0x, включая <cfoo>, в любом случае нет никакой гарантии против того, чтобы все было объявлено в глобальном пространстве имен. Вот почему я перестаю беспокоиться о <cfoo>.

Это был выпуск 456 Библиотеки, http://www.open -std.org / jtc1 / sc22 / wg21 / docs / lwg -fects.html # 456 .

(C ++ 0x все еще не поддерживает заголовки из стандартной библиотеки C, что очень весело.)

Мне никогда не нравились заголовки <cfoo>, и я обнаружил, что всегда использую <foo.h>. Теперь я чувствую, что могу перестать беспокоиться об отсутствии у C ++ «чистоты» в этом отношении.

4 голосов
/ 06 апреля 2010

В настоящее время нет.На самом деле, хотя код будет работать с каждым компилятором, из которого я сейчас работаю, он действительно , а не должен работать вообще - #include, если один из заголовков c * должен только дать вам доступ кимена внутри пространства имен std.

Поскольку реализация этого была такой трудной задачей (для ее правильной работы по сути требовалось дублирование всей библиотеки C в виде библиотеки C ++ в правильном пространстве имен), в C ++ 0x они изменилиНемного требований - ваш код теперь разрешен для работы, хотя (по крайней мере, если память служит) все равно работать не требуется.

0 голосов
/ 06 апреля 2010

Я не могу говорить о стандартах, так как я не читал их, но можно представить себе среду C ++, которая не построена поверх среды C, или где среда C представляет собой слой совместимости поверх базовых API-интерфейсов C ++ , В таком случае эти гарантии не могут быть предоставлены. Я был бы удивлен, если бы такая реализация была запрещена как совместимая реализация.

...