在Linux上,打印功能地址总是打印1(c ++)

时间:2014-08-28 00:01:25

标签: c++ printing cout virtual-memory

我正在开发一个处理不同变量和函数地址的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而不是虚拟地址。

我真的很感谢你的帮助

先谢谢 阿兹

3 个答案:

答案 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;
}

http://ideone.com/Fne4Mu


C ++标准版n3337 § 4.12布尔转换[conv.bool]

  

1算术,无范围枚举,指针或指针的prvalue   成员类型可以转换为bool类型的prvalue。零   转换value,null指针值或null成员指针值   为假;任何其他值都转换为true。一个类型的prvalue   std :: nullptr_t可以转换为bool类型的prvalue;该   结果值是假的。

答案 1 :(得分:3)

<<没有使用函数指针的标准重载;所以相反,指针转换为bool(因为那是一个合法的隐式转换),如果您使用了1,则会truestd::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

请见working sample here


问题是,

有标准的操作员过载
ostream& operator<<(ostream&,void*)

但不适用于函数指针

ostream& operator<<(ostream&,void (Function1Type*)())

且转化次数最少的转换

ostream& operator<<(ostream&,bool)

0x00000000以外的所有内容均为true