[英]Conversions between volatile, const, volatile const, and "neither" types
C++(11) 標准對 volatile、const、volatile const 和“兩者都不是”類型之間的轉換有什么看法? 我知道將 const 類型分配給非常量和非易失性類型是明確定義和可接受的,但是以下類型(其中 T 是某種類型)之間的轉換呢?
// T
T
T volatile
T const
T volatile const
// Pointer-to-T
T*
T volatile*
T const*
T volatile const*
// Volatile pointer-to-T
T* volatile
T volatile* volatile
T const* volatile
T volatile const* volatile
// Const pointer-to-T
T* const
T volatile* const
T const* const
T volatile const* const
// Volatile const pointer-to-T
T* volatile const
T volatile* volatile const
T const* volatile const
T volatile const* volatile const
作為一個簡單的例子,請考慮以下代碼:
T volatile a;
T const b;
a = b; // implicit conversion from const to volatile; okay?
template<typename T>
void fcn(T& t)
{
t = b; // implicit conversion from const to non-const, which I assume is okay
}
fcn(a); // implicit conversion from volatile to non-volatile; okay?
你可以分配給什么?
您始終可以將 volatile 值分配給非常量值。 您還可以將 const 和非常量值分配給 volatile 值。 你永遠不能給 const 值賦值,因為它們是 const 的。
是否發生轉換?
不 - 它只是在做一項任務。
為什么是這樣?
volatile
意味着無法優化對對象的任何訪問。 實際上很少有需要或使用volatile
情況。 這些情況是:
因此,必須可以將volatile
分配給常規對象,反之亦然。 但是,與此同時,不應該將 volatile 引用隱式轉換為常規引用,因為這可能會導致讀取和寫入被優化掉。
常量呢?
您可以將 const 的內容分配給任何東西,但不能將任何內容分配給 const(因為它是 const)。
a = b; // implicit conversion from const to volatile; okay?
是否“正常”取決於類型T
。
這里發生的是左值到右值的轉換。 這是標准規則所說的:
[conv.lval]
非函數、非數組類型 T 的泛左值可以轉換為純右值。 如果 T 是一個不完整的類型,那么需要這種轉換的程序就是格式錯誤的。 如果 T 是非類類型,則純右值的類型是 T 的 cv 非限定版本。否則,純右值的類型是 T。
因此,例如,如果T
不是類類型,那么從T const b
轉換的純右值將是T
,在這種情況下,它與分配的變量的類型相同。 所以,只要T
是可賦值的(即不是 const),它就“沒問題”。
對於類類型,賦值是否“可以”取決於類具有的賦值運算符類型。 隱式賦值運算符不是 volatile 限定的,因此示例賦值不會“好”。 它將是格式錯誤的。 但是有可能讓用戶聲明一個 volatile 限定的賦值運算符,盡管這種情況並不常見。
關於fcn(a); // implicit conversion from volatile to non-volatile; okay?
fcn(a); // implicit conversion from volatile to non-volatile; okay?
,根據this是不行的,因為它會導致從非易失性類型引用易失性類型:
C 標准 6.7.3 [ISO/IEC 9899:2011] 指出
如果嘗試通過使用具有非 volatile 限定類型的左值來引用使用 volatile 限定類型定義的對象,則行為未定義。
另外,雖然我沒有引用,但我相信指針之間的賦值和轉換必須具有它們指向的相同的 volatile-/const- 限定類型(即*
必須匹配之前的const
s/ volatile
s):
T volatile* volatile t; T volatile* volatile const t1 = t; // okay; initializing const with non-const T* volatile t2 = t; // not okay; t and t2 point to different types T volatile const* volatile t3 = t; // not okay; t and t3 point to different types
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.