【发布时间】:2017-01-19 16:16:04
【问题描述】:
一不小心,写了如下有趣的sn-p:
#include <iostream>
#include <cstring>
size_t strlen(const char* str) {
std::cout << "hello";
return 0;
}
int main() {
return std::strlen("sdf");
}
出乎我意料的是,GCC 5.1 中的输出是“hello”,这意味着我的 strlen 正在被调用。更有趣的是,如果我删除 return,即只调用 std::strlen("sdf"); 替换 main,则不会打印任何内容!
我还尝试了 Clang,std::strlen 调用了计算字符串长度的真实函数(并且没有打印任何内容)。这就是我期望看到的。
如何解释?定义我自己的 strlen 函数是否被视为未定义行为?
【问题讨论】:
-
参见 [reserved.names] 和 [depr.c.headers]。
-
在我的机器上你的示例段错误。 (linux,gcc-version 6.2.1 20160830)我没想到。我希望代码打印“hello”并以代码 0 退出操作系统。
-
我的示例也出现了段错误(gcc 5.4)。我建议在全局命名空间中提供
strlen函数是极其不寻常和“冒险”的,因为如果您首先包含<cstring>,这将覆盖libc 版本(带有“C”链接),因为那很自然也覆盖std::strlen,它可以在库的其他地方使用。例如。std::cout似乎产生了对strlen的调用。 -
你的代码里有ub
标签: c++ std language-lawyer undefined-behavior