There is an example on the FAQ to explain the difference between inline and #define. The code is here
and the link is: http://www.parashift.com/c++-faq/inline-vs-macros.html
Tried with Visual C++, both unsafe() and unsafe(f()) didn't increase i twice. Is there a mistake on the example?
The main idea of #define is that it is just a preprocessor directive, meaning that this:
#define unsafe(i) ( (i) >= 0 ? (i) : -(i) )
will preprocess your code before it is compiled, and will replace the statement
unsafe(x++);
with the following
((x++) >= 0 ? (x++) : -(x++));
Everytime x++ is evaluated, x gets incremented.
One possible reason why you have problems with getting this sample code right might be that you compile your code with optimizations that optimize out all the unused / unnecessary code.
If you don't use your x anywhere, then it is considered as unused, hence does not get included into compiled code.
Just tested the example, Check Eric Gopak's answer for the explanation:
// A macro that returns the absolute value of i
#define unsafe(i) \
((i) >= 0 ? (i) : -(i))
// An inline function that returns the absolute value of i
inline
int safe(int i)
{
return i >= 0 ? i : -i;
}
int countCalls = 0;
int f()
{
return countCalls++;
};
int main()
{
int x = 0;
int ans = 0;
ans = unsafe(x++); // Error! x is incremented twice
ans = unsafe(f()); // Danger! f() is called twice
// x = 2
// countCalls = 2
ans = safe(x++); // Correct! x is incremented once
ans = safe(f()); // Correct! f() is called once
// x = 3
// countCalls = 3
return 0;
}
Related
I noticed sometimes developers do these in their project;
while(int x = 0) {//run code}
int y = 0;
if (y = someFunction())
{//run code}
I want ask;
why c++ allow to do these in loops like while,(maybe for as well?) and if-else statements, what is the usage?
when someone should do this in his project?
and when conditions like these give result true?
what is the usage?
Declaration inside if/for/while allows to reduce scope of the variable.
so, instead of
int y = somevalue();
if (y) {// y != 0
// ...
}
// y still usable :/
or
{ // extra block :/
int y = somevalue();
if (y) {// y != 0
// ...
}
}
// y no longer usable :)
you might directly do:
if (int y = somevalue()) // y != 0
// ...
}
// y no longer usable :)
with syntax which might indeed surprise.
For more controversial:
int y;
// ...
if (y = somevalue()) // y != 0
// ...
}
// y still usable :)
it is allowed as that assignation is an expression convertible to bool (value of y = x is y (which has been assigned to x)).
it is more controversial as error prone as unclear if = or == is expected.
some convention use extra parents to more clearly express assignation
if ((y = somevalue())) // really = intended, not ==
// ...
}
when someone should do this in his project?
For existing projects, try to use existing convention.
For new project, you have to do the trade of:
scope versus syntax not shared with other language which might be surprising
and when conditions like these give result true?
when given expression convert to true, so non zero integral, non null pointer.
c++17 introduces another syntax to allow to split declaration and condition for if/while. (for already allow that split)
if (int y = somevalue(); y != 42) // y != 42
// ...
}
// y no longer usable :)
How i can write this macro as c++ code?
extern bool distribution_test_server;
bool distribution_test_server = false;
#define GetGoldMultipler() (distribution_test_server ? 3 : 1)
And one more question, what is the vale of the macros if distribution_test_server = false;
Soo if distribution_test_server is false... then the macro it's not used?
Example i have this :
#define GetGoldMultipler() (distribution_test_server ? 3 : 1)
You can write it as an inline function:
inline int GetGoldMultipler()
{
return distribution_test_server ? 3 : 1;
}
If distribution_test_server is false, the multiplier returned is 1.
It's already C++ code, but I assume you want to rewrite it as a function:
int GetGoldMultiplier() {return distribution_test_server ? 3 : 1;}
If distribution_test_server is false then the gold multiplier will be 1; that's how ?: works. (If the first part is true, the second part is returned; else the third part)
What is defined in this macro is what we call a ternary expression.
It's basically an "if" condition concatenated, this expression can be resumed as :
int MyFunction()
{
if(ditribution_test_server == true)
{
return 3;
}
else
{
return 1;
}
}
more on ternary conditions : http://www.cprogramming.com/reference/operators/ternary-operator.html
Now the macro is something completely different. When you define a macro and use it in your code, the compiler replace the macro by what you wrote on the right side.
For example :
#define MY_MACRO 8
int a = MY_MACRO;
actually translate to:
int a = 8;
more on macros : http://www.cplusplus.com/doc/tutorial/preprocessor/
So in your code #define GetGoldMultiplier() (distribution_test_server ? 3 : 1) defines a macro named GetGoldMultiplier() (which is NOT a function !) which upon use will be replaced by (distribution_test_server ? 3 : 1) which can be interpreted as what I wrote before.
The macro will replace any place it you code where there is the symbol GetGoldMultiplier() with the expression "distribution_test_server ? 3 : 1" And this happens as a precompilation step so before the code is interpreted. This also means that there never will be a function GetColdMultiplier() even if your code looks like it is calling it.
This means that if distribution_test_server is false then the expression will always be 1. if it is true the value will always be 3.
That is because the expression
val = a ? 3 : 1
is a short hand syntax inherited from C for the code
if (a)
{
val = 3;
}
else
{
val = 1;
}
You could so of achieve the same thing with an inline function but inline is only a compiler suggestion the macro is guaranteed to do this. But if inlining is preformed, then the result will be equivalent.
inline int GetGoldMultipler()
{
return distribution_test_server ? 3 : 1;
}
Could someone explain to me what happens in this? From the little knowledge I have(and clearly I am wrong in my thinking), to me this should keep decreasing x by 1 until x is 3. Then it should go to the 'return true, part and as the function returns true, it goes back to the second if statement, return false and then exit the function since there is nothing to do if the function returns false. But this keeps going back to the second if statement adding 1 to x until it is 9 again and then exits. Thanks in advance.
bool Rec(int x)
{
if( x > 3)
{
if(Rec(x - 1) == true)
{
return false;
}
else
{
return false;
}
}
else
{
return true;
}
}
void main()
{
Rec(9);
}
Actually I don't see a problem with the way your code functions. It actually works.
It can be simplified and is equivalent to:
#include <stdio.h>
bool Rec(int x)
{
printf("x = %d\n", x);
if (x > 3)
{
Rec(x - 1);
return false;
}
return true;
}
int main(int argc, char* argv[])
{
Rec(9);
return 0;
}
Which produces:
x=9
x=8
x=7
x=6
x=5
x=4
x=3
However you've also said: "But this keeps going back to the second if statement adding 1 to x until it is 9 again and then exits". But you're not actually adding 1 to x. I think what's going on is to do with your debug. You haven't put any debug in your code to print out said behaviour.
So I'll attempt to do it for you.
bool Rec(int x)
{
printf("x = %d\n", x);
if (x > 3)
{
Rec(x - 1);
printf("*x = %d\n", x);
return false;
}
return true;
}
Which produces:
x = 9
x = 8
x = 7
x = 6
x = 5
x = 4
x = 3
*x = 4
*x = 5
*x = 6
*x = 7
*x = 8
*x = 9
Think about this carefully. You're not adding 1. Your function is calling itself again printing x = and then if it's greater than 3 doing the same. Only when x > 3 does it return. After it returns it will again print *x =
So it's actually printing what x was before the recursive call. I hope that helps you see what's going on.
Your function is fine to see how recursion works. But in practice you'd never write code like that. Because you could just write it as a simple loop.
Avoid recursion if you can come up with code using a loop. But sometimes, recursion is easier. For example, traversing binary trees is really simple with recursion.
There are some answers on this question here which give real world examples of where recursion makes sense. Real-world examples of recursion
This is the nature of the recursion. You called function 6 times, it is going to return 6 times.
Recently I'm working on Macros and I got stuck in very simple problem. Here is my code:
#include <iostream>
#define abs(A) (A<0)? -A:A;
using namespace std;
int dis(int x, int y)
{
return abs(x-y);
}
int main()
{
cout<<dis(2,4);
}
Basically abs() takes the absolute of the given value, then the distance is calculated. But in this case it gives the output -6 rather than the 2.
This is because of the way your macro will be evaluated, i.e. during the preprocessor stage of code compilation process, the return abs(x-y) would be changed to:
return abs(x-y)
(A<0) -> -A
(2-4) < 0 = -2 -> -2-4 = -6
You should either change the definition of your macro (better solution), by wrapping macro variables in brackets, to:
#define abs(A) ((A)<0) ? -(A):(A);
or change your code to:
int dis(int x, int y)
{
int res = x-y;
return abs(res);
}
Please note that there is also a abs() function in C Standard Library.
First a little code:
int counter = 0;
int get_counter() { return counter++; }
#define EVEN_OR_ZERO(cc) ( (cc) % 2 == 0 ? (cc) : 0 )
int next_even_or_zero = EVEN_OR_ZERO(get_counter());
This code might seem OK, but... Let's expand the macro:
int next_even_or_zero = get_counter() % 2 == 0 ? get_counter() : 0;
As you can see the macro will only return odd numbers - which is the opposite of what was expected (or desired).
The question: Is there any way to get this work as intended with a macro? Or is a regular function the only way to go?
//This works as wanted
int even_or_zero(int value) { return value % 2 == 0 ? value : 0; }
#define EVEN_OR_ZERO(cc) even_or_zero(cc)
This may be the perfect answer or a bad joke, depending on why you need a macro, which you haven't told us.
The answer is simple: Don't use a macro, unless there's a good reason for it. This case isn't one of them:
int even_or_zero(int i) {
if (i % 2) {
return 0;
} else {
return i;
}
}
Make two functions.
int getCurrentCounter() { ... } // just return here
int getNextCounter() { ... } // increment here
This is how - in example - sequences is PSQL works.
Also, this seems like very bad code design.
don't use macros in C++, there are more better ways to achieve what you want (usally) without using them
functions with sideeffects on global variables are not that good. Think if it would not be better to create struct/class with it's counter and add methods to it. Or better yet, could hide methods as prive at set methods/class as their friends to limit who can affect counter.