C++ 3d.Комментарии


Макросы - часть 2


т.к. # может быть применен только к аргументу макроса. Решением является передача __LINE__ в виде параметра некоторому вспомогательному макросу, но очевидное #define _ADD_tmp_(str,arg) str " <" __FILE__ ":" #arg ">" #define _ADD_(str) _ADD_tmp_(str,__LINE__)

не работает: результатом _ADD_("Ошибка чтения") будет "Ошибка чтения <file.cpp:__LINE__>"

что нетрудно было предвидеть. В итоге мы приходим к приведенному выше варианту, который обрабатывается препроцессором следующим образом: _ADD_("Ошибка чтения") последовательно подставляется в _ADD_tmp_("Ошибка чтения",__LINE__) _ADD_tmp_tmp_("Ошибка чтения",34) "Ошибка чтения" " <" "file.cpp" ":" "34" ">" "Ошибка чтения <file.cpp:34>"

  • Получение значения числового макроса в виде строки. Как показывает практика, данная возможность находит себе применение и за пределами подробностей реализации "многоэтажных" макросов. Допустим, что для взаимодействия с SQL-сервером у нас определен класс DB::Query с соответствующей функцией void DB::Query::Statement(const char *);

    и мы хотим выбрать все строки некоторой таблицы, имеющие равное некому "магическому числу" поле somefield: #define FieldOK 7 // ... DB::Int tmp(FieldOK); q.Statement(" SELECT * " " FROM sometable " " WHERE somefield=? " ); q.SetParam(), tmp;

    Излишне многословно. Как бы это нам использовать FieldOK напрямую? Недостаточно знакомые с возможностями макросов программисты делают это так: #define FieldOK 7 // ... #define FieldOK_CHAR "7" // ... q.Statement(" SELECT * " " FROM sometable " " WHERE somefield=" FieldOK_CHAR );

    В результате чего вы получаете все прелести синхронизации изменений взаимосвязанных наборов макросов со всеми вытекающими из этого ошибками. Правильным решением будет #define FieldOK 7 // ... q.Statement(" SELECT * " " FROM sometable " " WHERE somefield=" _GETSTR_(FieldOK) );




    - Начало -  - Назад -  - Вперед -



    Книжный магазин