My book defines an expression as "a programming statement that has a value" and a literal as "a piece of data that is written directly into a program's source code", but I'm still having some trouble distinguishing between the two. For example, is 3+3 a literal AND an expression, or just an expression? Why?
int number = 2+2;
Is this whole statement an expression, or just the right value? Why? This whole statement has a value of 4, so surely the whole statement is an expression?
In my mind, an expression usually involves operators and a literal involves a single piece of data like 4, "Hello", 'A', etc. I also understand that a literal can be an expression because of unary operators such as - or +. Am I correct in thinking this?
An expression is a sequence of operators and operands that specifies a computation. An expression can result in a value and can cause side effects.
A literal is one of the following:
integer literal
character literal
floating point literal
string literal
boolean literal
pointer literal
I won't try to give the formal definition of each of these, but each is basically just a value.
There's one more type of literal that's somewhat special though:
user-defined literal
Although user-defined literals are literals, the value of the literal is defined in terms of the result of evaluating an expression.
References:
Expressions: [expr]
Literals: [lex.literal]
(For those unfamiliar with it, the tag in square brackets is the notation used to specify sections in the C++ standard).
A literal is something like the number 7 for example. When converted to assembly code, the literal 7 remains quite visible in the code:
MOV R1, 7 ; move the number 7 as a value into register R1
An expression is something that needs to be evaluated. Generally, you'll find something along the lines of C=A+B; where A+B is an expression.
An expression is a sequence of operators and their operands, that
specifies a computation. Expression evaluation may produce a result
(e.g., evaluation of 2+2 produces the result 4) and may generate
side-effects (e.g. evaluation of std::printf("%d",4) prints the
character '4' on the standard output).
http://en.cppreference.com/w/cpp/language/expressions
http://en.cppreference.com/w/cpp/language/expressions#Literals
Related
I'm studying the C++ programming language using Programming priciples and practice using C++.
I'm in chapter 4 now and in this chapter the book introduces the concept of expression, but I can't understand it at all :
The most basic building block in a program is an expression. An espression compute a value from a number of operands. The simplest expression in C++ is simply a literal value such as 11, 'c', "hello". Names of variables are also expressions. A variable represent the object which it is the name.
Why a literal is considered an expression ? Why the name of a variable is considered an expression ?
Expressions -in programming languages, in math, in linguistics- are defined compositionally (or inductively). So expressions are often made of subexpressions like x*2+y*4 is made of two sub-expressions x*2 and y*4 joined by the addition operator +.
But you need a base case (the most atomic and simple expressions). These are literals (2) and variables (x) - if either of them was not an expression 2*x could not be an expression (since both operands of the binary multiplication * are sub-expressions).
Notice that in C and C++ assignments and function calls are expressions
Think of it like this: An expression is a sequence of steps that produce a value. Thus, 4+3 is a two-step expression, because you (1) start with the number 4, and (2) add 3 to it.
Therefore, 7 can be regarded as a single-step sequence, because there is only one "action" performed: (1) start with the number 7.
Thus, both a = 4+3; and a = 7; can be generalised to a = <expression>;.
An expression is "a sequence of operators and operands that specifies a computation" (http://en.cppreference.com/w/cpp/language/expressions).
Let see a simple expression: 3 + 3. When you evaluate this expression, you will get the result 6.
So let see another expression: 3. When you evaluate this expression, you will get the result 3.
A literal is considered an expression because a literal is a type of constant and constants are expressions with a fixed value.
A variable is also considered as an expression because it can be used as an operand within another expression or as an expression by itself.
In software design, composite pattern can be used as a representation of the expression.
Consider the following code, which results in the boolean literal true being evaluated in a preprocessor conditional:
#define SOME_MACRO true
int main ()
{
#if SOME_MACRO
return 1;
#else
return 0;
#endif
}
Clang 3.4 and GCC 4.8 both accept this code, even with -pedantic -std=c++11 -Wall -Wextra.
Visual Studio 2013 rejects it, with fatal error C1017: invalid integer constant expression.
My reading of n3376 §
16.1 is that the regular C++ rules for evaluating constant expressions should apply.
If so, this code is valid, and it's a bug if MSVC does not accept it.
But I don't find the standardeze particularly clear. Could someone confirm this?
Yes, it is valid. See C++11 §16.1/4 (emphasis mine)
Prior to evaluation, macro invocations in the list of preprocessing tokens that will become the controlling
constant expression are replaced (except for those macro names modified by the defined unary operator),
just as in normal text. If the token defined is generated as a result of this replacement process or use
of the defined unary operator does not match one of the two specified forms prior to macro replacement,
the behavior is undefined. After all replacements due to macro expansion and the defined unary operator
have been performed, all remaining identifiers and keywords, except for true and false, are replaced
with the pp-number 0, and then each preprocessing token is converted into a token. The resulting tokens
comprise the controlling constant expression which is evaluated according to the rules of 5.19 using arithmetic
that has at least the ranges specified in 18.3. For the purposes of this token conversion and evaluation all
signed and unsigned integer types act as if they have the same representation as, respectively, intmax_t
or uintmax_t (18.4). This includes interpreting character literals, which may involve converting escape
sequences into execution character set members. Whether the numeric value for these character literals
matches the value obtained when an identical character literal occurs in an expression (other than within a
#if or #elif directive) is implementation-defined. Also, whether a single-character character literal may
have a negative value is implementation-defined. Each subexpression with type bool is subjected to integral
promotion before processing continues.
This question already has answers here:
How does the compiler know that the comma in a function call is not a comma operator?
(6 answers)
Closed 8 years ago.
In C++, the comma token (i.e., ,) is either interpreted as a comma operator or as a comma separator.
However, while searching in the web I realized that it's not quite clear in which cases the , token is interpreted as the binary comma operator and where is interpreted as a separator between statements.
Moreover, considering multiple statements/expressions in one line separated by , (e.g., a = 1, b = 2, c = 3;), there's a turbidness on the order in which they are evaluated.
Questions:
In which cases a comma , token is interpreted as an operator and in which as a separator?
When we have one line multiple statements/expressions separated by comma what's the order of evaluation for either the case of the comma operator and the case of the comma separator?
When a separator is appropriate -- in arguments to a function call or macro, or separating values in an initializer list (thanks for the reminder, #haccks) -- comma will be taken as a separator. In other expressions, it is taken as an operator. For example,
my_function(a,b,c,d);
is a call passing four arguments to a function, whereas
result=(a,b,c,d);
will be understood as the comma operator. It is possible, through ugly, to intermix the two by writing something like
my_function(a,(b,c),d);
The comma operator is normally evaluated left-to-right.
The original use of this operation in C was to allow a macro to perform several operations before returning a value. Since a macro instantiation looks like a function call, users generally expect it to be usable anywhere a function call could be; having the macro expand to multiple statements would defeat that. Hence, C introduced the , operator to permit chaining several expressions together into a single expression while discarding the results of all but the last.
As #haccks pointed out, the exact rules for how the compiler determines which meaning of , was intended come out of the language grammar, and have previously been discussed at How does the compiler know that the comma in a function call is not a comma operator?
You cannot use comma to separate statements. The , in a = 1, b = 2; is the comma operator, whose arguments are two assignment expressions. The order of evaluation of the arguments of the comma operator is left-to-right, so it's clear what the evaluation order is in that case.
In the context of the arguments to a function-call, those arguments cannot be comma-expressions, so the top-level commas must be syntactic (i.e. separating arguments). In that case, the evaluation order is not specified. (Of course, the arguments might be parenthesized expressions, and the parenthesized expression might be a comma expression.)
This is expressed clearly in the grammar in the C++ standard. The relevant productions are expression, which can be:
assignment-expression
or
expression , assignment-expression
and expression-list, which is the same as an initializer-list, which is a ,-separated list of initializer-clause, where an initializer-clause is either:
assignment-expression
or
braced-init-list
The , in the second expression production is the comma-operator.
My question sounds probably quite stupid, but I have to answer it while preparing myself to my bachelor exam.
So, what do you think about such an expression 'ab' == "ab" in C++? Is this not true or simply not legal and compiling error? I have googled a little and get to know that 'ab' is in type int and "ab" of course not...
I have to regard not what compilator says but what says formal description of language..
It definitely generates a warning, but by default, gcc compiles it.
It should normally be false.
That being said, it should be theoretically possible, of course depending on the platform you're running this on, to have the compile-time constant "ab" at a memory location whose address is equal in numerical value to the numerical value of 'ab', case in which the expression would be true (although the comparison is of course meaningless).
In both C and C++ expression 'ab' == "ab" is invalid. It has no meaning. Neither language allows comparing arbitrary integral values with pointer values. For this reason, the matter of it being "true" or not does not even arise. In order to turn it into a compilable expression you have to explicitly cast the operands to comparable types.
The only loophole here is that the value of multi-char character constant is implementation-defined. If in some implementation the value of 'ab' happens to be zero, it can serve as a null-pointer constant. In that case 'ab' == "ab" becomes equivalent to 0 == "ab" and NULL == "ab". This is guaranteed to be false.
It is going to give you a warning, but it will build. What it will do is compare the multibyte integer 'ab' with the address of the string literal "ab".
Bottom line, the result of the comparison won't reflect the choice of letters being the same or not.
The Standard has absolutely nothing to say about comparing an integral type with a pointer. All it says is the following (in section 5.9):
The operands shall have arithmetic, enumeration, or pointer type, or
type std::nullptr_t...
It then goes into a detailed description on what it means to compare two pointers, and mentions comparing two integers. So my interpretation of the lack of specification would be "whatever the compiler writer decides", which is either an error or a warning.
Lets consider this to parts in simple C, the 'c' is a simple char if you want to manipulate strings you will have to use array of chars, as a result 'ca' shouldn't work the way you expect, and in c++ this stuff is still valid. If you want to use Strings you will have to use String class which isn't a raw type. And all what it does is a class with methods and type def's so you handle chars of arrays easier. As result even the C-style-string and the array of chars are different stuff, as result 'ab' == "ab" is not going to give a valid boolean respond . It's like trying to compare an int to a string. So, this comaprison will most likely throw an error.
I want to evaluate one expression in C++. To evaluate it, I want the expression to be converted to prefix format.
Here is an example
wstring expression = "Feature1 And Feature2";
Here are possible ways.
expression = "Feature1 And (Feature2 Or Feature3)";
expression = "Not Feature1 Or Feature3";
Here And, Or, Not are reserved words and parentheses ("(", )) are used for scope
Not has higher precedence
And is set next precedence to Not
Or is set to next precedence to And
WHITE SPACE used for delimiter. Expression has no other elements like TAB, NEWLINE
I don't need arithmetic expressions. I can do the evaluation but can somebody help me to convert the strings to prefix notation?
You will need to construct the grammar up front. So why do all the parsing by hand.
Instead use a parser builder library like Boost-Spirit. Or lex/yacc or flex/bison.
Then use the AST generated by the parser builder to output the data in any way you see fit. Such as infix to prefix or postfix, ...etc.
I guess your intention is to evaluate condition. hence you dont need a full fledged parser.
First of all you dont need to work with strings here.
1. Convert "Feature 1" to say an Id (An integer which represents a feature)
So, the statement "Feature1 And (Feature2 Or Feature3)"; to say (1 & (2 | 3)
From here on...you can use the standard Infix to prefix conversion and evaluate th prefix notation.
Here is the algorithm to convert infix to prefix
http://www.c4swimmers.esmartguy.com/in2pre.htm
http://www.programmersheaven.com/2/Art_Expressions_p1
Use a parser generator like the Lex/Yacc pair.