为什么下面代码中的赋值无法编译?
struct foo
{
int* m_NormalIntPointer;
int* volatile m_IntPointerModifiedByManyThreads;
void func()
{
//compiles fine
void* pointerToNormalPointer = &m_NormalIntPointer;
//does not compile
void* volatile* pointerToPointerModifiedByManyThreads = &m_IntPointerModifiedByManyThreads;
}
};
如果m_IntPointerModifiedByManyThreads是指向int的指针,并且该指针可以被其他线程修改,并且“void * volatile *”是指向可以被其他线程修改的指针的指针,为什么赋值需要转换,非易失性版本没有?
答案 0 :(得分:1)
这一行:
void* volatile* pointerToPointerModifiedByManyThreads = &m_IntPointerModifiedByManyThreads
它指向(void *)
的指针。让我们忽略它不稳定的事实,因为它不相关。 (当你应该使用原子时,让我们忽略你正在使用volatile
的事实:volatile
几乎不可用用于多线程编程。)
您无法将指向(void *)
的指针转换为指向(int *)
的指针,反之亦然。就像您无法在指向struct x
的指针和指向struct y
的指针之间进行转换一样,您无法在指向(int *)
的指针和指向struct x
的指针之间进行转换。 {1}}。这些转换都不允许。
struct x my_x;
struct y *my_yptr = &my_x; // not allowed
int *my_intptr;
void **my_voidptr = &my_intptr; // not allowed, for exact same reason
唯一允许的转化是指向void
和其他人的指针。
int my_int;
void *my_voidptr = &my_int; // allowed
int *my_intptr = my_voidptr; // allowed
因此,如果您想进行转化,则必须转换为void *
,而不是void **
。由于int **
是指针,因此您可以将其转换为void *
并返回。
以下代码是正确的,但很难看:
int x = 3, y = 4;
int *my_intptr = &x;
void *my_intptr_ptr = &my_intptr;
*(int **) my_intptr_ptr = &y;
**(int **) my_intptr_ptr = 7;
// now y = 7, and my_intptr = &y