Problem with Macros - c++

HI ,
Can some one help me in understanding why the value of SQUARE(x) is 49 ?
I am using Visual C++ 6.0 .
#define SQUARE(X) X * X
int main(int argc, char* argv[])
{
int y = 5;
printf("%d\n",SQUARE(++y));
return 0;
}

Neil Butterworth, Mark and Pavel are right.
SQUARE(++y) expands to ++y * ++y, which increments twice the value of y.
Another problem you could encounter: SQUARE(a + b) expands to a + b * a + b which is not (a+b)*(a+b) but a + (b * a) + b. You should take care of adding parentheses around elements when needed while defining macros: #define SQUARE(X) ((X) * (X)) is a bit less risky. (Ian Kemp wrote it first in his comment)
You could instead use an inline template function (no less efficient at runtime) like this one:
template <class T>
inline T square(T value)
{
return value*value;
}
You can check it works:
int i = 2;
std::cout << square(++i) << " should be 9" << std::endl;
std::cout << square(++i) << " should be 16" << std::endl;
(no need to write
square<int>(++i)
because the int type is implicit for i)

Because the macro expands to:
++y * ++y
which gives undefined behaviour in C++ - the result could
be anything. This very well known problem should be covered in any decent textbook that covers the use of macros. Which one are you using?

Because macros do textual substitution so the code you wrote gets expanded to
printf("%d\n",++y * ++y );
and then the order of operations is undefined behaviour so this the compiler sees 2 increments and then a multiplication
So be careful with macros better to use functions which as the compiler can expand inline will not take any longer to run.
Secondly don't assume what will happen if you increment and use variables

Macros are not functions: they just alter the text of the program. This operation is called preprocessing and it's automatically executed before your code gets compiled. People write macros to save their time and introduce some variability to their source code.
When you write SQUARE(x), no actual funciton call happens, just the text is modified. The operation is quite dumb, so you have to do additional precautions in cases like yours. Refer to other answers for explanation of your case.

Related

Can ";" be added after "#define" And whether variables can be used in it

A topic has the following code, which is required to indicate the location of the error.
#include<iostream>
#define PT 3.5;
#define S(x) PT*x*x
void main() {
int a = 1, b = 2;
std::cout << S(a + b);
}
I think ";" caused this problem ,and deleted ';' the post compilation test can get the correct results.But the teacher thinks that variables cannot be used in macro definition.
I'm not sure who is right.
I've seen a lot of answers, but what I want to know is not whether it's reasonable to write like this, but what causes the program error in the end.
Add ';' after '#define' Not particularly good, but the compilation can pass. "#define" can also allow variables to appear. So the final error reason is "* a + b"?
There's a couple of problems. Yes, the PT will expand to 3.5; and cause a syntax error. Change that to:
#define PT 3.5
The other issue is that S(a + b) will expand to PT*a + b*a + b which is clearly not what you want. As a matter of convention, macros that perform arithmetic should wrap any expandable parts in parentheses, and the entire macro should also be in parentheses:
#define S(x) ((PT)*(x)*(x))
This ensures that you don't have to worry about expanded expressions wreaking havoc due to operator precedence rules.
Regarding the comment about your teacher...
the teacher thinks that variables cannot be used in macro definition
It's possible that they are talking about the fact that x is just a placeholder for expansion. If you pass a + b and use x twice, then a + b will be evaluated twice. Imagine if you called S(++a)... You'd get PT*(++a)*(++a)
It's usually more appropriate to just write a function, and that avoids problems like the above.
double S(int x) {
return PT * x * x;
}
Or even:
template<class T>
double S(T x) {
return PT * x * x;
}
Macros are just text substitution, so you can do pretty much anything you want, as long as the result of the substitution is valid code. So the literal answer to "Can ';' be added after #define" is yes, but the result might not work.
#define calc(x) ((x) * (x));
void f() {
int g = 3;
int h = calc(g);
}
The result of the macro expansion is
int h = ((g) * (g));;
That's valid code; the second semicolon marks the end of an empty expression, just as if it had been written
int h = ((g) * (g));
;
That's bad style, of course, and it could cause problems in other contexts, so the "right" way to use that macro would be
int h = calc(g)
That way, the text that results from the macro expansion would only have one semi-colon. But that looks weird, and the macro really shouldn't have that semicolon in it.
As to using variables, again, it depends on what the result of the text substitution is.
#define calc (x) * (x)
void f() {
int x = 3;
int y = calc;
}
That's okay; the code is equivalent to
void f() {
int x = 3;
int y = (x) * (x);
}
On the other hand, this isn't okay:
void f() {
int b = 3;
int y = calc;
}
It doesn't work because there is no x there. So this macro has vary limited usefulness; there are rare situations where it might be appropriate, but, in general, it's a bad idea.
You can't put a semicolon after PT because your macro S(X) PT*x*x would get processed to 3.5;*x*x
Your S(x) macro is breaking because the semicolons breaks it into 2 statements. First is 3.5; and the second one is *x*x
hence why you get the error.
To make it work you simply need to remove the ; in your definition of PT

C++ program that use macro [duplicate]

