Более старый код в нашем приложении содержит звонки на malloc
, realloc
и free
. Благодаря нашему обновленному коду наши собственные реализации вызываются вместо стандартных реализаций. Примеры приведены ниже,
#define malloc(s) OurMalloc(s)
#define free(p) OurFree(p)
Это прекрасно работает для обновленного кода и для более нового кода C ++, мы просто реализуем глобальные операторы new
и delete
, поэтому решение C ++ «чище».
Проблема в том, что теперь нам нужно включить стороннюю библиотеку, в которой есть классы, содержащие методы с именами, такими как malloc
и free
, например,
class ABC
{
public:
...
void free (char *p);
};
Если свободный метод класса имеет одинаковое количество аргументов, препроцессор C / C ++ просто заменяет все вхождения free
на ourFree
, даже в определении класса, даже при вызове метода, свободного от класса ABC
.
Итак определение класса выше и следующий вызов:
ABC abc;
abc.free(p);
заменены на
class ABC
{
public:
...
void OurFree (char *p);
};
ABC abc;
abc.OurFree(p);
Который может компилироваться, но который, конечно, не связывается.
Если ABC::free
имеет количество аргументов, отличное от стандартного free, компилятор по-прежнему выдает предупреждение. мы бы хотели их избежать.
Некоторые альтернативные решения:
- отмена определения в начале стороннего включаемого файла и переопределение его позже
- убедитесь, что сторонний включаемый файл всегда включен до нашего собственного определения
Но даже в этом случае, если наш код должен вызывать эти malloc или свободные методы сторонних классов, препроцессор все равно будет изменять вызовы, если мы не напишем все вызовы следующим образом:
(abc::free)(p)
Есть ли способ сказать, что препроцессор C / C ++ определяет это?
- должны быть заменены только чистые C-вызовы
- прототипы НЕ ДОЛЖНЫ заменяться
- методы в классах НЕ ДОЛЖНЫ заменяться