2013-10-19 33 views
0

为什么下面的代码中的赋值无法编译?为什么这个易失性指针convserion无效

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,并且该指针可以通过其它线程进行修改,并且“空隙*挥发性*”是一个指针,它指向可以通过其它线程被修改的指针,为什么用任务需要演员,其中非易失版本不?

+1

挥发性预选赛无关,跟线程,除非你使用Visual Studio – Cubbi

+0

@Cubbi的非标准扩展:或者使用IA64。 –

回答

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