can't concatenate __LINE__ in macro - c++

#include <iostream>
#define STR_HELPER(x) #x
#define STR(x) STR_HELPER(x)
#define (__FILE__ ": " STR(__LINE__))
int main()
{
std::cout << FILE_LOCATION << std::endl;
return 0;
}
output:
main.cpp : __LINE__Var+1
Why line no doesn't shown?

I think you have to define your FILE_LOCATION macro, I cannot see the code where you define it in your snippet.
But wouldn't the code below do it?
#define FILE_LOCATION __FILE__ ": " STR(__LINE__)

Related

Change C/C++ Preprocessor priority

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.

Embed Define into a string

I have a preprocessor define that should determine the size of an array.
This constant should also be passed to a HLSL shader.
For this I need to pass it around as a string.
Is there a way to embed preprocessor defines as a string?
#include <iostream>
#ifndef SIZE
#define SIZE 16
#endif
int main() {
const int arr[SIZE] = {}; // array size is 16 :)
const char* str = "SIZE"; // literal is "SIZE" and not "16" :(
std::cout << str << std::endl; // should print "16"
std::cout << SIZE << std::endl; // prints 16, but is not a string
}
You can use a stringifying macro, eg:
#define STRINGIFY(x) STRINGIFY2(x)
#define STRINGIFY2(x) #x
const char* str = STRINGIFY(SIZE);
std::cout << str << std::endl;
Alternatively, use a runtime format via snprintf() or equivalent, eg:
char str[12];
snprintf(str, "%d", SIZE);
std::cout << str << std::endl;
However, you really should be using std::string in C++ instead of char*, eg:
#include <string>
std::string str = std::to_string(SIZE);
std::cout << str << std::endl;
Or:
#include <string>
#include <sstream>
std::ostringstream oss;
oss << SIZE;
std::cout << oss.str() << std::endl;

Identifier Not defined in Macro

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.

MACRO to concatinate __FILE and __LINE__ with formatting

I have used macros in following way in my .cpp file named Test.cpp which is present in the location c:\Test\Test.cpp
Inside test.cpp
#define FILE_NAME strrchr(__FILE__, '\\') ? strrchr(__FILE__, '\\') + 1 : __FILE__
#define S1(x) #x
#define S2(x) S1(x)
#define LOCATION FILE_NAME " : " S2(__LINE__)
//#define LOCATION __FILE__" : " S2(__LINE__) Working but giving the whole file path where as i need only Filename:Line number
Inside Function
{
::MessageBox(NULL,LOCATION,"Test",MB_OK); //Here i am getting only Filename .
}
Please help me in writing a MACRO so that i can get both Filename(Not the full path , only Filename) and Line number in my application .
You try to concatenate string literal with the result of strrchr. This is not feasible. You will need a helper function, something like
std::string get_location(const std::string& file, int line)
{
std::ostringstream ostr;
size_t bspos = file.find_last_of('\\');
if (bspos != std::string::npos)
ostr << file.substr(bspos + 1) << " : " << line;
else
ostr << file << " : " << line;
return ostr.str();
}
#define LOCATION (get_location(__FILE__, __LINE__))

How can I print each function name as the function is called in C++?

I am exploring a large code-base and i am not a gdb fan. I would like add a
LOG(INFO) << __PRETTY_FUNCTION__ in the first line of each function in the code-base. But that's very tedious. Does anyone know a hack to make all function calls to print a LOG message with its function name?
I do something similar to:
#include <iostream>
class LogScope
{
public:
LogScope(const char* scope, const char* file, int line = 0)
: m_scope(scope), m_file(file), m_line(line)
{
std::clog << "[Begin] " << m_scope << ", " << m_file << ", " << m_line << std::endl;
}
~LogScope() {
std::clog << "[End] " << m_scope << ", " << m_file << ", " << m_line << std::endl;
}
private:
const char* m_scope;
const char* m_file;
int m_line;
};
#define NAME_AT_LINE_2(Name, Line) Name##_##Line
#define NAME_AT_LINE_1(Name, Line) NAME_AT_LINE_2(Name, Line)
#define NAME_AT_LINE(Name) NAME_AT_LINE_1(Name, __LINE__)
#define LOG_SCOPE \
::LogScope NAME_AT_LINE(log_scope)(__FUNCTION__, __FILE__, __LINE__)
void f() {
LOG_SCOPE;
}
int main() {
LOG_SCOPE;
f();
}
Seems a duplicate of Automatically adding Enter/Exit Function Logs to a Project
However, You can consider using gprof that has the capability to generate a runtime call tree. You can have dot graphs, which might be easier to read.