Why are they called "primary"? In the order of evaluence they are the first?
C++03 standard defines the expression in chapter 5 (Note 1):
An expression is a sequence of operators and operands that specifies a computation.
Then the 5.1 "Primary expressions" defines the list of primary expressions:
(1) primary-expression:
literal
this
( expression )
id-expression
My main question is in connection the third point:
( expression )
So, according to the standard, every expression with brackets are primary expressions and they are calculated firstly. It looks logical, and gives an exact explanation of the behavior of brackets in C++ expressions (precedence).
So this means that for example
(variable + 10)
is a primary expression.
var = (variable + 10) * 3
and according to my theory, it looks logic, BUT from other sources I know
(variable + 10)
is NOT a primary expression, but WHY? I don't understand, however the standard defines the (expression) as a primary expression.
Please, help me because I can't. Thank you very much, and sorry for my bad English.
Hi.
C++ expressions can be complex, which is to say they can be made up of nested expressions, combined through the use of operators, and those nested expressions may in turn be complex.
If you decompose a complex expression into ever smaller units, at some point you'll be left with units that are atomic in the sense that they cannot be decomposed further. Those are primary expressions; they include identifiers, literals, the keyword this, and lambda expressions.
However, it is true that there is one non-atomic construct that the C++ Standard defines as primary: Expressions enclosed in round brackets (aka parentheses). So the (variable + 10) example you give is a primary expression (and so are the sub-expressions variable (which is an identifier), and 10 (which is a literal).
I believe the Standard lists them as primary expressions because they play the some role as truly atomic expressions when it comes to the order of evaluation: Anything within the brackets must be evaluated before the value of the backeted expressions can enter into evaluations with other expressions: In (5+10)*a, the value of 5+10 must be evaluated before it can enter into the evaluation of *a. [Note that this does not mean 5+10 is evaluated before the expression a is evaluated. It only means that 5+10 must be evaluated before the multiplication itself can be evaluated.]
So, bracketed sub-expressions, in this sense, act as if they were atomic.
And I guess this is why the Standard doesn't use the term "atomic expressions" for this concept. They act as if they were atomic, but at least the bracketed variety is not actually atomic. "Primary" seems, to me, to be a good choice of words.
The term primary-expression is an element of the language grammar. They could equally have been called foobar-expression , it's just a name that doesn't have any deeper meaning.
A primary-expression is not necessarily atomic, evaluated first, top-level, more important than other expressions , or anything like that . And all expressions are "building blocks" because any expression can be added to to form a larger expression.
The definition was already given in the question so I won't repeat it here.
(variable + 10) is a primary-expression, your "other sources" are wrong. Here is another example of primary-expression:
([]{
int n, t1 = 0, t2 = 1, nextTerm = 0;
cout << "Enter the number of terms: ";
cin >> n;
cout << "Fibonacci Series: ";
for (int i = 1; i <= n; ++i)
{
// Prints the first two terms.
if(i == 1)
{
cout << " " << t1;
continue;
}
if(i == 2)
{
cout << t2 << " ";
continue;
}
nextTerm = t1 + t2;
t1 = t2;
t2 = nextTerm;
cout << nextTerm << " ";
}
return 0;
}())
(this calls a lambda function and parenthesizes the result; code borrowed from : here).
Also, the question flirts with a common misconception about precedence and order of evaluation. The standard doesn't mention "precedence" at all. A precedence table is a way of presenting the rules of the the language grammar in a way that is easier to read.
It refers to the way that operands are grouped with operators, not the order in which subexpressions are executed. In the case of f() + ([]{int n, t1 = 0, t2 = 1, nextTerm = 0; cout << "Enter the number of terms: ";.... etc. etc. , the f() may or may not be called before the lambda is called. The parentheses around the lambda do not cause it to be evaluated first.
Related
I found a section of code that shows the following:
int A = 4;
int Z;
Z = (A ? 55 : 3);
Why does the result for Z give 55?
You seem to have a common misconception about the fact that expressions in conditional statements (if, while, ...) and ternary operations must "look like" a condition, so they should contain a relational/equality/logical operator.
It's not like that. Commonly used relational/equality/... operators don't have any particular relationship with conditional statements/expressions; they can live on their own
bool foo = 5 > 4;
std::cout<<foo<<"\n"; // prints 1
and conditional statements/expressions don't care particularly for them
if(5) std::cout << "hello\n"; // prints hello
if/?/while/... just evaluate the expression, check if the result, converted to bool, is true or false, and act accordingly. If the expression doesn't "looks like" a condition is irrelevant, as long as the result can be converted to bool you can use it in a conditional.
Now, in this particular case A evaluates to 4, which is not zero, so when converted to bool is true, hence the ternary expression evaluates to its second expression, so 55.
#include <iostream>
using namespace std;
int main()
{
int arr[3] = { 10, 20, 30 };
cout << arr[-2] << endl;
cout << -2[arr] << endl;
return 0;
}
Output:
4196160
-30
Here arr[-2] is out of range and invalid, causing undefined behavior.
But -2[arr] evaluates to -30. Why?
Isn't arr[-2] equivalent to -2[arr]?
-2[arr] is parsed as -(2[arr]). In C (and in C++, ignoring overloading), the definition of X[Y] is *(X+Y) (see more discussion of this in this question), which means that 2[arr] is equal to arr[2].
The compiler parses this expression
-2
like
unary_minus decimal_integer_literal
That is definitions of integer literals do not include signs.
In turn the expression
2[arr]
is parsed by the compiler as a postfix expression.
Postfix expressions have higher precedence than unary expressions. Thus this expression
-2[arr]
is equivalent to
- ( 2[arr] )
So the unary minus is applied to the lvalue returned by the postfix expression 2[arr].
On the other hand if you wrote
int n = -2;
and then
n[arr]
then this expression would be equivalent to
arr[-2]
-2[arr] is equivalent to -(2[arr]), which is equivalent to -arr[2]. However, (-2)[arr] is equivalent to arr[-2].
This is because E1[E2] is identical to (*((E1)+(E2)))
The underlying problem is with operator precedence. In C++ the [], ie the Subscript operator hold more precedence (somewhat akin to preferance) than the - unary_minus operator.
So when one writes,
arr[-2]
The compiler first executes arr[] then - , but the unary_minus is enclosed within the bounds of the [-2] so the expression is decomposed together.
In the,
-2[arr]
The same thing happens but, the compiler executes 2[] first the n the - operator so it ends up being
-(2[arr]) not (-2)[arr]
Your understanding of the concept that,
arr[i] i[arr] and *(i+arr) are all the same is correct. They are all equivalent expressions.
If you want to write in that way, write it as (-2)[arr]. You will get the same value for sure.
Check this out for future referance :http://en.cppreference.com/w/cpp/language/operator_precedence
In Bjarne Stroustrup's The C++ Programming Language 4th edition section 36.3.6 STL-like Operations the following code is used as an example of chaining:
void f2()
{
std::string s = "but I have heard it works even if you don't believe in it" ;
s.replace(0, 4, "" ).replace( s.find( "even" ), 4, "only" )
.replace( s.find( " don't" ), 6, "" );
assert( s == "I have heard it works only if you believe in it" ) ;
}
The assert fails in gcc (see it live) and Visual Studio (see it live), but it does not fail when using Clang (see it live).
Why am I getting different results? Are any of these compilers incorrectly evaluating the chaining expression or does this code exhibit some form of unspecified or undefined behavior?
The code exhibits unspecified behavior due to unspecified order of evaluation of sub-expressions although it does not invoke undefined behavior since all side effects are done within functions which introduces a sequencing relationship between the side effects in this case.
This example is mentioned in the proposal N4228: Refining Expression Evaluation Order for Idiomatic C++ which says the following about the code in the question:
[...]This code has been reviewed by C++ experts world-wide, and published
(The C++ Programming Language, 4th edition.) Yet, its vulnerability
to unspecified order of evaluation has been discovered only recently
by a tool[...]
Details
It may be obvious to many that arguments to functions have an unspecified order of evaluation but it is probably not as obvious how this behavior interacts with chained functions calls. It was not obvious to me when I first analyzed this case and apparently not to all the expert reviewers either.
At first glance it may appear that since each replace has to be evaluated from left to right that the corresponding function argument groups must be evaluated as groups from left to right as well.
This is incorrect, function arguments have an unspecified order of evaluation, although chaining function calls does introduce a left to right evaluation order for each function call, the arguments of each function call are only sequenced before with respect to the member function call they are part of. In particular this impacts the following calls:
s.find( "even" )
and:
s.find( " don't" )
which are indeterminately sequenced with respect to:
s.replace(0, 4, "" )
the two find calls could be evaluated before or after the replace, which matters since it has a side effect on s in a way that would alter the result of find, it changes the length of s. So depending on when that replace is evaluated relative to the two find calls the result will differ.
If we look at the chaining expression and examine the evaluation order of some of the sub-expressions:
s.replace(0, 4, "" ).replace( s.find( "even" ), 4, "only" )
^ ^ ^ ^ ^ ^ ^ ^ ^
A B | | | C | | |
1 2 3 4 5 6
and:
.replace( s.find( " don't" ), 6, "" );
^ ^ ^ ^
D | | |
7 8 9
Note, we are ignoring the fact that 4 and 7 can be further broken down into more sub-expressions. So:
A is sequenced before B which is sequenced before C which is sequenced before D
1 to 9 are indeterminately sequenced with respect to other sub-expressions with some of the exceptions listed below
1 to 3 are sequenced before B
4 to 6 are sequenced before C
7 to 9 are sequenced before D
The key to this issue is that:
4 to 9 are indeterminately sequenced with respect to B
The potential order of evaluation choice for 4 and 7 with respect to B explains the difference in results between clang and gcc when evaluating f2(). In my tests clang evaluates B before evaluating 4 and 7 while gcc evaluates it after. We can use the following test program to demonstrate what is happening in each case:
#include <iostream>
#include <string>
std::string::size_type my_find( std::string s, const char *cs )
{
std::string::size_type pos = s.find( cs ) ;
std::cout << "position " << cs << " found in complete expression: "
<< pos << std::endl ;
return pos ;
}
int main()
{
std::string s = "but I have heard it works even if you don't believe in it" ;
std::string copy_s = s ;
std::cout << "position of even before s.replace(0, 4, \"\" ): "
<< s.find( "even" ) << std::endl ;
std::cout << "position of don't before s.replace(0, 4, \"\" ): "
<< s.find( " don't" ) << std::endl << std::endl;
copy_s.replace(0, 4, "" ) ;
std::cout << "position of even after s.replace(0, 4, \"\" ): "
<< copy_s.find( "even" ) << std::endl ;
std::cout << "position of don't after s.replace(0, 4, \"\" ): "
<< copy_s.find( " don't" ) << std::endl << std::endl;
s.replace(0, 4, "" ).replace( my_find( s, "even" ) , 4, "only" )
.replace( my_find( s, " don't" ), 6, "" );
std::cout << "Result: " << s << std::endl ;
}
Result for gcc (see it live)
position of even before s.replace(0, 4, "" ): 26
position of don't before s.replace(0, 4, "" ): 37
position of even after s.replace(0, 4, "" ): 22
position of don't after s.replace(0, 4, "" ): 33
position don't found in complete expression: 37
position even found in complete expression: 26
Result: I have heard it works evenonlyyou donieve in it
Result for clang (see it live):
position of even before s.replace(0, 4, "" ): 26
position of don't before s.replace(0, 4, "" ): 37
position of even after s.replace(0, 4, "" ): 22
position of don't after s.replace(0, 4, "" ): 33
position even found in complete expression: 22
position don't found in complete expression: 33
Result: I have heard it works only if you believe in it
Result for Visual Studio (see it live):
position of even before s.replace(0, 4, "" ): 26
position of don't before s.replace(0, 4, "" ): 37
position of even after s.replace(0, 4, "" ): 22
position of don't after s.replace(0, 4, "" ): 33
position don't found in complete expression: 37
position even found in complete expression: 26
Result: I have heard it works evenonlyyou donieve in it
Details from the standard
We know that unless specified the evaluations of sub-expressions are unsequenced, this is from the draft C++11 standard section 1.9 Program execution which says:
Except where noted, evaluations of operands of individual operators
and of subexpressions of individual expressions are unsequenced.[...]
and we know that a function call introduces a sequenced before relationship of the function calls postfix expression and arguments with respect to the function body, from section 1.9:
[...]When calling a function (whether or not the function is inline), every
value computation and side effect associated with any argument
expression, or with the postfix expression designating the called
function, is sequenced before execution of every expression or
statement in the body of the called function.[...]
We also know that class member access and therefore chaining will evaluate from left to right, from section 5.2.5 Class member access which says:
[...]The postfix expression before the dot or arrow is evaluated;64
the result of that evaluation, together with the id-expression,
determines the result of the entire postfix expression.
Note, in the case where the id-expression ends up being a non-static member function it does not specify the order of evaluation of the expression-list within the () since that is a separate sub-expression. The relevant grammar from 5.2 Postfix expressions:
postfix-expression:
postfix-expression ( expression-listopt) // function call
postfix-expression . templateopt id-expression // Class member access, ends
// up as a postfix-expression
C++17 changes
The proposal p0145r3: Refining Expression Evaluation Order for Idiomatic C++ made several changes. Including changes that give the code well specified behavior by strengthening the order of evaluation rules for postfix-expressions and their expression-list.
[expr.call]p5 says:
The postfix-expression is sequenced before each expression in the expression-list and any default argument. The
initialization of a parameter, including every associated value computation and side effect, is indeterminately
sequenced with respect to that of any other parameter. [ Note: All side effects of argument evaluations are
sequenced before the function is entered (see 4.6). —end note ] [ Example:
void f() {
std::string s = "but I have heard it works even if you don’t believe in it";
s.replace(0, 4, "").replace(s.find("even"), 4, "only").replace(s.find(" don’t"), 6, "");
assert(s == "I have heard it works only if you believe in it"); // OK
}
—end example ]
This is intended to add information on the matter with regards to C++17. The proposal (Refining Expression Evaluation Order for Idiomatic C++ Revision 2) for C++17 addressed the issue citing the code above was as specimen.
As suggested, I added relevant information from the proposal and to quote (highlights mine):
The order of expression evaluation, as it is currently specified in the standard, undermines advices, popular programming idioms, or the relative safety of standard library facilities. The traps aren't just for novices
or the careless programmer. They affect all of us indiscriminately, even when we know the rules.
Consider the following program fragment:
void f()
{
std::string s = "but I have heard it works even if you don't believe in it"
s.replace(0, 4, "").replace(s.find("even"), 4, "only")
.replace(s.find(" don't"), 6, "");
assert(s == "I have heard it works only if you believe in it");
}
The assertion is supposed to validate the programmer's intended result. It uses "chaining" of member function calls, a common standard practice. This code has been reviewed by C++ experts world-wide, and published (The C++ Programming Language, 4th edition.) Yet, its vulnerability to unspecified order of evaluation has been discovered only recently by a tool.
The paper suggested changing the pre-C++17 rule on the order of expression evaluation which was influenced by C and have existed for more than three decades. It proposed that the language should guarantee contemporary idioms or risk "traps and sources of obscure, hard to find bugs" such as what happened with the code specimen above.
The proposal for C++17 is to require that every expression has a well-defined evaluation order:
Postfix expressions are evaluated from left to right. This includes functions calls and member selection expressions.
Assignment expressions are evaluated from right to left. This includes compound assignments.
Operands to shift operators are evaluated from left to right.
The order of evaluation of an expression involving an overloaded operator is determined by the order associated with the corresponding built-in operator, not the rules for function calls.
The above code compiles successfully using GCC 7.1.1 and Clang 4.0.0.
I am aware of two techniques for flipping a bool:
x = !x
and
x ^= 1
I prefer the second, in the same way that I prefer x++ over x+=1 over x=x+1.
But are they guaranteed to produce the same Assembly code?
And if not, is there some rationale to favour one over the other?
There are never any guarantees about same assembly code. Yes, given bool x, they both do exactly the same thing. Yes, that implies they are likely to be the same.
It is a common fallacy that writing expressions in an unusual way might make them faster. Avoid working with anyone who makes habits based on such ideas.
x = ! x is clearer because ! is defined in terms of Boolean values.
I prefer the second, in the same way that I prefer x++ over x+=1 over x=x+1.
Please prefer the first. It is expected and easily understood by most programmers. The second form, only works for values 0 and 1 in integer's case.
But are they guaranteed to produce the same Assembly code?
No.
And if not, is there some rationale to favour one over the other?
Decreasing the ratio of "wtf/loc" of you code (i.e. how many times would another developer look at your code and say "WTF?!?", over every n lines of code).
Edit: Either way, you will probably never see a real-world example of an application made faster by replacing one expression with the other. It is a matter of style, not a matter of performance.
The second expression is simply a source of difficulty found bugs. For example you may think that some expression has type bool while its actual type due to the integer promotion or usual arithmetic conversion is some integral type.
Consider the following code snippet
unsigned int x = 3;
x ^= 1;
std::cout << x << std::endl;
if ( x == false ) std::cout << "All is O'k\n";
else std::cout << "Oops. Something is wrong!\n";
x = 3;
x = !x;
std::cout << x << std::endl;
if ( x == false ) std::cout << "All is O'k\n";
else std::cout << "Oops. Something is wrong!\n";
So using expression x ^= 1; to flip a boolean value can only confuse readers of the code.
So I would prefer to use x = !x; instead of x ^= 1;
Do not forget about the principle KISS: Keep It Simple Stupid.:)
Though for example in C the result of operator ! has type int nevertheless the value of the operation is either 0 or 1.
From the C Standard
5 The result of the logical negation operator ! is 0 if the value of
its operand compares unequal to 0, 1 if the value of its operand
compares equal to 0.
So for both languages there is a guarantee that the result will be exactly either 0 or 1 for any source value.
!x and x^1 are clearly different operations.
The former is a logical negation, returning a 0/1 value. It makes sense to use it on bools.
The latter is a bitwise exclusive or, returning any possible value. It shouldn't be used on a bool. (For xoring bools, prefer the inequality comparison !=). It is also less efficient in unoptimized code as it invoves and extra operand (1).
K&R forgot to provide a !! operator, that you would have loved, and possibly ~~.
I've read that usually statements in c++ end with a semi-colon; so that might help explain what an expression statement would be. But then what would you call an expression by giving an example?
In this case, are both just statements or expression statements or expressions?
int x;
x = 0;
An expression is "a sequence of operators and operands that specifies a computation" (that's the definition given in the C++ standard). Examples are 42, 2 + 2, "hello, world", and func("argument"). Assignments are expressions in C++; so are function calls.
I don't see a definition for the term "statement", but basically it's a chunk of code that performs some action. Examples are compound statements (consisting of zero or more other statements included in { ... }), if statements, goto statements, return statements, and expression statements. (In C++, but not in C, declarations are classified as statements.)
The terms statement and expression are defined very precisely by the language grammar.
An expression statement is a particular kind of statement. It consists of an optional expression followed by a semicolon. The expression is evaluated and any result is discarded. Usually this is used when the statement has side effects (otherwise there's not much point), but you can have a expression statement where the expression has no side effects. Examples are:
x = 42; // the expression happens to be an assignment
func("argument");
42; // no side effects, allowed but not useful
; // a null statement
The null statement is a special case. (I'm not sure why it's treated that way; in my opinion it would make more sense for it to be a disinct kind of statement. But that's the way the standard defines it.)
Note that
return 42;
is a statement, but it's not an expression statement. It contains an expression, but the expression (plus the ;) doesn't make up the entire statement.
These are expressions (remember math?):
1
6 * 7
a + b * 3
sin(3) + 7
a > b
a ? 1 : 0
func()
mystring + gimmeAString() + std::string("\n")
The following are all statements:
int x; // Also a declaration.
x = 0; // Also an assignment.
if(expr) { /*...*/ } // This is why it's called an "if-statement".
for(expr; expr; expr) { /*...*/ } // For-loop.
A statement is usually made up of an expression:
if(a > b) // a > b is an expr.
while(true) // true is an expr.
func(); // func() is an expr.
To understand what is an expression statement, you should first know what is an expression and what is an statement.
An expression in a programming language is a combination of one or more explicit values, constants, variables, operators, and functions that the programming language interprets (according to its particular rules of precedence and of association) and computes to produce ("to return", in a stateful environment) another value. This process, as for mathematical expressions, is called evaluation.
Source: https://en.wikipedia.org/wiki/Expression_(computer_science)
In other words expressions are a sort of data items. They can have single or multiple entities like constants and variables. These entities may be related or connected to each other by operators. Expressions may or may not have side effects, in that they evaluate to something by means of computation which changes a state. For instance numbers, things that look like mathematical formulas and calculations, assignments, function calls, logical evaluations, strings and string operations are all considered expressions.
function calls: According to MSDN, function calls are considered expressions. A function call is an expression that passes control and arguments (if any) to a function and has the form:
expression (expression-list opt) which is invoked by the ( ) function operator.
source: https://msdn.microsoft.com/en-us/library/be6ftfba.aspx
Some examples of expressions are:
46
18 * 3 + 22 / 2
a = 4
b = a + 3
c = b * -2
abs(c)
b >= c
c
"a string"
str = "some string"
strcat(str, " some thing else")
str2 = "some string" + " some other string" // in C++11 using string library
Statements are fragments of a program that execute in sequence and cause the computer to carry out some definite action. Some C++ statement types are:
expression statements;
compound statements;
selection statements;
iteration statements;
jump statements;
declaration statements;
try blocks;
atomic and synchronized blocks (TM TS).
Source: http://en.cppreference.com/w/cpp/language/statements
I've read usually statements in c++ ends with a semicon;
Yes usually! But not always. Consider the following piece of code which is a compound statement but does not end with a semicolon, rather it is enclosed between two curly braces:
{ // begining of a compound statement
int x; // A declaration statement
int y;
int z;
x = 2; // x = 2 is an expression, thus x = 2; with the trailing semicolon is an expression statement
y = 2 * x + 5;
if(y == 9) { // A control statement
z = 52;
} else { // A branching statement of a control statement
z = 0;
}
} // end of a compound statement
By now, as you might be guessing, an expression statement is any statement that has an expression followed by a semicolon. According to MSDN an expression statement is a statement that causes the expressions to be evaluated. No transfer of control or iteration takes place as a result of an expression statement.
Source: https://msdn.microsoft.com/en-us/library/s7ytfs2k.aspx
Some Examples of expression statements:
x = 4;
y = x * x + 10;
radius = 5;
pi = 3.141593;
circumference = 2. * pi * radius;
area = pi * radius * radius;
Therefore the following can not be considered expression statements since they transfer the control flow to another part of a program by calling a function:
printf("The control is passed to the printf function");
y = pow(x, 2);
side effects: A side effect refers to the modification of a state. Such as changing the value of a variable, writing some data on a disk showing a menu in the User Interface, etc.
Source: https://en.wikipedia.org/wiki/Side_effect_(computer_science)
Note that expression statements don't need to have side effects. That is they don't have to change or modify any state. For example if we consider a program's control flow as a state which could be modified, then the following expression statements
won't have any side effects over the program's control flow:
a = 8;
b = 10 + a;
k++;
Wheres the following expression statement would have a side effect, since it would pass the control flow to sqrt() function, thus changing a state:
d = sqrt(a); // The control flow is passed to sqrt() function
If we consider the value of a variable as a state as well, modifying it would be a side effect thus all of expression statements above have side effects, because they all modify a state. An expression statement that does not have any side effect is not very useful. Consider the following expression statements:
x = 7; // This expression statement sets the value of x to 7
x; // This expression statement is evaluated to 7 and does nothing useful
In the above example x = 7; is a useful expression statement for us. It sets the value of x to 7 by = the assignment operator. But x; evaluates to 7 and it doesn't do anything useful.
According to The C++ Programming Language by Bjarne Stroustrup Special(3rd) Edition, a statement is basically any declaration, function call, assignment, or conditional. Though, if you look at the grammar, it is much more complicated than that. An expression, in simple terms, is any math or logical operation(s).
The wikipedia links that ok posted in his answer can be of help too.
In my opinion,
a statement *states* the purpose of a code block. i.e. we say this block of code if(){} is an if-statement, or this x=42; is an expression statement. So code such as 42; serves no purporse, therefore, this is *not* a statement.
and,
an expression is any legal combination of symbols that represents a value (Credit to Webopedia); it combines variables and constants to produce new values(Quoted from Chapter 2 in The C Programming Language). Therefore, it also has a mathematical connotation. For instance, number 42 in x=42; is an expression (x=42; is not an expression but rather an expression statement), or func(x) is an expression because it will evaluate to something. On the contrary, int x; is not an expression because it is not representing any value.
I think this excerpt from a technical book is most useful and clear.
Read the paragraphs till the start of 1.4.2 statements would be useful enough.
An expression is "a sequence of operators and operands that specifies a computation"
These are expressions:
1
2 + 2
"hi"
cout << "Hello, World!"
The last one is indeed an expression; << is the output operator, cout (of type ostream) and "Hello, World!" (string literals) are the operands. The operator returns the left-hand operand, so (cout << "Hello, ") << "World!" is also a valid expression but also not a statement.
An expression becomes an expression statement when it is followed by a semicolon:
1;
2 + 2;
"hi";
cout << "Hello, World!";
An expression is part of a statement, OR a statement itself.
int x; is a statement and expression.
See this : http://en.wikipedia.org/wiki/Expression_%28programming%29
http://en.wikipedia.org/wiki/Statement_%28programming%29