HI ,
Can some one help me in understanding why the value of SQUARE(x) is 49 ?
I am using Visual C++ 6.0 .
#define SQUARE(X) X * X
int main(int argc, char* argv[])
{
int y = 5;
printf("%d\n",SQUARE(++y));
return 0;
}
Neil Butterworth, Mark and Pavel are right.
SQUARE(++y) expands to ++y * ++y, which increments twice the value of y.
Another problem you could encounter: SQUARE(a + b) expands to a + b * a + b which is not (a+b)*(a+b) but a + (b * a) + b. You should take care of adding parentheses around elements when needed while defining macros: #define SQUARE(X) ((X) * (X)) is a bit less risky. (Ian Kemp wrote it first in his comment)
You could instead use an inline template function (no less efficient at runtime) like this one:
template <class T>
inline T square(T value)
{
return value*value;
}
You can check it works:
int i = 2;
std::cout << square(++i) << " should be 9" << std::endl;
std::cout << square(++i) << " should be 16" << std::endl;
(no need to write
square<int>(++i)
because the int type is implicit for i)
Because the macro expands to:
++y * ++y
which gives undefined behaviour in C++ - the result could
be anything. This very well known problem should be covered in any decent textbook that covers the use of macros. Which one are you using?
Because macros do textual substitution so the code you wrote gets expanded to
printf("%d\n",++y * ++y );
and then the order of operations is undefined behaviour so this the compiler sees 2 increments and then a multiplication
So be careful with macros better to use functions which as the compiler can expand inline will not take any longer to run.
Secondly don't assume what will happen if you increment and use variables
Macros are not functions: they just alter the text of the program. This operation is called preprocessing and it's automatically executed before your code gets compiled. People write macros to save their time and introduce some variability to their source code.
When you write SQUARE(x), no actual funciton call happens, just the text is modified. The operation is quite dumb, so you have to do additional precautions in cases like yours. Refer to other answers for explanation of your case.

Change variable type inside main() C++

I have this code , i need output x variable as double (3.14) without changing anything in the main function
#include <iostream>
int main() {
int x = 3.14;
std::cout << x << "\n";
return 0;
}
What should i do ?
There are two solutions, one correct and one your professor probably wants.
The correct solution (one method, there are other similar ones).
Add this right after the #include line:
int main() {
double x = 3.14;
std::cout << x << "\n";
return 0;
}
#if 0
Add this at the end of the file:
#endif
The incorrect solution for your professor.
Add this line before main:
#define int double
Why is this incorrect? Because #defineing a reserved word is undefined behaviour.
[macro.names] A translation unit shall not #define or #undef names lexically identical to keywords [...]
Why do I think your professor probably wants this? Because I've seen a few C++ assignments, and observed that their authors all too often disregard and abuse the C++ standard.
Your professor might want the first solution instead. I have no way to predict that.

Constrain function port from Arduino

I'm now porting arduino code to stm32(c/c++). Please help me with this function:
constrain(x, a, b)
Returns
x: if x is between a and b
a: if x is less than a
b: if x is greater than b
Example
sensVal = constrain(sensVal, 10, 150);
// limits range of sensor values to between 10 and 150
Here a template-version, including a complete program to demonstrate the use (you should be able to copy and paste that):
#include <iostream>
template<class T>
const T& constrain(const T& x, const T& a, const T& b) {
if(x < a) {
return a;
}
else if(b < x) {
return b;
}
else
return x;
}
int main() {
int value = 10;
std::cout << constrain(value, 5, 20) << "\n" // prints "10"
<< constrain(value, 15, 20) << "\n" // prints "15"
<< constrain(value, 5, 9) << std::endl; // prints "9"
}
This can be used for any type that has an operator< (this includes all built-in numeric types, such as int and float).
For Arduino, constrain is not a function, it is a #define'd macro.
It is defined in Arduino.h within the Arduino IDE.
Arduino source code is released under an Open Source license, so you can read it :-)
It's definition is:
#define constrain(amt,low,high) ((amt)<(low)?(low):((amt)>(high)?(high):(amt)))
Which would continue to work in your port to stm32.
Of course, it is a macro, and so is simply a text replacement. Hence the parameters appear in your source code, so their is no new type information.
You may prefer to use functions rather than macros, but as your code is a port of existing code, it may be simpler to continue to use the macro. Then, if the original code is improved or changed, there should be less work to produce a new port.
A small issue about trying to use typed functions, or a template functions, rather than a macro, is it may cause confusion later. Using functions rather than the macro might create new warnings, errors or bugs to be introduced if you try to port any Arduino code. Specifically if the original code uses types or classes to constrain for which you have no matching function, there will be an error which clearly does not exist in the Arduino source. Or worse, a typed or templated function might trigger some C++ type conversions which do not happen in the macro version. You might leave a small 'gotcha' for yourself, or whoever takes on your code in the future.
Looking at Wikipedia under Clamping (graphics), it looks like you could have a type-independent template?
template<typename T>
T clamp(T Value, T Min, T Max)
{
return (Value < Min)? Min : (Value > Max)? Max : Value;
}

C++ Output evaluation order with embedded function calls

