未声明“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.
<cstring>
和 <string.h>
都会导致错误。我还尝试了包含<cstdlib>
和<stdlib.h>
,它们导致了同样的错误。
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】:您应该尝试包含<string.h>
并使用不合格的memset
。根据IBM XL C/C++ Programming Guide,_debug_memset
住在string.h
。那么问题就变成了,<cstring>
不应该通过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”的主要内容,如果未能解决你的问题,请参考以下文章
架构 armv7 的未定义符号 - route-me 库,仅限临时
Netbeans 7.2.1 mac javadoc 未找到 Java Me