strlen的奇怪用法
Strange use of strlen
我试图编译以下示例代码:
#include <iostream>
#include <stdio.h>
#include <string>
using namespace std;
int main ()
{
if (strlen <= 0) {
cout << "trace1" << endl;
return 0;
}
cout << "trace2" << endl;
return 0;
}
奇怪的是它编译成功了。你知道为什么吗?
我没有将strlen声明为变量。
只使用函数的标识符会衰减到相应类型的函数指针。在这种情况下,strlen
是类型为size_t (*)(const char *)
的指针。此指针保存可执行代码中函数的第一条指令的地址。
测试该指针的值是合法的,无论原因是什么,尽管在您提供的代码片段中这似乎很奇怪。
strlen为您提供了一个函数指针,指向在内存中分配strlen函数的地址。
如果库函数strlen被分配在小于0的地址(这在世界上的每台计算机上都是不可能的),或者如果它被分配在地址0(极不可能,但可能),程序将打印"trace1"。否则,如果strlen被分配在大于零的地址(很可能是这种情况),它将打印"trace2"。
它可能会衰减为一个地址,该地址会衰减为整数。真正的编译器可能会在屏幕上显示警告。
如果对strlen
以外的其他函数执行相同操作,则此示例代码将打印trace2,因为strlen
是指向函数size_t strlen ( const char * str )
的指针,其值应为正数。
cout << (size_t *) strlen << endl;
cout << (size_t *) strcat << endl;
例如,上面的代码打印:
0x7fff84d29110
0x7fff84d63953
在我的机器上(正如你所看到的,这些是正数,因为它们以7开头)。
此外,如果我打印strlen
和strcat
而不强制转换为(size_t*),则结果将为1,这意味着这些函数是有效的。
相关文章:
- 这个指针在c++中的用法
- 循环中的条件:为什么每次都调用strlen(),而vector.size()只调用一次
- 当C++中需要自动删除时,这是静态的正确用法吗?
- libstdc++ 文件系统中未初始化的用法?
- 复制和交换习惯用法与移动操作之间的交互
- 类作用域的类型别名"using":[何时]方法中的用法可以先于类型别名?
- 命名参数习惯用法和(抽象)基类
- 省略号在C++中的所有用法
- () 在 C++ 11 中的特殊而奇怪的用法?
- 构造函数的用法
- 模板类中自动的类用法不完整
- 这里的 = 运算符有什么用法?
- std::strlen 在内部是如何工作的?
- 为什么strlen(s)与s的大小不同,为什么cout-char显示的是字符而不是数字
- 什么模板用法在阶乘中更好
- 如果可变长度元素的constexpr用法得到<>
- 为什么 setjmp/longjmp 的这种用法是未定义的行为?
- C++编译 strlen 和 strcpy 的问题
- 访问提升:shared_ptr 主范围外崩溃,断言失败:px != 0.指针的正确用法是什么?
- strlen的奇怪用法