I'm a TA for an intro C++ class. The following question was asked on a test last week:
What is the output from the following program:
int myFunc(int &x) {
int temp = x * x * x;
x += 1;
return temp;
}
int main() {
int x = 2;
cout << myFunc(x) << endl << myFunc(x) << endl << myFunc(x) << endl;
}
The answer, to me and all my colleagues, is obviously:
8
27
64
But now several students have pointed out that when they run this in certain environments they actually get the opposite:
64
27
8
When I run it in my linux environment using gcc I get what I would expect. Using MinGW on my Windows machine I get what they're talking about.
It seems to be evaluating the last call to myFunc first, then the second call and then the first, then once it has all the results it outputs them in the normal order, starting with the first. But because the calls were made out of order the numbers are opposite.
It seems to me to be a compiler optimization, choosing to evaluate the function calls in the opposite order, but I don't really know why. My question is: are my assumptions correct? Is that what's going on in the background? Or is there something totally different? Also, I don't really understand why there would be a benefit to evaluating the functions backwards and then evaluating output forward. Output would have to be forward because of the way ostream works, but it seems like evaluation of the functions should be forward as well.
Thanks for your help!
The C++ standard does not define what order the subexpressions of a full expression are evaluated, except for certain operators which introduce an order (the comma operator, ternary operator, short-circuiting logical operators), and the fact that the expressions which make up the arguments/operands of a function/operator are all evaluated before the function/operator itself.
GCC is not obliged to explain to you (or me) why it wants to order them as it does. It might be a performance optimisation, it might be because the compiler code came out a few lines shorter and simpler that way, it might be because one of the mingw coders personally hates you, and wants to ensure that if you make assumptions that aren't guaranteed by the standard, your code goes wrong. Welcome to the world of open standards :-)
Edit to add: litb makes a point below about (un)defined behavior. The standard says that if you modify a variable multiple times in an expression, and if there exists a valid order of evaluation for that expression, such that the variable is modified multiple times without a sequence point in between, then the expression has undefined behavior. That doesn't apply here, because the variable is modified in the call to the function, and there's a sequence point at the start of any function call (even if the compiler inlines it). However, if you'd manually inlined the code:
std::cout << pow(x++,3) << endl << pow(x++,3) << endl << pow(x++,3) << endl;
Then that would be undefined behavior. In this code, it is valid for the compiler to evaluate all three "x++" subexpressions, then the three calls to pow, then start on the various calls to operator<<. Because this order is valid and has no sequence points separating the modification of x, the results are completely undefined. In your code snippet, only the order of execution is unspecified.
Exactly why does this have unspecified behaviour.
When I first looked at this example I felt that the behaviour was well defined because this expression is actually short hand for a set of function calls.
Consider this more basic example:
cout << f1() << f2();
This is expanded to a sequence of function calls, where the kind of calls depend on the operators being members or non-members:
// Option 1: Both are members
cout.operator<<(f1 ()).operator<< (f2 ());
// Option 2: Both are non members
operator<< ( operator<<(cout, f1 ()), f2 () );
// Option 3: First is a member, second non-member
operator<< ( cout.operator<<(f1 ()), f2 () );
// Option 4: First is a non-member, second is a member
cout.operator<<(f1 ()).operator<< (f2 ());
At the lowest level these will generate almost identical code so I will refer only to the first option from now.
There is a guarantee in the standard that the compiler must evaluate the arguments to each function call before the body of the function is entered. In this case, cout.operator<<(f1()) must be evaluated before operator<<(f2()) is, since the result of cout.operator<<(f1()) is required to call the other operator.
The unspecified behaviour kicks in because although the calls to the operators must be ordered there is no such requirement on their arguments. Therefore, the resulting order can be one of:
f2()
f1()
cout.operator<<(f1())
cout.operator<<(f1()).operator<<(f2());
Or:
f1()
f2()
cout.operator<<(f1())
cout.operator<<(f1()).operator<<(f2());
Or finally:
f1()
cout.operator<<(f1())
f2()
cout.operator<<(f1()).operator<<(f2());
The order in which function call parameters is evaluated is unspecified. In short, you shouldn't use arguments that have side-effects that affect the meaning and result of the statement.
Yeah, the order of evaluation of functional arguments is "Unspecified" according to the Standards.
Hence the outputs differ on different platforms
As has already been stated, you've wandered into the haunted forest of undefined behavior. To get what is expected every time you can either remove the side effects:
int myFunc(int &x) {
int temp = x * x * x;
return temp;
}
int main() {
int x = 2;
cout << myFunc(x) << endl << myFunc(x+1) << endl << myFunc(x+2) << endl;
//Note that you can't use the increment operator (++) here. It has
//side-effects so it will have the same problem
}
or break the function calls up into separate statements:
int myFunc(int &x) {
int temp = x * x * x;
x += 1;
return temp;
}
int main() {
int x = 2;
cout << myFunc(x) << endl;
cout << myFunc(x) << endl;
cout << myFunc(x) << endl;
}
The second version is probably better for a test, since it forces them to consider the side effects.
And this is why, every time you write a function with a side-effect, God kills a kitten!