Подтвердить что ты не робот

С++ конкатенация макросов __FILE__ и __LINE__?

Я хочу, чтобы мои сообщения об исключениях содержали информацию о местоположении исключения.

Итак, я хотел бы иметь что-то подобное.

#define LOCATION __FILE__ " : " __LINE__

throw std::exception(std::string("ABCD. ") + LOCATION);

Это определение явно неверно. Как достичь этого?

4b9b3361

Ответ 1

Вам нужен метод с двумя макро-строками (развернуть этот макрос на двух уровнях):

#define S1(x) #x
#define S2(x) S1(x)
#define LOCATION __FILE__ " : " S2(__LINE__)

Почему?

Короткий ответ:

Вам нужно развернуть __LINE__ на двух уровнях, прежде чем передать его на #x.

 

Длинный ответ:

Прежде всего, используя оператор # в функционально-подобном макросе, он должен следовать за параметром макроса, а __LINE__ не является параметром, иначе компилятор жалуется на него бродячим оператором.

Во-вторых, __LINE__ сам является макросом и содержит текущий номер строки, его следует развернуть до номера перед его использованием с помощью #, иначе вы получите строку "__LINE__" вместо числа.

Макро S2(__LINE__) расширяет __LINE__ до номера строки, затем мы передаем номер строки #x.