При использовании заголовков C в С++ следует ли использовать функции из std:: или глобального пространства имен?
C является несколько не совсем подмножеством C++. Таким образом, мы можем использовать большинство функций/заголовков C в C++, немного изменив имя (stdio.h
на cstdio
, stdlib.h
на cstdlib
).
Мой вопрос на самом деле семантический. В коде C++ (с использованием новейшей версии компилятора GCC) я могу вызвать printf("Hello world!");
и std::printf("Hello world!");
и работает точно так же. И в ссылке, которую я использую, она также отображается как std::printf("Hello world!");
,
Мой вопрос заключается в том, предпочтительнее ли использовать std::printf();
в C++? Есть ли разница?
Ответы
Ответ 1
Из стандарта С++ 11 (ударный удар):
D.5 C стандартные заголовки библиотек [des.c.headers]
- Для совместимости со стандартной библиотекой C...
- Каждый заголовок C, каждый из которых имеет имя формы name.h, ведет себя так, как если бы каждое имя помещалось в стандартный пространство имен библиотек с помощью соответствующего заголовка cname помещается в область глобального пространства имен. не указано, объявлены или определены ли эти имена в области пространства имен (3.3.6) из пространства имен std и затем вводятся в глобальная область пространства имен с помощью явных использования-деклараций (7.3.3).
- Пример: заголовок
<cstdlib>
уверенно предоставляет свои декларации и определения в пространстве имен std
. Он также может предоставлять эти имена в глобальном пространстве имен. Заголовок <stdlib.h>
уверенно предоставляет те же декларации и определения в глобальном пространстве имен, что и в стандарте C. Это также могут предоставлять эти имена в пространстве имен std
.
Использование заголовков "name.h" устарело, они были идентифицированы как кандидаты для удаления из будущих версий.
Итак, я бы предложил включить заголовки "cname" и использовать объявления и определения из пространства имен std
.
Если вам нужно использовать заголовки "name.h" по некоторым причинам (это устарело, см. выше), я бы предложил использовать декларации и определения из глобального пространства имен.
Другими словами: предпочитайте
#include <cstdio>
int main() {
std::printf("Hello world\n");
}
над
#include <stdio.h>
int main() {
printf("Hello world\n");
}
Ответ 2
<cmeow>
всегда предоставляет ::std::purr
и может или не может предоставить ::purr
.
<meow.h>
всегда предоставляет ::purr
и может или не может предоставить ::std::purr
.
Используйте форму, которая, как гарантируется, предоставляется заголовком, который вы включаете.
Ответ 3
Нет, ты в порядке.
Первоначально предполагалось, что заголовки <___.h>
будут версиями C, которые помещают все в глобальное пространство имен, а заголовки <c___>
будут версиями С++, которые помещают все в пространство имен std
.
На практике, однако, версии С++ также помещают все в глобальное пространство имен. И нет четкого консенсуса в том, что использование версий std::
- "правильная вещь".
Итак, в основном, используйте то, что вы предпочитаете. Наиболее распространенным, вероятно, является использование стандартных библиотечных функций C в глобальном пространстве имен (printf
вместо std::printf
), но не так много причин считать один "лучше", чем другой.
Ответ 4
Единственное отличие заключается в том, что в std::printf()
путем добавления разрешения std::
разрешений вы сможете защитить себя от того, кто в будущем будет писать функцию с таким же именем, что приведет к конфликту пространства имен. Оба использования приведут к точно таким же вызовам OS API (вы можете проверить его в Linux, запустив strace your_program
).
Мне очень маловероятно, что кто-то назвал бы такую функцию, поскольку printf()
является одной из наиболее часто используемых функций. Кроме того, в С++ для cstdio
используются функции iostream
, такие как printf.
Ответ 5
Из стандарта С++ 11:
Каждый заголовок C, каждый из которых имеет имя формы name.h, ведет себя как если бы каждое имя помещалось в пространство имен стандартной библиотеки соответствующий заголовок cname помещается в глобальное пространство имен объем. Не указано, объявлены ли эти имена сначала или определенные в пространстве пространства имен (3.3.6) пространства имен std и являются затем вводится в область глобального пространства имен явным Использование-декларации (7.3.3).
Итак, если вы используете <cstdio>
, вы можете быть уверены, что printf
будет в namespace std
и, следовательно, не в глобальном пространстве имен.
Использование глобального пространства имен создает конфликт имен. Это не С++-способ.
Поэтому я использую заголовки <cstdio>
и советую вам это сделать.
Ответ 6
Из моей собственной практики: используйте префиксы std::
. В противном случае один день abs
будет укусить вас очень больно, если вы используете плавающие точки.
Неквалифицированный abs
относится к функции, определенной на int
на некоторых платформах. На других он перегружен. Однако std::abs
всегда перегружается для всех типов.
Ответ 7
Использование только printf
без std::
может генерировать некоторые конфликты имен и считается плохой практикой для многих разработчиков С++. Google - ваш друг на этом, но вот некоторые ссылки, надеюсь, что это поможет
Почему" using namespace std " считается плохой практикой?
http://www.cplusplus.com/forum/beginner/61121/
Ответ 8
В stdio
Это версия С++ для библиотеки Standard C Library @c stdio.h, и его содержимое (в основном) такое же, как и этот заголовок, но все содержащихся в пространстве имен @c std (кроме имен, которые определены как макросы в C).
Так что это не должно иметь никакого значения.