Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to make preprocessor generate a string for __LINE__ keyword?

__FILE__ is replaced with "MyFile.cpp" by C++ preprocessor. I want __LINE__ to be replaced with "256" string not with 256 integer. Without using my own written functions like

toString(__LINE__); 

Is that possible? How can I do it?

VS 2008

EDIT I'd like to automatically Find and Replace all throw; statements with

throw std::runtime_error(std::string("exception at ") + __FILE__ + " "+__LINE__); 

in my sources. If I use macro or function to convert __LINE__ into a string I'll need to modify each source file manually.

like image 605
Dmitriy Avatar asked Apr 12 '11 20:04

Dmitriy


People also ask

What is __ LINE __ in C?

__LINE__ is a preprocessor macro that expands to current line number in the source file, as an integer. __LINE__ is useful when generating log statements, error messages intended for programmers, when throwing exceptions, or when writing debugging code.

What is __ file __ in C?

The __FILE__ macro expands to a string whose contents are the filename, surrounded by double quotation marks ( " " ). If you change the line number and filename, the compiler ignores the previous values and continues processing with the new values. The #line directive is typically used by program generators.

How do you #define on multiple lines in C++?

In general, you can write a multi-line define using the line-continuation character, \ .

What does __ LINE __ return?

The __LINE__ is an inbuilt Macro in C programming language, it returns current line number of the code. Example: #include <stdio.h> int main(){ printf("Hello world\n"); printf("Line: %d\n",__LINE__); printf("How are you?\ n"); printf("Line: %d\n",__LINE__); printf("Bye bye!!!\n"); return 0; } Output.


2 Answers

You need the double expansion trick:

#define S(x) #x #define S_(x) S(x) #define S__LINE__ S_(__LINE__)  /* use S__LINE__ instead of __LINE__ */ 

Addendum, years later: It is a good idea to go a little out of one's way to avoid operations that may allocate memory in exception-handling paths. Given the above, you should be able to write

throw std::runtime_error("exception at " __FILE__ " " S__LINE__); 

which will do the string concatenation at compile time instead of runtime. It will still construct a std::string (implicitly) at runtime, but that's unavoidable.

like image 63
zwol Avatar answered Oct 05 '22 15:10

zwol


EDIT: In response to request on the other answer, I added a non-macro version:

#include <iostream> #include <boost/lexical_cast.hpp> #include <string>  #define B(x) #x #define A(x) B(x)  void f(const char *s) { std::cout << s << "\n"; }  int main() {     f(A(__LINE__));    f(boost::lexical_cast<std::string>(__LINE__).c_str()); } 
like image 25
Robᵩ Avatar answered Oct 05 '22 16:10

Robᵩ