左值

左值

左值(lvalue) 是B語言/C語言/C++語言等類C語言中的一類表達式。“左”(left)的原意是指可以放在賦值符號“=”的左邊,但其實也表示能作為&和++等操作符的操作數(B語言中已經如此)。而且,現代C/C++中的含義已經不局限於此。lvalue的l被重新解釋為location。這也對應於ISO C11/ISO C++11的內存位置(memory location)。

詳解


左值可以表示對象,即具有對應的可以由用戶訪問的存儲單元(應特別注意和類風格面向對象中的對象——類的實例的區別;Java等語言的對象即使用此種說法;C的左值相當於Java中的“變數”)。正因為如此,用於取得對象的指針的內建操作符&要求操作數是左值。
左值表示存儲在計算機內存的對象,與此相對的概念是右值(rvalue),習慣上統稱為左值性(lvalue-ness)。

變數關係


可以出現在特定的操作符中的一些操作數需要是左值,如賦值(左操作數)、一元&、++和--。此外,sizeofalignof等操作數中可以出現左值,且不會發生以下提到的左值到非左值的轉換。
左值參與決定轉換規則。除了需要左值的上下文,左值可以轉換為非左值。數組名和函數名作為表達式除了表示其本身,可以轉換為對應指針。這些在C中lvalue conversion、array conversion和function conversion,對應於C++的lvalue-to-rvalue conversion、array-to-pointer conversion和function-to-pointer conversion。后兩者習慣上稱為退化(decay) ,在傳遞函數參數時尤其明顯。這三個轉換是C++的標準轉換(standard conversion)的子集,因為其左值轉換成右值的共性(注意函數名作為表達式在C++也是左值),在函數重載規則中被稱為左值變換(lvalue transformation)。

計算機語言


B語言的左值和右值是形式文法中的元素。而ISO C/C++的左值和右值獨立於語法,是純粹語義上的概念。此外,ISO C在腳註中約定右值就是值,但ISO C++中右值和值是兩個明確獨立的概念。
ISO C允許不是左值也不作為右值(即具有值)的表達式——函數指示符(function designator) ——也就是單獨的函數名。它通過轉換得到函數指針值。
ISO C++03規定表達式必須是左值或右值之一。而在ISO C++11中,左值性被正式地擴充為更複雜的值類別(value category) :左值是返左值(glvalue, "generic lvalue") 的一類,後者和純右值(prvalue, "pure rvalue") 相對。純右值相當於之前版本的右值,此外還有消亡值(xvalue, "eXpired value")。函數名作為表達式在C++中是左值。
ISO C/C++中,左值可以進一步分為可以修改的左值(modifiable lvalue) 和不可修改的左值。只有可修改的左值才能作為賦值表達式的左操作數。不可修改的左值的一類例子是具有const類型的左值。
注意左值可能表示對象。左值和對象類型並無特定關聯,ISO C99(以及之後的3個技術修正案)在此的定義有誤,在ISO C11被修正。
左值和常量並不一定有必然的固定關聯。常量在C語言中是語法元素,和C的字元串字面量(string literal)一起,對應於C++的字面量(literal)。作為常量表達式,它可以是左值(如C++的字元串字面量,習慣上也被稱為字元串常量——儘管C的字元串字面量嚴格地不是常量),也可以是非左值(C的常量或C++的其它字面量)。注意這裡的常量比數學中使用的通常意義上的概念嚴格得多,也不和變數直接相對。