C ++代码中的易失相关错误

时间:2014-11-15 21:32:49

标签: c++ windows c++11 gcc volatile

你能帮我理解为什么编译器会给我这些错误信息吗?我相信易变物体的成员也是易变的。我来自here。但它表明,如果我们有一个结构:

struct someStruct
{
    int d;
};

并且' p'定义如下:

volatile someStruct* volatile* p;

&(*p)->d具有以下类型' int * volatile *'而不是' volatile int * volatile *'。以下是我正在处理的实际代码。


行(标记为错误1和2)是编译器抛出错误消息的地方:

#include <vector>
#include <windows.h>

using namespace std;

struct ThreadInfo
{
    bool bWaiting = false;

    bool bWorking = false;
};

struct lThreadInfo
{
    ThreadInfo d;
    lThreadInfo *pNextList = nullptr;
} volatile *volatile lThreads(nullptr);

thread_local ThreadInfo* currentThr(nullptr);

void CreateThread_(void (*pFunc)(ThreadInfo*))
{
    volatile lThreadInfo* volatile* p = &lThreads;

    for(; *p; p = &(*p)->pNextList); //**//error 1!**

    *p = new lThreadInfo;

    CreateThread(
            nullptr,                   // default security attributes
            0,                      // use default stack size
            (long unsigned int (*)(void*))pFunc,       // thread function name
            &(*p)->d,          // argument to thread function     **//error 2!**
            0,                      // use default creation flags
            nullptr);
}

错误消息如下:

error 1: invalid conversion from 'lThreadInfo* volatile*' to 'volatile lThreadInfo* volatile*' [-fpermissive]
error 2: invalid conversion from 'volatile void*' to 'LPVOID {aka void*}' [-fpermissive]

注意:我知道volatile与线程安全无关,所以不要打扰告诉我。 Note1 :我在Windows上使用mingw64编译器。

1 个答案:

答案 0 :(得分:2)

通过pNextList访问路径

volatile也是volatile。但pNextList指针指针对象类型具有与之前相同的cv资格。

struct A
{
    lThreadInfo* p;
};

someStruct volatile* volatile* p;
  • *psomeStruct volatile* volatile
  • 类型的左值
  • (*p)->dlThreadInfo* volatile类型的左值。

因此,在(*p)->d类型中,您错过了lThreadInfo*之间的易变。 [expr.ref] / 4:

  

如果E2是非静态数据成员且E1的类型为“ cq1 vq1   X“,E2的类型为” cq2 vq2 T“,表达式   指定由第一个指定的对象的命名成员   表达。如果E1是左值,则E1.E2是左值;如果E1   是xvalue,然后E1.E2是xvalue;否则,它是一个prvalue。   让符号 vq12 代表 vq1 vq2 的“联合”;也就是说,如果 vq1 vq2 volatile,那么    vq12 volatile同样,让符号 cq12 代表 cq1 cq2 ;也就是说,如果 cq1 cq2 是   const,然后 cq12 const。如果声明E2是可变的   成员,然后E1.E2的类型是“ vq12 T”。如果E2不是   声明是一个可变成员,然后 E1.E2的类型是“ cq12    vq12 T

vq1 volatile vq2 为空。因此 vq12 volatile。因此,表达式的类型为volatile T,即lThreadInfo* volatile