2016-01-09 14 views
2

Я видел еще один вопрос о C, где код использовал gets(), , и я прокомментировал это с обычным предупреждением о том, чтобы никогда не использовать gets(), за исключением , когда вы хотите продемонстрировать, как разбить систему безопасности.Как сделать gcc 4.7 предупреждением об использовании пресловутой функции gets()?

На этот раз я решил проверить, выдал ли мой компилятор предупреждение о использовании gets(). Конечно, я ожидал, что так и будет. Должен, верно? Даже если вы не указали никаких предупреждений?

Представьте себе мое удивление, когда я обнаружил, что не только делает компилятор не предупредит по умолчанию, но я даже не мог понять, как сделать это предупредит!

Компилятор в вопросе GCC 4.7.2 на Debian, а вот код, который я использовал :

#include <stdio.h> 

int main(void) 
{ 
    char s[10]; 

    gets(s); 
    puts(s); 

    return 0; 
} 

Пробовал gcc g.c. Компиляция без предупреждений. Запускается. Получает segfault, если вводит слишком много текста.

Пробовал со всеми стандартными предупреждениями я обычно ставлю в Makefile:

gcc -W -Wall -Wno-long-long -Wshadow -Wlarger-than-1000 \ 
-Wpointer-arith -Wbad-function-cast -Wcast-qual -Wcast-align \ 
-Wconversion -Waggregate-return -Wmissing-prototypes \ 
-Wmissing-declarations -Wpadded -Wredundant-decls -Wnested-externs g.c 

Тот же результат.

Пробовал с -std=c11. Даже это не вызвало предупреждения, которое является довольно странным, учитывая, что gets() даже не существует в C11. Пробовал c99 тоже. Нет предупреждения.

Так что же здесь происходит? Почему этот очень широко используемый компилятор не предупреждает меня, когда я использую самую устаревшую функцию на всем языке C?


EDIT: Действуя по предложению Кит Томпсон ниже, я проверил для атрибута устаревания в stdio.h. Его там не было. Затем я скопировал файл заголовка и поэкспериментировал. Добавление любой из этих строк (которые я , найденных в других заголовков) в конце объявления было генерировать предупреждение:

__attribute_deprecated__ 
__attribute__ ((__deprecated__)) 

Предупреждение:

‘gets’ is deprecated (declared at /usr/include/stdiotz.h:632) [-Wdeprecated-declarations] 

Суммируя ответы Я видно, что версия libc в моей системе не содержит предупреждения, которое существует в более поздних версиях. Это странно, так как предупреждение существует в какой-то форме с по крайней мере 1996 года. Я смутно помню, что libc был раздвоен на меньше всего раз, поэтому, возможно, предупреждение было оставлено из одной ветви значительно позже, чем в других ветвях.

Я думаю, что я спрошу в списках рассылки Debian об этом, и, возможно, сообщит об этом как об ошибке, в зависимости от того, что я узнаю.


EDIT 2: Я смотрел на какой-то исходный код. glibc получил предупреждение с 2007 года, по крайней мере, в libio/iogets.c. eglibc 2,13, то один я, имеет точно такой же код предупреждения:

#ifdef _LIBC 
link_warning (gets, "the `gets' function is dangerous and should not be used.") 
#endif 

Я полагаю _LIBC не был определен, когда библиотека была собрана. Почему, я не знаю. Я не уверен, что цель _LIBC есть.

Итак, ответ, кажется, сводится к «Это библиотека, и по какой-либо причине , в своей мудрости, разработчик Debian ответственность за это скомпилирован это таким образом.» Мы никогда не знаем, почему.

Не собираюсь сообщать об этом как об ошибке, так как я использую oldstable. Мог бы принести , если это все еще так после моего следующего обновления.

Спасибо, всем, за ваши информационные ответы!

+6

Обновите свой компилятор до [GCC 5] (http://gcc.gnu.org/gcc-5/) и используйте 'gcc -Wall -Wextra -g -std = c11'; вам также может потребоваться обновить свой 'libc', что практически означает обновление вашего дистрибутива Linux до недавнего –

+0

Все, что сообщение gcc 4.6 будет предупреждать о' gets' с предупреждениями, как описано выше. –

+0

@ DavidC.Rankin Но это gcc 4.7.2, и он не предупреждает, даже с набором флагов, которые Basile предоставил выше. –

ответ

5

Это не GCC, включающее это предупреждающее сообщение, это GLIBC.

Это маловероятно, что вы используете слишком старую версию GLIBC: предупреждение было вокруг по крайней мере, с 1996 года см линию 67 из this GLIBC code на GitHub для примера (обратите внимание на дату: 15 дек 1996):

link_warning (gets, "the `gets' function is dangerous and should not be used.") 

Скорее всего, вы используете другую библиотеку C.

+0

Только стандартная библиотека, установленная Debian, не сделала ничего особенного. И установка была выполнена менее двух лет назад. Полагаю, я должен сообщить об этом как об ошибке для Debian. –

+0

gcc печатает предупреждение в ответ на аннотацию в 'stdio.h' glibc. –

+0

@KeithThompson На самом деле, gcc печатает * другое * предупреждение - см. Мое редактирование. Возможно, есть специальный атрибут, например '__dangerous__' или, возможно, код * ad hoc *. –

 Смежные вопросы

  • Нет связанных вопросов^_^