不小心,我写了以下有趣的片段:
#include#include size_t strlen(const char* str) { std::cout << "hello"; return 0; } int main() { return std::strlen("sdf"); }
出乎意料的是,GCC 5.1中的输出是"hello",这意味着我strlen
被调用了.更有趣的是,如果我删除了return
,即只需要一个调用替换main,就std::strlen("sdf");
不会打印任何内容!
我也尝试过Clang,它std::strlen
调用实际函数来计算字符串长度(并且没有任何内容被打印).这就是我期望看到的.
怎么解释这个?是否将我自己的strlen
函数定义为未定义的行为?
这里没有什么有趣的,只是一个函数重载和一些未定义的行为.您strlen()
使用自己的版本重载了库函数.因为在GCC实现中std::strlen
只是命名空间内的库函数调用std
,所以你得到了你所看到的结果.
以下是相关摘录cstring
:
namespace std _GLIBCXX_VISIBILITY(default) { _GLIBCXX_BEGIN_NAMESPACE_VERSION using ::strlen; ...
当你删除return语句时,GCC完全优化掉调用,因为它知道这strlen
是没有副作用的函数,它实际上是一个保留名称,不应该重载.我假设,编译器可能会在这里给你一个警告,但是唉,它没有,因为它不是必需的.