C++ не может найти нестандартные функции C в глобальном пространстве имен

У нас есть довольно большой проект C++, который я сейчас перехожу на VS2010, а также обновляю несколько библиотек. Пока что все строится просто отлично, за исключением того, что я получаю (для меня) довольно странные ошибки, когда явно не определено количество (edit: non-) стандартных функций и символов C:

error C2039: 'strdup' : is not a member of '`global namespace''    ...\ACE_wrappers\ace\OS_NS_string.inl    222
...
error C2065: 'O_WRONLY' : undeclared identifier                    ...\ACE_wrappers\ace\OS_NS_unistd.inl    1057
...

Это влияет на следующие функции и символы для меня:

strdup      getcwd      O_WRONLY
putenv      swab        O_TRUNC
access      unlink      S_IFDIR
chdir       mkdir       S_IFREG
rmdir       tempnam     O_RDONLY
isascii

Одна часть во включаемом файле от ACE, с которым я экспериментировал, была strdup часть, которая выглядит так:

ACE_INLINE char *
ACE_OS::strdup (const char *s)
{
#  if (defined (ACE_LACKS_STRDUP) && !defined(ACE_STRDUP_EQUIVALENT)) \
  || defined (ACE_HAS_STRDUP_EMULATION)
  return ACE_OS::strdup_emulation (s);
#  elif defined (ACE_STRDUP_EQUIVALENT)
  return ACE_STRDUP_EQUIVALENT (s);
#  elif defined (ACE_HAS_NONCONST_STRDUP)
  return ::strdup (const_cast<char *> (s));
#else
  return ::strdup (s);
#  endif /* (ACE_LACKS_STRDUP && !ACE_STRDUP_EQUIVALENT) || ... */
}

Существует множество похожих разделов для других функций выше и ниже, и все они прекрасно компилируются.

Путь, выбранный в моем случае, является последним, т.е. return ::strdup (s);, Если я нажму F12 на ::strdup VS принимает меня к декларации в string.h стандартной библиотеки C.

Если я удаляю классификатор пространства имен, который он создает, хотя IntelliSense говорит мне, что теперь это рекурсивный вызов, поэтому он, вероятно, не будет работать. Если я изменю пространство имен на std:: Я получаю еще около 270 ошибок, на этот раз из нескольких других проектов. Если я изменю функцию на ::_strdup это строит. В том числе string.h как самая первая вещь ничего не меняет.

(Примечание: "он собирает" относится к "эта конкретная ошибка компилятора исчезает в этом месте, но, тем не менее, она оставляет ошибки о других функциях, очевидно.)

Я немного растерялся здесь. Я заметил, что многие более крупные библиотеки либо строят свою собственную абстракцию над стандартной библиотекой, либо предоставляют вещи, которых нет по умолчанию, и это было той точкой, где ACE и ImageMagick уже конфликтовали (в обоих typedef ИНГ ssize_t но с несовместимыми определениями). Поскольку мы задействуем довольно много библиотек (сейчас у меня нет точного обзора), это может быть еще одно столкновение, вызванное неправильным порядком включения и подобными вещами. На это также намекает тот факт, что то же самое из ACE явно работает нормально в других проектах в том же решении.

У кого-нибудь есть идея, что я мог бы искать здесь, по крайней мере? Журнал сборки с /showIncludes просто 24k строк, поэтому я не вижу там много паттернов, кроме того, что string.h включается задолго до проблемного заголовка ACE.

И я не хотел бы изменять исходный код библиотеки, так как он снова укусит нас, если мы обновимся до более новой версии.

3 ответа

Решение

С комментарием Марка Б, который побудил меня посмотреть на 12 Мбайт производительности препроцессора, я смог ее решить. В string.h фрагмент где strdup определяется выглядит так:

#if     !__STDC__

...

_Check_return_ _CRT_NONSTDC_DEPRECATE(_strdup) _CRTIMP char * __cdecl strdup(_In_opt_z_ const char * _Src);

Так получилось, что этот единственный проект определяет __STDC__ символ, который приводит к полному исчезновению множества нестандартных функций библиотеки C-C-But-все-таки-в-C-стандарте (спасибо Робу за придирчивость, но не решение проблемы).

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

"ряд стандартных функций и символов C не определены"

strdup не является стандартной функцией C. Он определен в POSIX, но не в C или C++. Цитирование MSDN:

Эти функции POSIX устарели, начиная с Visual C++ 2005. Вместо этого используйте совместимый с ISO C++ _strdup, _wcsdup, _mbsdup.

Мне кажется, что ни один из перечисленных вами символов не является стандартными функциями C.

Если я правильно понимаю VS, то strdupи т. д. в настоящее время имена функций устарели (я думаю, что они не соответствуют POSIX). Вы должны использовать подчеркнутые версии.

Когда это случилось со мной, я запустил глобальный поиск и замену, так как это казалось разумным делом и поддерживает исходный код в хорошем состоянии на будущее (VS 2012 уже вышел!:)).

Другие вопросы по тегам