Можно ли применить переопределение макроса к одному файлу cpp?

Я использую Rapidjson, библиотеку всех заголовков. В rapidjson.h есть макрос RAPIDJSON_ASSERT, в одном из моих cpp-файлов я хотел бы его переопределить, поэтому у меня в верхней части файла есть этот код:

#include "stdafx.h" // for windows
#pragma push_macro("RAPIDJSON_ASSERT")
#define RAPIDJSON_ASSERT(x) if(!(x)) throw std::logic_error("rapidjson exception");

#include "rapidjson/rapidjson.h"
#include "rapidjson/document.h"
#include "rapidjson/stringbuffer.h"
#include "rapidjson/writer.h"

....
....
#pragma pop_macro("RAPIDJSON_ASSERT")

Вот как rapidjson.h определяет RAPIDJSON_ASSERT:

#ifndef RAPIDJSON_ASSERT
#include <cassert>
#define RAPIDJSON_ASSERT(x) assert(x)
#endif // RAPIDJSON_ASSERT

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

Проблема в том, что когда я запускаю код в отладчике, RAPIDJSON_ASSERT не переопределяется. Я проверил stdafx.h на наличие чего-либо, что могло бы включать заголовочные файлы Rapidjson, и ничего не нашел.

Я исходил из того, что каждая единица компиляции должна проходить через заголовочные файлы.

Обратите внимание, что если я перенесу переопределение макроса в stdafx.h, я получу переопределение макроса, но я надеялся, что смогу сделать это для каждой единицы компиляции.


person bpeikes    schedule 29.06.2016    source источник
comment
вы включаете rapidjson в stdafx.h?   -  person jaggedSpire    schedule 29.06.2016
comment
Схема кажется неправильной. Вы хотели изменить макрос внутри Rapidjson для этой единицы перевода или просто внутри вашей единицы перевода? Если последнее, поместите переопределение после заголовков rapidjson. В противном случае Rapidjson может просто переопределить сам макрос.   -  person KABoissonneault    schedule 29.06.2016
comment
@jaggedSpire - я не включил rapidjson.h в stdafx.h, поэтому я не уверен, почему он не переопределит макрос.   -  person bpeikes    schedule 30.06.2016
comment
@KABoissonneault - я добавил некоторую информацию к вопросу. В частности, о том, как Rapidjson.h определяет. Похоже, вы должны определить макрос до его включения, а не после.   -  person bpeikes    schedule 30.06.2016


Ответы (1)


Похоже, вы хотите изменить определение RAPIDJSON_ASSERT для самого кода RapidJSON.

Если это так, вам нужно добавить #define после места, где он определен. Если вы не хотите редактировать файл rapidjson.h, единственная альтернатива — сделать это:

#include "stdafx.h" // for windows

// One would assume that the macro gets defined somewhere inside here
#include "rapidjson/rapidjson.h"

// Compiler will complain about macro redefinition without this #undef
#undef RAPIDJSON_ASSERT    
#define RAPIDJSON_ASSERT(x) if(!(x)) throw std::logic_error("rapidjson exception");

#include "rapidjson/document.h"
#include "rapidjson/stringbuffer.h"
#include "rapidjson/writer.h"

Теперь определение RAPIDJSON_ASSERT изменено для остальных заголовочных файлов. Вам не нужны махинации с push_macro и pop_macro — макросы действительны только для каждого юнита.

Обратите внимание, что не рекомендуется переопределять вещи для библиотек с помощью #define.

person rep_movsd    schedule 29.06.2016
comment
Я добавил некоторую информацию в вопрос, но в документах указано, что вы должны определить RAPIDJSON_ASSERT до включения файла, а не после. Что не имеет смысла, так это то, что оператор #ifndef rapidjson.h каким-то образом проверяется только один раз во всех единицах компиляции. - person bpeikes; 30.06.2016
comment
Полностью отключить предварительно скомпилированные заголовки и попробовать? - person rep_movsd; 01.07.2016
comment
Я думал, что проблема может быть в предварительно скомпилированных заголовках. Я попробую. - person bpeikes; 05.07.2016