Почему Windows и Linux имеют разные реализации strdup: strdup () и _strdup ()? - PullRequest
2 голосов
/ 10 февраля 2020

При работе с strdup на Windows я обнаружил, что _strdup - это Windows speci c, но когда я запустил тот же код на Linux, потребовалось strdup без подчеркивания. Кто-нибудь знает историю этого различия, а также некоторую информацию о том, как вы справились с этой проблемой при написании кросс-платформенного кода?

1 Ответ

2 голосов
/ 10 февраля 2020

Есть несколько функций, которые являются частью спецификации POSIX, то есть Linux и большинство других вариантов UNIX, которые не являются частью стандарта C. К ним относятся strdup, write, read и др.

Основное подчеркивание приведено ниже, взято из документов MSDN :

Универсальная C библиотека времени выполнения (UCRT) поддерживает большую часть стандартной библиотеки C, необходимой для соответствия C ++. Он реализует библиотеку C99 (ISO / IEC 9899: 1999), за некоторыми исключениями: макросы общего типа, определенные в, и строгая совместимость типов в. UCRT также реализует большое подмножество библиотеки POSIX.1 (ISO / IEC 9945-1: 1996, интерфейс прикладного программного обеспечения системы POSIX) C. Однако он не полностью соответствует какому-либо конкретному c стандарту POSIX. UCRT также реализует несколько специфических для Microsoft функций и макросов, которые не являются частью стандарта.

Функции, указывающие c на Реализация Microsoft Visual C ++ находится в библиотеке vcruntime. Многие из этих функций предназначены для внутреннего использования и не могут быть вызваны кодом пользователя. Некоторые документированы для использования при отладке и совместимости реализации.

Стандарт C ++ резервирует имена, которые начинаются с подчеркивания в глобальном пространстве имен для реализации. Как функции POSIX, так и специфичные для Microsoft функции c библиотеки времени выполнения находятся в глобальном пространстве имен, но не являются частью стандартной библиотеки времени выполнения C. Вот почему предпочтительные реализации этих функций в Microsoft имеют ключевое подчеркивание. Для переносимости UCRT также поддерживает имена по умолчанию, но компилятор Microsoft C ++ выдает предупреждение об устаревании при компиляции кода, который их использует. Только имена по умолчанию устарели, а не сами функции. Чтобы подавить предупреждение, определите _CRT_NONSTDC_NO_WARNINGS, прежде чем включать любые заголовки в код, который использует оригинальные имена POSIX.

Я справился с этим, имея #define, который проверяет, компилируется ли программа для Windows, и, если это так, создает еще один #define, чтобы сопоставить имя POSIX с Windows конкретное c имя. Есть несколько вариантов, которые вы можете проверить, хотя, вероятно, наиболее надежным является _MSC_VER, который определяется, если MSV C является компилятором.

#ifdef _MSC_VER
#define strdup(p) _strdup(p)
#endif
...