我正在开发一个处理不同变量和函数地址的c ++程序。
当我在基于Linux的操作系统上编译我的程序时,包括main在内的所有函数都获得1的地址而不是像其他变量一样的8位六进制数,这在Windows中不会发生。
我写了一小段代码来解释这个问题
#include <iostream>
using namespace std;
void Function1();
void Function1()
{
}
int main()
{
int tmp;
void (*a) ()=&Function1;
cout<<a<<endl;
cout<<&Function1<<endl;
cout<<&main<<endl;
return 0;
}
对于所有3个cout调用,输出为1而不是虚拟地址。
我真的很感谢你的帮助
先谢谢 阿兹
答案 0 :(得分:5)
指针被转换为另一种类型 boolean ,因为它是一个函数指针&amp;对于这些类型的参数,iostrem库中没有operator<<
的重载(因为存在无限数量的此类类型)。指针指向一些非零地址,因为它已经用函数地址初始化 - 因此转换为1(只有0x0地址会给你布尔值0)。
要断言正确的行为,您应该将指针强制转换为void *,以便operator<<
使用void*
重载,is
ostream & operator <<( ostream &, const void * );
示例:
void Function1(){}
int main() {
void ( *a) () = &Function1;
cout << ( void*)( a) << endl;
/* or better - being explicit about harshness of this design */
cout << reinterpret_cast< void*> ( a) <, endl;
}
C ++标准版n3337 § 4.12布尔转换[conv.bool]
1算术,无范围枚举,指针或指针的prvalue 成员类型可以转换为bool类型的prvalue。零 转换value,null指针值或null成员指针值 为假;任何其他值都转换为true。一个类型的prvalue std :: nullptr_t可以转换为bool类型的prvalue;该 结果值是假的。
答案 1 :(得分:3)
<<
没有使用函数指针的标准重载;所以相反,指针转换为bool
(因为那是一个合法的隐式转换),如果您使用了1
,则会true
或std::boolalpha
在流上操纵器。
如果你想要地址,你必须明确地将它转换为对象指针:
std::cout << reinterpret_cast<void*>(&Function1) << std::endl;
答案 2 :(得分:0)
如果我将代码更改为以下内容,函数指针地址将正确显示:
void Function1() {
}
int main() {
void*a = (void*)&Function1;
cout<<a<<endl;
cout<< (void*)&Function1<<endl;
cout<< (void*)&main<<endl;
return 0;
}
输出:
0x8048710
0x8048710
0x8048570
问题是,
有标准的操作员过载ostream& operator<<(ostream&,void*)
但不适用于函数指针
ostream& operator<<(ostream&,void (Function1Type*)())
且转化次数最少的转换
ostream& operator<<(ostream&,bool)
0x00000000
以外的所有内容均为true
。