0

以下のコードの割り当てがコンパイルに失敗するのはなぜですか?

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*" が他のスレッドによって変更されるポインターへのポインターである場合、割り当てにキャストが必要なのはなぜですか。不揮発性版ではありませんか?

4

1 に答える 1

1

この行:

void* volatile* pointerToPointerModifiedByManyThreads = &m_IntPointerModifiedByManyThreads

へのポインタ(void *)です。無関係なので、揮発性であるという事実を無視しましょう。volatile(アトミックを使用する必要があるときに使用しているという事実も無視しましょう。マルチスレッド プログラミングにvolatileほとんど役に立ちません。)

(void *)ポインターをポインターに、(int *)またはその逆に変換することはできません。struct xへのポインターと へのポインターの間で変換できないのと同じように、 へのポインターとへのstruct yポインターの間で変換することもできません。これらの変換は許可されていません。(int *)struct x

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
于 2013-10-19T21:36:38.613 に答える