2016-03-04 3 views
6

Функции библиотеки имеют по умолчанию слабый атрибут (см. [1]) и могут быть «перезаписаны» функциями, имеющими одну и ту же подпись случайно. Например, printf внутренне вызывает fputc, и я мог бы легко объявить одну из своих функций int fputc(int, FILE *). Если это произойдет, я хотел бы получить предупреждение о компиляторе.Как установить предупреждение компилятора (GNU GCC) при перезаписи слабой функции

Есть ли способ сказать компилятору предупредить меня в случае перезаписи слабой функции?

[1] https://gcc.gnu.org/onlinedocs/gcc-3.2/gcc/Function-Attributes.html

+0

Это не будет предупреждение компилятора, но предупреждение компоновщика. BTW GCC3.2 - это средство, не соответствующее текущему стандарту C11 и C++ 14, - текущая версия (марш 2016) - [GCC5] (http://gcc.gnu.org/gcc-5/), поэтому вы должен * обновить * ваш 'gcc' –

+0

Вы * разрешены * для * переопределения *' fputc', если ваше определение соответствует стандарту (и это может быть сложно) –

+0

** Почему вы спрашиваете? ** и что такое фактическая проблема, которую вы хотите решить? Похоже на проблему [XY] (http://xyproblem.info/) ... Итак, пожалуйста, отредактируйте свой вопрос **, чтобы больше объяснить и мотивировать его. –

ответ

3

(я предполагаю, что вы на Linux, и компиляции и компоновки приложения, как обычно, в частности, с libc.soдинамически подключаемой)

Библиотечные функции имеют слабый атрибут, установленный по умолчанию

Это не всегда так; на моей системе fputc не слабый символ:

% nm -D /lib/x86_64-linux-gnu/libc-2.21.so|grep fputc 
000000000006fdf0 T fputc 
0000000000071ea0 T fputc_unlocked 

(если он был слабым, T будет W, и действительно write слабый)

BTW, переосмысление свой собственный fputc (или malloc) является законным (и может быть полезным, но очень сложным), при условии, что он сохраняет семантику, соответствующую стандарту. Ожидается, что в целом слабые символы будут переопределяться (но это сложно).

Есть ли способ сообщить компилятору предупредить меня в случае перезаписи слабой функции?

Нет (компилятор не может предупредить вас надежно).

С только вещь, которая может дать вам некоторое предупреждение является не компилятор (который не знает, какой именно libc будет использоваться во время выполнения, вы можете обновить libc.so после компиляции), но компоновщик, и многое другое точно dynamic linker, то есть ld-linux(8). И предупреждения могут быть надежно предоставлены только во время выполнения (потому что libc.so может быть другим во время сборки и во время выполнения). Возможно, вы хотите LD_DYNAMIC_WEAK.

Если вы готовы потратить несколько недель работы над решением, вы можете рассмотреть возможность использования GCC MELT с вашим собственным РАСПЛАВНЫХ расширения и настроить недавнееGCC испускать предупреждение, когда слабый символ из libc доступен во время компиляции (который может быть не таким же libc динамически связанным во время выполнения, поэтому такая проверка имеет ограниченную полезность) переопределяется.

Возможно, вы можете использовать некоторые LD_PRELOAD trick.

Кроме того, если вы связали статически свое приложение, линкер может дать вам диагностику, если вы переопределите функцию libc.

Read also Drepper's How to Write a Shared Library & Levine's Linkers & loaders книга.