Я видел еще один вопрос о 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. Мог бы принести , если это все еще так после моего следующего обновления.
Спасибо, всем, за ваши информационные ответы!
Обновите свой компилятор до [GCC 5] (http://gcc.gnu.org/gcc-5/) и используйте 'gcc -Wall -Wextra -g -std = c11'; вам также может потребоваться обновить свой 'libc', что практически означает обновление вашего дистрибутива Linux до недавнего –
Все, что сообщение gcc 4.6 будет предупреждать о' gets' с предупреждениями, как описано выше. –
@ DavidC.Rankin Но это gcc 4.7.2, и он не предупреждает, даже с набором флагов, которые Basile предоставил выше. –