Понимание устаревшего C ++ #define - PullRequest
0 голосов
/ 27 марта 2012

У меня есть какой-то устаревший код C ++, который я пытаюсь понять немного лучше.Одна проблема, с которой я сталкиваюсь - это строка вроде:

#define LOG_TRACE_ERROR(s)  LOG_traceError( _T(__FILE__), __LINE__, s )

, которая находится в заголовочном файле.Я вижу, что LOG_TRACE_ERROR - это то, что код вызывает, и передает ему строку, и я вижу, что LOG_traceError - это функция, которая фактически выполняет эту работу, поэтому я предполагаю, что эта строкасопоставляет два разных имени для функции вместе?Что меня смущает, так это то, почему список параметров отличается (просто строка для LOG_TRACE_ERROR и (_T ( FILE ), LINE , s) для LOG_traceError).Кроме того, я не могу найти _ FILE _ или _ LINE _ или s , заданные в любом месте, так как программазнаете, что они?

Ответы [ 4 ]

5 голосов
/ 27 марта 2012

_FILE_ расширяется до имени файла.

_LINE_ расширяется до номера строки.

s - параметр, передаваемый макросу.

Когда вы пишете:

//file.cpp
//...
LOG_TRACE_ERROR("error here"); //line 13

препроцессор преобразует его в:

//file.cpp
//...
LOG_traceError( _T("file.cpp"), "13", "error here" );

_T() - макрос, связанный с UNICODE.Если в среде Unicode, она преобразует вашу строку в wchar_t*.

3 голосов
/ 27 марта 2012

__FILE__ и __LINE__ - это внутренние значения, определенные вашим компилятором, которые расширяются до скомпилированного файла и текущей строки (макрос расширяется в).

С макросами, когда вы говорите (например):

#define YOUR_MACRO(param1, param2) some_function_here(param1 + param2, 0)

вы определяете макрос с двумя параметрами param1 и param2 (в вашем случае есть только один параметр и его имя s).Затем вы можете использовать эти параметры в своем определении макроса в любом случае.

Примечание: вы должны быть осторожны при написании макросов, так как они могут быть сложными.В приведенном выше примере, если вы вызовете:

YOUR_MACRO(x << 2, y << 2)

, он расширится до:

some_function_here(x << 2 + y << 2, 0);

, что на самом деле:

some_function_here(x << (2 + y) << 2, 0);

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

2 голосов
/ 27 марта 2012

__FILE__ и __LINE__, наряду с __DATE__, __TIME__ и некоторыми другими, являются предопределенными макросами, впервые определенными в стандарте ISO / IEC 9899: 1990 (C89) для языка программирования C,section §6.10.8 :

6.10.8 Предопределенные имена макросов

Следующие имена макросов должны быть определены реализацией:

__ DATE__ Дата перевода единицы преобразования предварительной обработки: строковый литерал в форме «Mmm dd yyyy», где имена месяцев совпадают с названиями, сгенерированными функцией asctime, и первымисимвол dd является пробелом, если значение меньше 10. Если дата перевода недоступна, должна быть указана дата, определенная реализацией.

__ FILE__ Предполагаемое имя текущего исходного файла (буквенная строка символов).

__ LINE__ Предполагаемый номер строки (в текущем исходном файле) текущей исходной строки (целочисленная константа).

__STDC__ Целочисленная константа 1, предназначенная для обозначения соответствующей реализации.

__ STDC_HOSTED__ Целочисленная константа 1, если реализация является размещенной реализацией, или целочисленная константа 0, если это не так.

__ STDC_VERSION__ Целое числоконстанта 199901L.

__ TIME__ Время перевода единицы преобразования предварительной обработки: строковый литерал символа в формате "чч: мм: сс", как во времени, сгенерированном функцией asctime.Если время трансляции недоступно, должно быть указано правильное время, определенное реализацией.

Как и все макросы, они оцениваются препроцессором до компиляции вашего кода.

0 голосов
/ 27 марта 2012

_FILE_ и _LINE_ исходят от вашего препроцессора. Подобный макрос - единственный способ получить доступ к этим значениям для строки, в которой вы вызываете Log_traceError (...), если вы не хотите, чтобы пользователь вводил _FILE_ и _LINE_ каждый раз, когда он вызывает LOG_traceError (.. .).

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...