Область применения библиотек C в C ++ -против <cX> - PullRequest
5 голосов
/ 22 января 2010

Язык программирования C ++: Специальный выпуск на стр. 431 утверждает, что ...

For every header < X.h > defining part of the C standard library in the global namespace and also in namespace std, there is a header < cX > defining the same names in the std namespace only.

Однако, когда я использую заголовки C в стиле , мне не нужно определять пространство имен. Например ...

#include <cmath>
void f() {
  double var = sqrt( 17 );
}

Это хорошо скомпилируется. Хотя в книге говорится, что использование заголовка определяет имена только в пространстве имен std, вы можете использовать эти имена без определения пространства имен. Что мне здесь не хватает?

P.S. Использование компилятора GNU.GCC

Ответы [ 5 ]

9 голосов
/ 22 января 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-дефектs.html # 456 .

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

Я полностью согласен с Lavavej, за исключением того, что никогда не пытался быть очень осторожным с использованием заголовков в стиле <cfoo>, даже когда я впервые начал использовать C ++ - стандартные C были слишком укоренились - и никогда не было любая реальная проблема с их использованием (и, очевидно, никогда не было никакой реальной пользы от использования заголовков в стиле <cfoo>).

6 голосов
/ 22 января 2010

Правило для библиотек C отличается от библиотек C ++ для пространств имен

gcc интерпретирует стандарт в Gcc docs как

Стандарт определяет, что если один включает заголовок в стиле C (в данном случае ), символы будут доступны в глобальном пространстве имен и, возможно, в пространстве имен std :: (но это больше не фирма требование.) С другой стороны, включая заголовок в стиле C ++ () гарантирует, что сущности будут найдены в пространстве имен std и, возможно, в глобальном пространстве имен.

В проекте спецификации C0X ++ говорится в разделе 17.6.2.3 Заголовки

Не указано, были ли эти имена сначала объявлены в глобальной области пространства имен, а затем введены в пространство имен std с помощью явных объявлений using

4 голосов
/ 22 января 2010

Трудно исправить это, не реализовав дважды библиотеку C. См. DR 456 , в котором в основном предлагается отказаться от проблемы.

1 голос
/ 22 января 2010

Почему вы говорите «Это хорошо скомпилируется», если оно нарушает Стандарт? Кто позволяет использовать эти имена без определения пространства имен? Вы проверяли это на конкретной реализации и обнаружили, что она работает?

Я настоятельно не рекомендую использовать какую-то особую нестандартную функцию, потому что она работает на выбранном вами компиляторе. Такие вещи легко ломаются, возможно, с более поздней версией того же компилятора.

0 голосов
/ 22 января 2010

Возможно, вам не хватает компилятора, соответствующего стандартам (или тот, который вы используете, настроен на совместимость с предстандартным кодом).

...