未声明“std::_debug_memset”

Posted

技术标签:

【中文标题】未声明“std::_debug_memset”【英文标题】:"std::_debug_memset" is not declared 【发布时间】:2019-04-24 14:15:02 【问题描述】:

我正在编译农场研究 GCC119。该机器是 AIX 7.1、POWER8 和 IBM XLC 13.1。我正在尝试使用调试堆:

gcc119$ cat test.cxx
#include <altivec.h>
#undef vector
#undef pixel
#undef bool

#include <cstdlib>

int main(int argc, char* argv[])

  unsigned char x[32];
  std::memset(x, 0x00, 32);

  return 0;

编译结果:

gcc119$ xlC -DDEBUG -g3 -O0 -qheapdebug -qro test.cxx -o test.exe
"test.cxx", line 11.3: 1540-0130 (S) "std::_debug_memset" is not declared.

&lt;cstring&gt;&lt;string.h&gt; 都会导致错误。我还尝试了包含&lt;cstdlib&gt;&lt;stdlib.h&gt;,它们导致了同样的错误。

Optimization and Programming Guide 手册对调试内存函数有很好的讨论,但处理方法仅限于 C。它似乎不处理 C++。

如何在 C++ 程序中使用调试堆?


gcc119$ oslevel -s
7200-00-01-1543

gcc119$ xlC -qversion
IBM XL C/C++ for AIX, V13.1.3 (5725-C72, 5765-J07)
Version: 13.01.0003.0004

【问题讨论】:

我可能已经说过,即使在 MS Windows 或 GnuLinux 等流行平台上,C++ 也是有问题的,但在 AIX 等外来平台上,它是彻头彻尾的致命问题。还有 gcc 的 include-fixed 头文件:它们通常与它们默默替换的实际头文件不匹配。 gcc.gnu.org/onlinedocs/gcc/Fixed-Headers.html 解决方法:(std::memset)(x, 0x00, 32);。如果可能,请在 MSVC++、Clang 或 G++ 等普通系统上进行开发,然后移植到 XLC。不要尝试在此类外来对象上调试堆错误。 @MSalters - 谢谢。是的,我们使用Analysis Tools 中描述的工具在 BSD、Linux、OS X、Solaris 和 Windows 上很干净。我们正在尝试追查 PowerPC 上 Clang 7.0 自检失败的原因。 Clang 7.0 是最新的,我刚刚从平台的源代码中构建它。我怀疑这是一个有问题的编译器(我们已经提交了一些错误,比如LLVM Issue 39704)。 @MSalters - Nemanja Ivanovic 针对问题 39704 的 LLVM 补丁修复了失败的自测。似乎 Clang 正在删除我们的一些加载和存储,因为 LLVM 函数的注释不正确。 LLVM 认为它们需要 16 字节对齐,而它们只需要 1 字节对齐。 【参考方案1】:

根据@user10688376 的观察,这是我想出的。我认为这是技术上未定义的行为,因为我不允许将 _debug_memset_debug_memcpy 之类的符号放在 std 命名空间中。在这一点上,潜在的 UB 比编译失败且没有测试要好。

#if defined(_AIX) && (defined(__xlc__) || defined(__xlC__) || defined(__ibmxl__))
# if defined(__DEBUG_ALLOC__)
namespace std 
  using ::_debug_memset;
  using ::_debug_memcpy;

# endif
#endif

_AIX 被使用是因为它标识了操作系统。调试堆在 Linux 设备上不可用。 (一些 IBM XLC 编译器也在 Linux 上运行)。

__xlc____xlC__ 用于检测 IBM XLC 编译器 13.0 及更早版本。该编译器完全由 IBM 构建。

__ibmxl__ 用于检测 IBM XLC 编译器 13.1 及更高版本。此编译器使用 Clang 前端和 IBM 后端。我认为这是LLVM Review 21078中提到的“LLC”编译器。

之所以使用__DEBUG_ALLOC__,是因为编译器将其设置为-qheapdebug

【讨论】:

【参考方案2】:

您应该尝试包含&lt;string.h&gt; 并使用不合格的memset。根据IBM XL C/C++ Programming Guide,_debug_memset 住在string.h。那么问题就变成了,&lt;cstring&gt; 不应该通过std:: 提供它吗?在IBM XL C/C++ Standard Library reference中,显示了所有的using声明,没有调试功能。

namespace std

using ::size_t; using ::memcmp; using ::memcpy; using ::memmove;
using ::memset; using ::strcat; using ::strcmp; using ::strcoll;
using ::strcpy; using ::strcspn; using ::strerror; using ::strlen;
using ::strncat; using ::strncmp; using ::strncpy; using ::strspn;
using ::strtok; using ::strxfrm;

【讨论】:

来自该手册:“这些功能将在未来的版本中删除”。让它发挥作用可能不值得麻烦,只是在 2019 年移除整个机制。

以上是关于未声明“std::_debug_memset”的主要内容,如果未能解决你的问题,请参考以下文章

在 J2ME 中未播放通知声音

架构 armv7 的未定义符号 - route-me 库,仅限临时

Netbeans 7.2.1 mac javadoc 未找到 Java Me

在 J2ME 项目 (Netbeans 6.9.1) 中未检测到预处理器块

VB:“Me” “.”与“!

无法声明 USB 接口(设备或资源繁忙)卡住