2014-11-15 44 views
5

你能幫我理解編譯器爲什麼給我這些錯誤信息嗎?我相信易失物體的成員也是不穩定的。我指的是here。但是它顯示了,如果我們有一個結構:C++代碼中的易變相關錯誤

struct someStruct 
{ 
    int d; 
}; 

和「P」就像是一個定義:

volatile someStruct* volatile* p; 

&(*p)->d有以下類型「詮釋*揮發性*」而不是「揮發性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與線程安全無關,所以不要打擾告訴我。 注1:我在windows上使用mingw64編譯器。

+0

對於第二個錯誤,您需要'const_cast'來爲Windows API函數調用拋出'volatile'。對於第一個錯誤,成員'pNextList'也需要'volatile'(或者從'p'中移除'volatile')。 – Niall

+0

但不應該創建一個具有易失性說明符的對象自動使它的所有子對象都變得不穩定嗎? – AnArrayOfFunctions

+0

'lThreadInfo :: pNextList'的類型爲'lThreadInfo *'。如果你有一個'volatile'的lThreadInfo對象,例如'lThreadInfo volatile o;',然後'o.pNextList'是'lThreadInfo * volatile'。 cv-qualifiers總是應用於「最外層」類型,而不是指向的類型。 – dyp

回答

2

pNextList,通過volatile訪問路徑,也是volatile。但是pNextList指針pointee類型具有與以前一樣的cv限定。

也就是說,對於

struct A 
{ 
    lThreadInfo* p; 
}; 

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

所以在(*p)->d類型,你就錯過了揮發性lThreadInfo*之間。 [expr.ref]/4:

如果E2是非靜態數據成員和E1類型是「CQ1 VQ1 X」,和E2類型是「CQ2 VQ2T 「,表達式 指定由第一個 表達式指定的對象的指定成員。如果E1是左值,則E1.E2是左值;如果E1 是一個xvalue,那麼E1.E2是一個xvalue;否則,這是一個價值。 讓符號VQ12立場的的VQ1VQ2「聯盟」;也就是說,如果VQ1VQ2volatile,然後 VQ12volatile類似地,讓符號cq12代表cq1cq2的「聯合」也就是說,如果CQ1CQ2const,然後cq12const。如果E2被宣告爲可變成員 ,則E1.E2的類型爲「vq12T」。如果E2不 聲明爲可變的成員,則E1.E2類型爲「cq12 VQ12T

VQ1volatileVQ2是空的。因此vq12volatile。因此表達式的類型是volatile T,它是lThreadInfo* volatile