I would like to ask why this code prints out 2 instead of 0. Doesn't #define "assign" values to the names of the macros and calculate also the result? How does it give this answer?
#include <iostream>
using namespace std;
#define A 0
#define B A+1
#define C 1-B
int main() {
cout << C<<endl;
return 0;
}
Macros are direct text replacements That means
#define C 1-B
becomes
1-A+1
and then A gets expanded so we have
1-0+1
which is 2. If you want 0 then stop using macros and instead use constant variables
const int A = 0;
const int B = A + 1;
const int C = 1 - B;
And now C is 0.
The preprocessor expands the C macro to 1-B, which expands to 1-A+1 which expands to 1-0+1 which equals 2. Don't think of it in terms of sequential assignment, but you can get the desired behavior by adding parenthesis around the macro definitions. Then the C macro would expand to (1-B), then (1-(A+1)) then (1-((0)+1)) which equals 0.
Edit:
As an example, the code snip below prints 42, even though BAR is "assigned" to FOO when FOO equals 17. This is because the expansion is deferred until it's actually used. On the cout line, BAR is still equal to FOO, but at that point, FOO is now 42, not 17. Note that it's bad practice to redefine a macro without first #undefining it.
#define FOO 17
#define BAR FOO
#define FOO 42
cout << BAR << endl;
Because C expands to 1-0+1
Preprocessor defines simply replace text and don't care about operator precedence or calculation rules.
Related
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.
Assume we have a #define FOO(x,y) something.
I want to construct such macro #define BAR that BAR(x)(y) would call FOO(x,y). How can I do it, if it's possible at all?
I tried following:
#define BAR(x) FOO(x, BAR_
#define BAR_(y) y)
But got:
error: unterminated argument list invoking macro "FOO"
Here's a MCVE:
#include <iostream>
#define FOO(x,y) std::cout << x << y << '\n';
#define BAR(x) FOO(x, BAR0
#define BAR0(y) y)
#define STR(...) STR0(__VA_ARGS__)
#define STR0(...) #__VA_ARGS__
int main()
{
std::cout << STR( BAR(1)(2) );
}
Another attempt:
#define BAR FOO BAR0
#define BAR0(x) (x, BAR1
#define BAR1(y) y)
This one compiles, but leaves FOO (1, 2) unexpanded in the end.
MCVE:
#include <iostream>
#define FOO(x,y) std::cout << x << y << '\n';
#define BAR FOO BAR0
#define BAR0(x) (x, BAR1
#define BAR1(y) y)
#define STR(...) STR0(__VA_ARGS__)
#define STR0(...) #__VA_ARGS__
int main()
{
// Prints `FOO (1, 2)`, but I want `std::cout << 1 << 2 << '\n';`
std::cout << STR( BAR(1)(2) );
}
1. Dissecting the error
Let's start here:
#define BAR(x) FOO(x, BAR_
#define BAR_(y) y)
#define FOO(x,y) foo{x|y}
BAR(1)(2)
Note that I'm only going to use the preprocessor to debug the preprocessor (why do I need to build C++ programs, which invokes the preprocessor anyway, when I can simply just invoke the preprocessor? (That's rhetorical o/c; I'm just telling a story here)).
Here's how the CPP looks at this. We see BAR; that's a function-like macro. Interesting, but not actionable unless we see an open parentheses. Next, we see... an open parentheses. Now we're getting somewhere... we need to identify its arguments. So we keep scanning: BAR(1)... there... that's the matching open parentheses... looks like we're invoking with one argument. BAR it turns out is defined with one argument, so this works great.
Now we perform argument substitution... so we note that BAR's replacement list mentions its parameter (x) in a non-stringifying, non-pasting way. That means we should evaluate the corresponding argument (1), which is easy... that's just itself. That evaluation result then replaces the parameter in the replacement list, so we have FOO(1, BAR_. We're now done with argument substitution.
The next thing we need to do is rescan and further replacement. So we rescan... FOO, ah, yes. That's a function-like macro... FOO( ...and it's being invoked. Now we're getting somewhere... we need to identify its arguments. So, we keep scanning: FOO(1, BAR_(2)...and, suddenly we reach the end of the file. Huh? That's not right. FOO is being invoked; it's supposed to have a matching parentheses.
You might naively think that BAR_(2) should be invoked, but that's not how macros work. They evaluate outer-in, and the "in" (aka, argument tokens) only evaluates if there's a mention of the parameter in the replacement list, where said mention is not a stringification or paste.
Note that if FOO were not a function-like macro, this story would go an entirely different direction. In such a case, FOO( would simply be tokens the preprocessor doesn't care about... so by the time it sees BAR_(2), it will be invoking a macro. But there's another "cheat"; if FOO is passed over without actually invoking the macro FOO, the tokens would also be skipped over. In both cases, FOO(1, 2) will eventually be produced, which is what you want. But if you then want to evaluate FOO as a function-like macro, you have only one choice. You need a second pass; first pass actually allows your second argument in the sequence to be invoked to build your macro, and this pass must not allow FOO to be invoked. The second pass is needed to invoke it.
2. How to do this
Well, that's easy enough:
#define DELAY()
#define BAR(x) FOO DELAY() (x, BAR_
#define BAR_(y) y)
#define FOO(x,y) foo{x|y}
#define EVAL(...) __VA_ARGS__
BAR(1)(2)
EVAL(BAR(1)(2))
Here's how this is different (first line). After BAR's argument substitution, its replacement list is now FOO DELAY() (1, BAR_ instead of just FOO(1, BAR_. Now, during the rescan, it still sees FOO, which is still interesting... but the next token it sees is DELAY, not an open parentheses. So the CPP in this pass decides it's not invoking FOO and passes on it. After the full DELAY() expansion, which produces nothing, it then just sees (1, BAR_; the first three are just tokens. BAR_, however, is a macro invocation, and so goes the story... so the result of expanding BAR(1)(2) is to produce the tokens FOO(1, 2), error free. But that doesn't evaluate FOO.
The EVAL, however, accepts BAR(1)(2) as an argument. Its replacement list mentions its "parameter" (varying arg variant), so BAR(1)(2) is fully evaluated, producing FOO(1, 2). Then FOO(1, 2) is rescanned, which is when FOO actually gets invoked.
Is there some way in C++11 or higher to achieve a similar behavior to:
int some_int;
std::string x=variable_name<some_int>::value; //Theoretical code
std::cout << x;
Result should be:
some_int
If not, is there a compiler specific way to do it? I am targeting MSVS.
You ask:
Is there some way in C++11 or higher to achieve a similar behavior to:
int some_int;
std::string x=type_name<some_int>::value; //Theoretical code
std::cout << x;
Result should be:
some_int
Yes, you can just use the preprocessor's stringizing operator #:
#include <iostream>
#define NAME_OF( v ) #v
using namespace std;
auto main() -> int
{
int some_int;
//std::string x=type_name<some_int>::value; //Theoretical code
auto x = NAME_OF( some_int );
(void) some_int;
cout << x << endl;
}
If you're asking for something different, then please post a new question since this one has now been answered (amending the question would invalidate this answer).
As an example real world usage, here's macro to pass a variable and its name to a test function:
#define TEST( v ) test( v, #v )
If you want a compile time check that the name in question is a variable or type name, then you can simply apply sizeof, e.g. in a comma expression:
#define NAME_OF( v ) (sizeof(v), #v)
The difference between having sizeof or not, is whether this is guaranteed to be done purely at compile time, versus possibly generating code to also do something at run time.
To avoid a possible warning you can add a pseudo-cast to void:
#define NAME_OF( v ) ((void) sizeof(v), #v)
And to make this work also for a function name you can add a typeid:
#define NAME_OF( name ) ((void) sizeof(typeid(name)), #name)
Complete example:
#include <typeinfo>
#define NAME_OF( name ) ((void) sizeof(typeid(name)), #name)
void foo() {}
#include <iostream>
using namespace std;
auto main() -> int
{
int some_int;
(void) some_int;
//std::string x=type_name<some_int>::value; //Theoretical code
auto v = NAME_OF( some_int );
auto t = NAME_OF( int );
auto f = NAME_OF( foo );
#ifdef TEST_CHECKING
(void) NAME_OF( not_defined );
#endif
cout << v << ' ' << t << ' ' << f << endl;
}
The checking is not 100% perfect, though, because it's still possible to pass a function invocation to the NAME_OF macro.
As others have pointed out, you can indeed use a macro to "stringify" the variable name. However, instead of simply defining it as #define NAMEOF(variable) #variable, you can use the following definition:
#define NAMEOF(variable) ((decltype(&variable))nullptr, #variable)
As you can see, it uses a comma operator. The left part of this expression does nothing but performs a (pointless) conversion from nullptr to a pointer to variable's type, the result of which gets immediately discarded. The right part simply returns the stringified variable's name.
Why is this better than simply using #variable in the macro?
Thanks to the decltype() operator, the whole thing will only compile if you pass a variable of some sort and not some arbitrary string or a literal to NAMEOF macro. Consider the following example:
double value = 523231231312.0095;
cout<< NAMEOF(value) << endl; // value
cout<< NAMEOF(value1) << endl; // Compiler error: 'value1' was not declared in this scope
cout<< NAMEOF(42) << endl; // Compiler error: lvalue required as unary '&' operand
Because of this, if during future refactoring you modify the name of value variable, you won't forget to also modify places, where you use its name, since compiler will scream at you, until you also fix every usage of NAMEOF for this variable.
Tested on MinGW-W64 (gcc v5.2.0)
In the comments, #iammilind and #Niall have suggested two other ways to define this macro, which don't rely on C++11-specific decltype() operator:
#define NAMEOF(variable) ((void*)&variable, #variable)
...or...
// Unlike other definitions, this one, suggested by #Niall,
// won't get broken even if unary & operator for variable's type
// gets overloaded in an incompatible manner.
#define NAMEOF(variable) ((void)variable, #variable)
// On the other hand, it accepts literals as parameters for NAMEOF,
// though this might be desired behaviour, depending on your requirements.
NAMEOF(42); // 42
Using such a macro with #Leon's suggestion, based on your comments, we get:
template<class T>
void foo(T var, const char* varname)
{
std::cout << varname << "=" << var << std::endl;
}
#define FOO(var) foo(var, NAMEOF(var))
int someVariable = 5;
FOO(someVariable); // someVariable = 5
FOO(nonExistingVariable); // compiler error!
As follows from the comments, you need it for passing into a function both the value of the variable and its name. This must be done with the help of a macro:
#include <iostream>
template<class T>
void foo(T var, const char* varname)
{
std::cout << varname << "=" << var << std::endl;
}
#define FOO(var) foo(var, #var)
int main()
{
int i = 123;
double d = 45.67;
std::string s = "qwerty";
FOO(i);
FOO(d);
FOO(s);
return 0;
}
Output:
i=123
d=45.67
s=qwerty
Please note C++03! any C++11 solutions are not good for me, but do post them just for knowledge sake.
I know the preprocessor can do things like:
#define FOO 4
#if FOO == 4
cout<<"hi"<<endl;
#endif
What I need is:
#define BAR(X)\
#if X == 4\
cout<<"hi"<<endl;\
#endif
main.cpp
BAR(4)
I don't see why all the needed information wouldn't be available in preprocessor time.
So, Please tell me how to achieve this kind of behavior.
edit 1:
A normal if condition won't work for my case, because I also do things like:
#define BAR(X)\
#if X == 4\
int poop;
#elif
double poop;
#endif
As you've discovered, you can't do this in the way that you've attempted. Macro expansion simply doesn't have inline conditional evaluation, so you'd have to create multiple macros instead.
However, if you're just trying to "optimise" normal code flow, you can rely on your compiler's optimizations. Consider this:
if (true) {
std::cout << "Hi\n";
}
The resulting program will not have any conditional checks in it, because true is always truthy.
Similarly:
if (false) {
std::cout << "Hi\n";
}
The resulting program will not contain any code to produce output, because false is never truthy.
Similarly:
if (4 != 4) {
std::cout << "Hi\n";
}
The program will still not contain the std::cout code.
In many cases, you may use this fact to keep your code simple and achieve your desired effect:
#define BAR(X) \
if ((X) == 4) {
std::cout << "hi" << std::endl;\
}
The constraint here, of course, is that an if statement must be valid at the place you write BAR(5), or BAR(42) or BAR(999).
This is also flexible in that now you can use a runtime value (like BAR(i)) and, although the conditional can no longer be collapsed at compile-time, in such a case you'd have no reason to expect that anyway.
I take this approach in my logging macro: the macro, when called for LOG_LEVEL_DEBUG, expands to a conditional that is statically known never to match, in release builds.
The idea is to let the compiler do the optimising.
You're also going to want to consider using a little macro expansion trick to avoid problems with subsequent else clauses.
You can do this with the preprocessor if the domain of values for the conditional parameter is well-known (and preferably small). For example, supposing the parameter can only have the values 0 and 1:
#define DOIT_0(X)
#define DOIT_1(X) X
#define CONCAT_(X, Y) X ## Y
#define MAYBE(X) CONCAT_(DOIT_, X)
#define BAR(X) MAYBE(X)( cout<<"hi"<<endl; )
#define YESNO 0
BAR(YESNO)
Live on coliru.
Beware of unprotected commas in the argument to BAR.
For equality checks, again over a small range:
#define CONCAT3_(X,Y,Z) X ## Y ## Z
#define EQUAL_0_0(X) X
#define EQUAL_1_1(X) X
#define EQUAL_1_1(X) X
#define EQUAL_0_1(X)
#define EQUAL_0_2(X)
#define EQUAL_1_0(X)
#define EQUAL_1_2(X)
#define EQUAL_2_0(X)
#define EQUAL_2_1(X)
#define DO_IF_EQUAL(X, Y) CONCAT3_(EQUAL_, X, Y)
#define BAR(X) DO_IF_EQUAL(X, 2) ( std::cout << "hi\n"; )
If you can use Boost, you could do this with Boost.Preprocessor:
#define BAR(X) BOOST_PP_EXPR_IF(BOOST_PP_EQUAL(X, 4), cout << "hi" << endl;)
Some answers here were better than others.
The one I accepted was posted by Christian Kiewiet in a comment, but it was the most accurate for my purpose.
Here is the expanded version:
useCases.h
enum UseCases{
useCase1=0,
useCase2,
useCaseNumber//always last for iterations
}
specializer.h
#include "useCases.h"
<template UseCases theCase>
struct StaticCase{
//empty, thus accidents calling from this can't happen
}
//specialization
template<>
class StaticCase<UseCases::useCase1>{
typedef int T;
static foo(T arg){cout<<"case1";};
}
template<>
class StaticCase<UseCases::useCase2>{
typedef double T;
static foo(){cout<<"case2";};
}
Now, I can do
#define BAR1(useCase) StaticCase<useCase>::foo();
or
#define BAR2(useCase) StaticCase<useCase>::T var;
and the call:
BAR1(UseCases::useCase1)//output - case1
BAR1(UseCases::useCase2)//output - case2
#include <iostream>
#include<Windows.h>
#define LENGTH 10;
#define NEWLINE '\n'
using namespace std;
int main(){
int area;
const int WIDTH=20;
area=LENGTH*WIDTH;
cout<<area<<NEWLINE;
system("pause");
}
Error is at line where area is calculated, it says "
operand of * must be a pointer
You should not terminate the macro definitions with ;. Otherwise the expression expands to:
area=10;*WIDTH;
Now the error makes sense, right?
#define LENGTH 10;
should be
#define LENGTH 10
// ^ no trailing ;
At present, the preprocessor expands your code to
area=10;*WIDTH;
// ^ error
Never, ever, terminate a macro with a semicolon.
#define LENGTH 10
is what you need.
Macros are simple text replacements.
Your macro LENGTH expands to the tokens 10;.
Then your statement in main is actually two statements:
area = LENGTH; *WIDTH
This attempts to dereference WIDTH, which is not a pointer and therefore cannot be dereferenced.
Your definition includes a semicolon which would normally end the statement.
#define LENGTH 10;
Remove the semicolon.
Exists error in your LENGTH macros, remove semicolon.
Good: #define LENGTH 10
Use the std::endl for carriage return.
std::cout<< area << std::endl;