我们有一个相当大的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
...
这会影响我的以下功能和符号:
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);
。如果我在::strdup
VS上点击F12,则会转到C标准库的string.h
中的声明。
如果我删除它构建的命名空间限定符,虽然IntelliSense告诉我它现在是一个递归调用,所以它可能不起作用。如果我将命名空间更改为std::
,我会得到大约270个更多错误,这次来自其他几个项目。如果我将函数更改为::_strdup
,则构建它。包括string.h
在内的第一件事情一无变化。
(Nota bene:“it builds”指的是“这个特定的编译器错误在该位置消失,但显然仍会留下其他函数的错误。”
我在这里有点不知所措。我注意到许多较大的库要么在标准库上构建自己的抽象,要么提供默认情况下不存在的东西,这是ACE和ImageMagick已经发生冲突的一点(在typedef
ssize_t
/showIncludes
中与不相容的定义)。由于我们引入了相当多的库(我现在也没有确切的概述),这可能是由于错误的包含顺序和类似的事情引起的另一次冲突。这也是由于ACE在同一解决方案中的其他项目中可以正常工作的事实所暗示的。
任何人都知道我至少可以找到什么吗? string.h
的构建日志只有24k行,所以我没有看到很多模式,除了{{1}}在有问题的ACE头之前被包含在内。
我不想修改库源代码,因为如果我们更新到更新的版本,它只会再次让我们感到厌烦。
答案 0 :(得分:4)
“许多标准C函数和符号未定义”
strdup
不是标准的C函数。它在POSIX中定义,但不在C或C ++中定义。引用MSDN:
从Visual C ++ 2005开始,不推荐使用这些POSIX函数。请改用ISO C ++符合_strdup,_wcsdup,_mbsdup。
在我看来,您列出的符号都不是标准C函数。
答案 1 :(得分:1)
Mark B的评论促使我看看12 MiB的预处理器输出,我能够解决它。在string.h
中,定义strdup
的代码段如下所示:
#if !__STDC__
...
_Check_return_ _CRT_NONSTDC_DEPRECATE(_strdup) _CRTIMP char * __cdecl strdup(_In_opt_z_ const char * _Src);
碰巧这个单一项目定义了__STDC__
符号,导致了很多非标准的C但仍然在C标准库中(谢谢,Rob φ 用于挑剔但不解决问题)功能完全消失。
我知道他们已经被弃用了,我收到了很多告诉我的警告。但是如上所述,我不会维护第三方库的项目特定补丁,如果我们更新它们,我们只是为了获得相同的乐趣。
答案 2 :(得分:0)
如果我正确理解VS,那么{@ 1}}等功能名称现在已被弃用(我认为不符合POSIX标准)。您应该使用带下划线的版本。
当我遇到这种情况时,我进行了全局搜索并进行了替换,因为它似乎是一件明智的事情,并且保持源代码在未来的良好状态(VS 2012已经出来!:))。