为什么这个易失性指针convserion无效

时间:2013-10-19 21:26:23

标签: c++ volatile

为什么下面代码中的赋值无法编译?

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 *”是指向可以被其他线程修改的指针的指针,为什么赋值需要转换,非易失性版本没有?

1 个答案:

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