我们有一个相当大的C++项目,我现在正在迁移到VS2010,并且还在更新一些库.到目前为止,一切都建立得很好,除了我(对我来说)非常奇怪的错误,显然有很多(编辑:非)标准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
...
Run Code Online (Sandbox Code Playgroud)
这会影响我的以下功能和符号:
strdup getcwd O_WRONLY
putenv swab O_TRUNC
access unlink S_IFDIR
chdir mkdir S_IFREG
rmdir tempnam O_RDONLY
isascii
Run Code Online (Sandbox Code Playgroud)
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) || ... */
}
Run Code Online (Sandbox Code Playgroud)
上面和下面的其他函数有很多类似的部分,所有这些都编译得很好.
在我的案例中采取的路径是最后一个,即return ::strdup (s);.如果我在::strdupVS 上点击F12,请带我到string.hC标准库中的声明.
如果我删除它构建的命名空间限定符,虽然IntelliSense告诉我它现在是一个递归调用,所以它可能无法工作.如果我更改命名空间,std::我会得到大约270 个错误,这次来自其他几个项目.如果我将功能更改为::_strdup它构建.包括string.h因为第一件事情一无所获.
(Nota bene:"它构建"指的是"这个特定的编译器错误在该位置消失,但显然仍会留下其他函数的错误."
我在这里有点不知所措.我注意到,许多大型图书馆要么建立自己的抽象超过标准库或提供的东西是不存在默认情况下,这是一个点ACE和ImageMagick的冲突已经(在typedef荷兰国际集团ssize_t,但不兼容的定义).由于我们引入了相当多的库(我现在也没有确切的概述),这可能是由于错误的包含顺序和类似的事情引起的另一次冲突.这也是由ACE相同的事实暗示,在同一解决方案中,ACE在其他项目中表现得非常好.
任何人都知道我至少可以找到什么吗?构建日志/showIncludes只有24k行,所以我没有看到很多模式,除了string.h在有问题的ACE头之前包含的方式.
我不想修改库源代码,因为如果我们更新到更新的版本,它只会再次咬我们.
Mark B 的评论促使我查看 12 MiB 的预处理器输出,我能够解决这个问题。在string.h片段中strdup中,定义如下所示:
#if !__STDC__\n\n...\n\n_Check_return_ _CRT_NONSTDC_DEPRECATE(_strdup) _CRTIMP char * __cdecl strdup(_In_opt_z_ const char * _Src);\nRun Code Online (Sandbox Code Playgroud)\n\n碰巧这个项目定义了__STDC__导致大量非标准 C 但仍然在 C 标准库中的符号(谢谢,Rob \xcf\x86的挑剔,但没有解决问题)功能完全消失。
我知道它们已被弃用,我收到很多警告告诉我这一点。但如前所述,我不会维护针对第三方库的特定于项目的补丁,我们使用这些补丁只是为了在更新它们时再次获得相同的乐趣。
\n