Сообщение об ошибке при вызове memcpy

Как я могу убедиться, что если кто-то использует специальную функцию (скажем, memcpy) в коде, он возвращает ошибку.

Мы удалили все экземпляры memcpy из кода с помощью некоторой внутренней разработанной функции,

что я хочу убедиться, так это то, что всякий раз, когда кто-то будет использовать memcpy в будущем, компилятор выдает сообщение об ошибке.


c
person Sohrab Ahmad    schedule 11.07.2013    source источник
comment
У вас есть два хороших ответа, но мне любопытно, почему вы хотите запретить memcpy? Это довольно простая функция, и в ней трудно ошибиться.   -  person nonsensickle    schedule 11.07.2013
comment
если вы используете GCC, добавьте #pragma GCC poison memcpy в свой основной файл заголовка, это может вам помочь   -  person How Chen    schedule 11.07.2013
comment
чтобы преодолеть проблему дублирования, да, мы можем использовать memmove, но они его не используют... я не знаю, почему   -  person Sohrab Ahmad    schedule 11.07.2013


Ответы (2)


Вы можете использовать препроцессор для этого, например

#define memcpy(a, b, c) do_not_use_memcpy

Поместите это в заголовочный файл, который включен во все исходные файлы, и препроцессор заменит все вызовы memcpy на (неопределенный) символ do_not_use_memcpy. Поскольку этот символ не определен, вы получите сообщение об ошибке компилятора.

person Some programmer dude    schedule 11.07.2013
comment
Проблема с этим подходом заключается в том, что вновь созданная функция использует memcpy внутри. - person Sohrab Ahmad; 11.07.2013
comment
+1 особенно приятно тем, что он выдаст вам удобочитаемое предупреждение компилятора, содержащее текст do_not_use_memcpy - person Bathsheba; 11.07.2013
comment
@Sohrab Ahmad, undef и переопределить его в новой функции. - person Bathsheba; 11.07.2013
comment
@SohrabAhmad Для этого единственного места отмените определение макроса с помощью #undef memcpy. - person Some programmer dude; 11.07.2013
comment
Для меня это звучит опасно, потому что gcc может заменить некоторые циклы вызовом функции memcpy. Это делается с помощью оптимизации шаблонов распределения древовидных циклов в gcc 4.8. - person Maxime Chéramy; 11.07.2013
comment
@Maxime Оптимизация кода выполняется спустя долгое время после запуска препроцессора, так что это не будет проблемой. На самом деле это не заменяет реальную функцию memcpy, а просто изменяет ее вызовы. - person Some programmer dude; 11.07.2013
comment
Понятно, но вы уверены, что в конце не будет вызова memcpy? Как насчет добавления -fno-builtin-memcpy? - person Maxime Chéramy; 11.07.2013
comment
@Maxime Если этот макрос есть во всех единицах перевода, то явных вызовов memcpy не будет. Этот флаг просто говорит GCC, что он не должен использовать собственную реализацию memcpy, а вместо этого использовать ту, что находится в стандартной библиотеке. - person Some programmer dude; 11.07.2013

Чтобы не ломать библиотеки, используйте атрибут deprecated:

void * my_new_memcpy ( void * destination, const void * source, size_t num )
{
    return memcpy(destination, source, num);
} __attribute__((deprecated));

// Make sure this is used *after* declaring the function
#define memcpy my_new_memcpy
person Tom van der Woerdt    schedule 11.07.2013
comment
Как насчет использования -Wl,-wrap,memcpy вместо этого? - person Maxime Chéramy; 11.07.2013
comment
@Maxime Не уверен: это аргумент компоновщика, в то время как __attribute__((deprecated)) (iirc) интерпретируется компилятором. - person Tom van der Woerdt; 11.07.2013
comment
Я имел в виду, вместо использования #define, но все еще используя устаревший атрибут (хотя я не знаю, возможно ли это). - person Maxime Chéramy; 11.07.2013
comment
@ Максим Я знал, что вы имели в виду это :-) Но вы не можете, потому что deprecated интерпретируется на этапе компиляции, который предшествует этапу связывания (где работает ваш аргумент). - person Tom van der Woerdt; 11.07.2013