I\'m getting unexpected results from all compilers on which I tried the following (GCC 4.7.2, GCC 4.8.0 beta, ICC 13.0.1, Clang 3.2, VC10):
#include
[Note: Originally, this was not meant to be a self-answered question; I just happened to find the answer myself while I was describing my attempts to investigate, and I thought it would have been nice to share it.]
According to Annex C (2.14.5) of the C++11 Standard:
The type of a string literal is changed from “array of char” to “array of const char.” [....]
Moreover, Paragraph 7.1.6.2/4 specifies (about the result of decltype
):
The type denoted by
decltype(e)
is defined as follows:— if
e
is an unparenthesized id-expression or an unparenthesized class member access (5.2.5),decltype(e)
is the type of the entity named bye
. If there is no such entity, or ife
names a set of overloaded functions, the program is ill-formed;— otherwise, if
e
is an xvalue,decltype(e)
isT&&
, whereT
is the type ofe
;— otherwise, if
e
is an lvalue,decltype(e)
isT&
, whereT
is the type ofe
;— otherwise,
decltype(e)
is the type ofe
.
Since string literals are lvalues, according to the above Paragraph and the Paragraph from Annex C, the result of decltype("Hello")
is an lvalue reference to an array of size 6 of constant narrow characters:
#include <type_traits>
int main()
{
// This will NOT fire
static_assert(
std::is_same<decltype("Hello"), char const (&)[6]>::value,
"Error!"
);
}
Finally, even though the hello
variable is also an lvalue, the second compile-time assertion from the question's text does not fire, because hello
is an unparenthesized id-expression, which makes it fall into the first item of the above list from Paragraph 7.1.6.2/4. Therefore, the result of decltype(hello)
is the type of the entity named by hello
, which is char const[6]
.