* a =&a如何合法?


88

考虑以下C ++代码:

void* a = &a;

为什么编译器不抱怨使用未声明的标识符?

另外,编译器认为变量a是什么?是指向空对象的指针还是指向指针的void*指针?




15
应该提到为什么要这样做-获得指向栈顶的指针(您可以从中进行各种操作)。
OrangeDog

Answers:


95

C ++中变量声明的范围可能非常令人惊讶:

void* a =               &a;
         ^~~~~~~~~~~~~~~~~
          a declared as `void*` from here on

因此,&avoid**,因为任何指针类型都可以隐式转换为void*...


我将如何为此分配一个有用的对象?
user2681063 2013年

22
@ user2681063 a = &userfulObject
Nikos C.

4
@MarkGarcia:请注意,void *a = a;如果在本地声明,它将是UB,否则在命名空间范围内就可以了。
Nawaz

1
@TheodorosChatzigiannakis:我相信是的。
Matthieu M.

1
规范引用在这里真的很好。
本杰明·格林鲍姆

30

相当于

void* a;
a = &a;

因此,a已被声明。因此a获取a写入的地址a。因此,它是指向空指针的指针。(您尚未定义任何对象。)


9
从技术上讲,您确实定义了一个对象。a本身就是一个对象。(并非所有对象在C ++中都有用户定义的类型)
MSalters 2013年

1
@MSalters您在说什么“对象”?:D
Gusdor

3
@Gusdor我们只能假设事件范围之外的内容。
科尔·约翰逊

它们的名称不同,但是在这种情况下“效果”是相同的
Stasik 2013年

它们通常并不等效,但是在这种情况下它们是等效的。
Lightness Races Orbit

7

在中void* aa被声明为不是指向void类型的指针,而是指向“任何”类型的指针(特殊情况)。a当然,对于要声明的任何其他变量,将地址(在内存中的位置)分配给。

之后,&a将对expression 求值以初始化a刚刚声明的变量(也与无关,但这并不相关)。的类型&a为“指向任何类型的指针”,这是“指向任何类型的指针”的特例,与的类型完全兼容a。嗯,没有编译器消息。

结论:void*如果要进行强类型检查,请不要使用。 任何东西都可以转换为它。反向相反,除了void*它本身(类型与其自身不兼容是不必要的例外)。

另外,AFAIR确实来自C。

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.