C ++在全局命名空间中找不到非标准C函数

时间:2012-11-28 14:16:31

标签: c++ c ace

我们有一个相当大的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头之前被包含在内。

我不想修改库源代码,因为如果我们更新到更新的版本,它只会再次让我们感到厌烦。

3 个答案:

答案 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已经出来!:))。