rewrite define macro as c++ code? - c++

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;
}

Related

Is there a way to replace string ">" with > in an 'if' condition?

I came across the below use case, but I could not find a proper solution.
Is there a way to replace string "<" or ">" with condition < or > in an if condition?
Example:
string condition = "<";
if (10 condition 8) // Here I want to replace condition with <
{
// Some code
}
I don't want to do it like:
if ("<" == condition)
{
if (10 < 8)
{
}
}
else if (">" == condition)
{
if (10 > 10)
{
}
}
And my condition will change during run time. I am just searching for a simple way if exist apart from above.
Use case: The user will give some query like below:
input: 10 > 9 => output: true
input: 10 < 7 => output: false
Basically I need to parse this query, as I have these 3 words (10, >, 9) as strings, and somehow I want to convert string ">" or "<" to actual symbol > or <.
You can map the string to a standard library comparator functor such as std::less via a std::map or a std::unordered_map.
You can't create a new operator in C++ (Can I create a new operator in C++ and how?). I can see where you are coming from with this idea, but the language just doesn't support that. You can, however, create a function that takes two operands and a string "argument" and returns the appropriate value.
bool CustomCompare(int operand1, int operand2, string op)
{
if (op == "<")
{
return operand1<operand2;
}
if (op == ">")
{
return operand1>operand2;
}
if (op == "_")
{
return DoTheHokeyPokeyAndTurnTheOperandsAround(operand1, operand2);
}
}
std::function<bool(int,int)> comparator = std::less;
if(comparator(10, 8))
{
//some code
}
See Also:
http://en.cppreference.com/w/cpp/utility/functional/function
http://en.cppreference.com/w/cpp/utility/functional/less
#include <functional>
#include <map>
#include <string>
int main()
{
using operation = std::function<bool(int,int)>;
std::map<std::string, operation> mp =
{{"<", std::less<int>()},
{">", std::greater<int>()}};
int x = 5;
int y = 10;
std::string op = "<";
bool answer = mp[op](x, y);
}
If you are a C++ Ninja, and you are very stubborn to get it working just the way you wish, there is a way, but it is advanced and complicated.
I mostly write POSIX code for VxWorks, but I guess it can be done for any other.
Let's say you have: string myExpression = "mySize > minSize";
"Rebuild the String as a C code" (save to file, use ccppc, gcc, gpp, whatever toolchain you have.)
You need to link it with your code, at least to get ELF relocations for mySize & minSize (I think it can be done using app-load, if you customize your ld command.
Load the code using ld
Jump to the new address you loaded your code to.
All that said, I would not recommend you to do that:
Very complicated.
Not the most stable, and very bug/error prone.
Can lead to major vulnerabilities "Hacker" style,
and proper sanitation is required.
The only pro I can see, is that this method supports everything C has to offer out of the box! BitWise, +-/*^!, even functions as pow(), and such.
A little bit better is:
To compile a function as:
`"bool comparer_AB(int a, int b) { return a " + operator + "}"`
and then call comparer_AB();.

Function call as argument to C macro

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.

if and else without braces

I expect the following code to compile. Clang and VC++ both give me an error on the line with else.
void MyFunction(std::int32_t& error)
{
std::int32_t variable = 0;
if(GetSomething())
error = EOK;
else
error = ERROR;
}
If I put curly braces around error = EOK;, then it compiles. Why does VC++ say:
illegal else without matching if
?
My full code is below, replacing std::uint32_t with a typedef. It still gives the same error in VC++.
using sint32 = int;
#define ERROR 5;
#define EOK 0;
bool GetSomething();
void MyFunction(sint32& error)
{
sint32 variable = 0;
if (GetSomething())
error = EOK;
else
error = ERROR;
}
If your definition of EOK is as follows:
#define EOK 0;
then it would cause this type of error, because it forcibly terminates the if-statement before the else is reached, making it an else without a matching if. The compiler sees this code after macro replacement:
if(GetSomething())
error = 0;;
else
Here is a possible fix:
enum
{
EOK = 0,
ERROR = 5
};
Note that all identifiers starting with E followed by either another uppercase letter or a number are reserved for use as macro names by <cerrno>, so to avoid name clashes consider using a different naming convention for your errors.
To be implest and more efficient, you can do :
error = (GetSomething()) ? 0 : 5 ;
And if you want to with enum as Matt say , it become :
error = (GetSomething()) ? enum.EOK : enum.ERROR ;

C++ FAQ example on inline vs. #define

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;
}

Ill formed code snippets

can somebody please tell me the difference between the following two code snippets:
//Code snippet A: Compiles fine
int main()
{
if(int i = 2)
{
i = 2 + 3;
}
else
{
i = 0;
}
}
//Code Snippet B: Doesn't compile :(
int main()
{
if((int i = 2))
{
i = 2 + 3;
}
else
{
i = 0;
}
}
If you notice the diff is just an extra parenthesis at if statement. I am using g++ compiler.Error is "expected primary-expression before âintâ"
Section 6.4 of the C++ standard (draft n2914 of c++0x) has this to say about the format of if statements:
Selection statements choose one of several flows of control.
selection-statement:
if ( condition ) statement
if ( condition ) statement else statement
switch ( condition ) statement
condition:
expression
type-specifier-seq attribute-specifieropt declarator = initializer-clause
type-specifier-seq attribute-specifieropt declarator braced-init-list
That bit at the end means a condition can be either an expression or a decalarator-type construct.
And the minute the parser hits that second parenthesis, it becomes an expression, so no declarations allowed, I'm afraid.
The snippet:
if (int i = 2) { ... } else { ... }
is perfectly valid C++ in which the if section defines an integer i for the duration of the if/else and sets it to 2. It then uses that 2 as the input to the if (2 is always true, being non-zero).
The snippet if((int i = 2)) is no different syntactically to int x = (int i = 2;); if (x) which is not valid C++.
Snippet A is fine - the if condition delares and initialises a variable that can be interpreted as a boolean. The variable is defined within the if and any else blocks.
Snippet B is wrong, because you can't put parentheses around a declaration - you can only put them round expressions. The following is also wrong for the same reason:
int main()
{
int i; // OK
(i = 2); // OK
(int x = 2); // compile error
}
Here is another variant of second snippet error:
int main()
{
int i = (int j = 0);
return 0;
}
You can't declare variables inside ANY expression.
Second () inside for is the same case - you can declare variable i inside for() but not inside nested expression placed into ().
Hope I explained it in proper words, maybe more correct explanation exists. Actually both code fragments are odd.
Both look wrong.
Just because code compiles it doesn't mean it's valid. I'm surprised that the first case is compiling, since it seems like i isn't defined in the else case.
edit: I'm wrong here, definitions in the if condition are valid for that whole if / else statement.