При использовании заголовков 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).

Так что это не должно иметь никакого значения.