I was trying the below program
#include <iostream>
using namespace std;
#define MKSTR(x) #x
#define CONCATE( x , y ) (x)##(y)
int main()
{
int xy = 100;
cout << MKSTR(HELLO C++) << endl;
cout << CONCATE(HELLO,C++) << endl;
cout << CONCATE(x,y) << endl;
return 0;
}
and getting the error
error C2065: 'HELLO' : undeclared identifier
. I don't see see why the VS 2012 compiler is expecting the macro argument or is treating them as identifier. Also the MKSTR macro worked fine but the CONCATE macro is giving me trouble. Can't understand why compiler is doing so.
You need to concatenate symbols first, and then expand it in a string, like this (compiles in GCC 4.8.1) :
#include <iostream>
using namespace std;
#define MKSTR(x) #x
#define CONCATE( x , y ) x ## y
#define CONCATESTR( x , y ) MKSTR(x ## y)
int main()
{
int xy = 100;
cout << MKSTR(HELLO C++) << endl;
cout << CONCATESTR(HELLO,C++) << endl;
cout << CONCATE(x,y) << endl;
return 0;
}
output :
HELLO C++
HELLOC++
100
EDIT :
So for the question of why MKSTR(CONCAT(...)) is not working, the reason is because of the expansion order of macros.
Because CONCAT is a parameter of MKSTR and MKSTR uses operator #, the argument is not expanded but instead immediately stringified. You could do this instead to make it work :
#include <iostream>
using namespace std;
#define CONCATE( x , y ) x ## y
#define MKSTR(x) #x
#define MKSTR2(x) MKSTR(x)
#define CONCATESTR( x , y ) MKSTR(x ## y)
int main()
{
int xy = 100;
cout << MKSTR2(HELLO C++) << endl;
cout << MKSTR2(CONCATE(HELLO,C++)) << endl;
cout << CONCATE(x,y) << endl;
return 0;
}
and it will output what you expect.
Related
I want to change the priority of the preprocessor define process.
see the following code:
#include <iostream>
#include <sstream>
#define $(x) << x <<
#define f(x) (#x)
int main()
{
auto world = "universe!";
std::stringstream ss;
ss << f(Hello $(world)) << std::endl;
std::cout << ss.str();
return 0;
}
The code run, but the 'f' macro will always processed before the '$' macro.
The current output:
Hello $(world)
Expected output:
Hello universe!
Thx.
"Solving" the problem:
#include <iostream>
#include <sstream>
#define $(x) << " " << x
#define STRINGIFY(x) #x
#define TOSTRING(x) STRINGIFY(x)
#define f(x, y) TOSTRING(x) y
int main()
{
auto world = "universe!";
std::stringstream ss;
ss << f(Hello, $(world)) << std::endl;
std::cout << ss.str();
return 0;
}
Output:
Hello universe!
You might "delay" expansion with extra indirection:
#define $(x) << x <<
#define STRINGIFY(x) #x
#define f(x) STRINGIFY(x)
but you won't get your expected result but Hello << world << Demo
Without changing your MACRO, you might already get your result by "fixing" your parenthesis (and surrounding):
ss << f(Hello) " " $(world) /*<<*/ std::endl;
Demo.
I try to write spherical bessel function in C++ and use
#include <boost/math/special_functions/bessel.hpp> and sph_bessel(v,x) in my code but error is happened say this not declared in this scope.I compile with g++ test.cpp .please help me.
#include <cmath>
#include <iostream>
#include <boost/math/special_functions/bessel.hpp>
using namespace std;
int main()
{
// spot check for n == 1
double x = 1.2345;
cout << "j_1(" << x << ") = " << sph_bessel(1, x) << '\n';
}
compile the code with:
g++ test.cpp
and give this error:
error: ‘sph_bessel’ was not declared in this scope
cout << "j_1(" << x << ") = " << sph_bessel(1, x) << '\n';
a.cpp:9:38: note: suggested alternative:
In file included from a.cpp:3:0:
/usr/include/boost/math/special_functions/bessel.hpp:544:79: note: ‘boost::math::sph_bessel’
ename detail::bessel_traits<T, T, policies::policy<> >::result_type sph_bessel(unsigned v, T x)
The error message tells you what to do:
a.cpp:9:38: note: suggested alternative:
‘boost::math::sph_bessel’
so the code should be:
cout << "j_1(" << x << ") = " << boost::math::sph_bessel(1, x) << '\n';
or You could add:
using namespace boost::math;
but this is strongly discouraged: Why is “using namespace std” considered bad practice?
So I would instead suggest:
namespace bmath = boost::math;
Then instead of boost::math::sph_bessel(1, x) You can write: bmath::sph_bessel(1, x).
I want to generate different named function useful for writing unit test cases. I want to do this basically to give unique name to each unit test case.
I am using google test framework for writing unit test cases.
I have to use TEST_Macro to write unit test cases. I want to automatically give incrementing numbers to every unit test.
Here is my (non-working) code:
#include <iostream>
using namespace std;
#define join(x, y) x## y
void join(test, __COUNTER__)()
{
cout << "\n 1";
}
void join(test, __COUNTER__)()
{
cout << "\n 2";
}
int main()
{
cout << "Hello world!" << endl;
test0() ;
test1() ;
return 0;
}
What is the correct way to generate unique function names using __COUNTER__?
So this is the old "paste happens before evaluation of macro arguments", so you get test__COUNTER__ instead of test0.
You need to do a nested macro:
#define expandedjoin(x,y) x##y
#define join(x, y) expandedjoin(x, y)
(The rest of your code gives lots of errors because you are passing a void function to cout, which isn't good)
Complete working code:
#include <iostream>
using namespace std;
#define expandedjoin(x,y) x##y
#define join(x, y) expandedjoin(x, y)
void join(test, __COUNTER__)()
{
cout << "\n 1";
}
void join(test, __COUNTER__)()
{
cout << "\n 2";
}
int main()
{
cout << "Hello world!" << endl;
test0();
test1();
return 0;
}
I'm trying to code a macro called EMPTY_OR, which will return the first argument, but if it's empty, it will return the second one.
Here's what I have so far:
#include <iostream>
#define EMPTY_OR(x, y) ( (sizeof(#x) > sizeof("")) ? (x) : (y) )
#define TEST(x, y) EMPTY_OR(y, x)
using namespace std;
int main()
{
int four = TEST(4, );
int eight = TEST(4, 8);
cout << "four: " << four << endl;
cout << "eight: " << eight << endl;
return 0;
}
It's close, but it doesn't work because the first line of the main function expands to the following:
( (sizeof("") > sizeof("")) ? () : (4) )
The condition is never true, so () is never evaluated. I shouldn't care about it, but the compiler does, and it shows an error.
How can I solve it with the most straightforward and standard-compliant (or at least MSVC-compliant) way?
If I'm understanding what you're trying to do correctly, I'd remove the sizeof and just check if the first character in the string is \0;
#define EMPTY_OR(x, y) ( #x[0] ? (x+0) : (y) )
Here's a solution adapted from this article and without Boost that works on anything that I can think of that you can pass:
#define CAT(a, b) CAT_(a, b)
#define CAT_(a, b) a##b
#define IF(cond, t, f) CAT(IF_, cond)(t, f)
#define IF_1(t, f) t
#define IF_0(t, f) f
#define COMMA(x) ,
#define ARG3(a, b, c, ...) c
#define HAS_COMMA(x) ARG3(x, 1, 0,)
#define EMPTY(x) EMPTY_(HAS_COMMA(COMMA x ()))
#define EMPTY_(x) HAS_COMMA(CAT(EMPTY_, x))
#define EMPTY_1 ,
#define EMPTY_OR(x, y) IF(EMPTY(x), y, x)
#define TEST(x, y) EMPTY_OR(y, x)
#include <iostream>
using namespace std;
int main()
{
int t = TEST(1==, ) 1;
int f = TEST(1==, 0==) 1;
cout << "t: " << t << endl;
cout << "f: " << f << endl;
return 0;
}
I want to dynamically create strings using MACRO. e.g. if I have int i in range of 1:n and string "testArray". I should be able to create testArray[0],testArray[1], ... testarray[n-1]
Please let me know if it is possible.
Below is sample code :
void fun2(int x,std::string name)
{
/*do something*/
}
void fun1()
{
for (unsigned int i = 0 ;i < 5 ; ++i )
{
// I want to create a MACRO such that it create "testArray[0]","testArray[1]",..."testArray[4]" etc.
fun2(x,CREATE_ARRAY_ELEM ("testArray",i));
}
}
I tried below but it does not work :
#define STR1(x) #x
#define CREATE_INDEX(paramName,elementIndex) #paramName << "[" << elementIndex << "]"
#define CREATE_ARRAY_ELEM(paramName,elementIndex) CREATE_INDEX(paramName,elementIndex)
#define STRINGIZE_1(x) STR1(x)
You appear to be wanting to create the string literals "testArray[0]", "testArray[1]", etc.. at compile time. Thats not going to happen. You could easily accomplish this at runtime using an ostringstream, but I don't think that is what you're looking for.
If it is what you're looking for, then...
#include <iostream>
#include <sstream>
using namespace std;
static std::string array_str(const char* s, unsigned int i)
{
std::ostringstream oss;
oss << s << '[' << i << ']';
return oss.str();
}
void fun2(int x, const std::string& name)
{
std::cout << x << ':' << name << std::endl;
}
void fun1()
{
for (unsigned int i = 0 ;i < 5 ; ++i )
{
fun2(i, array_str("testArray", i));
}
}
Test Output
0:testArray[0]
1:testArray[1]
2:testArray[2]
3:testArray[3]
4:testArray[4]
you can do like this..means in macros itself you have to display the desired string ..
#include<iostream>
#define STR1(x) #x
#define CREATE_INDEX(paramName,elementIndex) cout <<paramName<< "[" << elementIndex << "]"
#define CREATE_ARRAY_ELEM(paramName,elementIndex) CREATE_INDEX(paramName,elementIndex)
#define STRINGIZE_1(x) STR1(x)
using namespace std;
int main()
{
int testArray;
for (unsigned int i = 0 ;i < 5 ; ++i )
{
// I want to create a MACRO such that it create "testArray[0]","testArray[1]",..."testArray[4]" etc.
CREATE_ARRAY_ELEM ("testArray",i);
}
return 1;
}