Как заставить препроцессор генерировать строку для ключевого слова __LINE__? - PullRequest
28 голосов
/ 13 апреля 2011

__FILE__ заменяется на «MyFile.cpp» препроцессором C ++.Я хочу, чтобы __LINE__ был заменен на строку "256", а не на целое число 256.Без использования моих собственных письменных функций, таких как

toString(__LINE__);

Возможно ли это?Как я могу это сделать?

VS 2008

РЕДАКТИРОВАТЬ Я хочу автоматически найти и заменить все throw; операторы на

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

в моих источниках.Если я использую макрос или функцию для преобразования __LINE__ в строку, мне нужно будет вручную изменить каждый исходный файл.

Ответы [ 2 ]

59 голосов
/ 13 апреля 2011

Вам нужен трюк с двойным расширением:

#define S(x) #x
#define S_(x) S(x)
#define S__LINE__ S_(__LINE__)

/* use S__LINE__ instead of __LINE__ */

Добавление, годы спустя: Хорошая идея - немного поработать над тем, чтобы избежать операций, которые могут выделить память в путях обработки исключений. Учитывая вышесказанное, вы должны быть в состоянии написать

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

, который будет выполнять конкатенацию строк во время компиляции, а не во время выполнения. Он по-прежнему будет создавать std :: string (неявно) во время выполнения, но это неизбежно.

8 голосов
/ 13 апреля 2011

РЕДАКТИРОВАТЬ : В ответ на запрос о другом ответе я добавил немакро-версию:

#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());
}
...