Отключить предупреждающие сообщения в GCC через заголовочные файлы? - PullRequest
6 голосов
/ 31 июля 2009

Я использую функцию gets() в моем C-коде. Мой код работает нормально, но я получаю предупреждение

(.text+0xe6): warning: the `gets' function is dangerous and should not be used.

Я хочу, чтобы это предупреждение не появлялось. Есть ли способ?

Мне интересно, что могут быть такие возможности, создав файл заголовка для отключения некоторых предупреждений. Или есть какие-то варианты во время компиляции, которые могут служить моей цели? Или может быть есть особый способ использования gets(), чтобы это предупреждение не всплывало?

Ответы [ 10 ]

27 голосов
/ 31 июля 2009

Очевидный ответ состоит в том, чтобы узнать из того, что компилятор пытается вам сказать - вы никогда не должны использовать get (), поскольку это абсолютно небезопасно. Вместо этого используйте fgets () , что позволяет предотвратить возможные переполнения буфера.

#define BUFFER_SIZE 100
char buff[BUFFER_SIZE];
gets( buff);   // unsafe!
fgets( buff, sizeof(buff), stdin );   // safe
24 голосов
/ 31 июля 2009

Если вы действительно хотите использовать его.

Вот ответ От: http://www.gamedev.net/community/forums/topic.asp?topic_id=523641

Если вы используете достаточно свежую версию gcc, вы можете использовать:

#pragma GCC diagnostic ignored "your option here"

Например, если эти заголовки выдают ошибку «Сравнение с плавающей запятой небезопасно», вы должны использовать:

#pragma GCC diagnostic ignored "-Wfloat-equal".

К сожалению, вы не можете отключить «-Wall» таким образом (это было бы слишком просто, не правда ли ...), вы должны сделать отдельные параметры предупреждения, которые -Wall активируют вручную (по крайней мере, конфликтующие из них).

Документы: http://gcc.gnu.org/onlinedocs/gcc/Diagnostic-Pragmas.html#Diagnostic-Pragmas

EDIT: Но, похоже, не работает предупреждение о получении ... Я пытался на моем компьютере.

9 голосов
/ 31 июля 2009

Я бы учел предупреждение и заменил gets. Это достаточно ясно для меня:

ОШИБКА

Никогда не используйте get (). Потому что невозможно сказать, не зная данных в заранее, сколько символов get () будет читать, и потому что gets () будет продолжать хранить символы после конца буфера, это чрезвычайно опасно для использования. Она имеет был использован для взлома компьютерной безопасности. Вместо этого используйте fgets ().

8 голосов
/ 31 июля 2009

Используйте fgets () вместо gets ()

char buffer[BUFSIZ];
/* gets(buffer); */
fgets(buffer,sizeof(buffer), stdin);

Функция gets () не проверяет длину буфера и может записывать после конца и изменять стек. Это «переполнение буфера», о котором вы слышали.

6 голосов
/ 31 июля 2009

На самом деле нет веских оснований для использования gets(). Даже стандарт C говорит, что он устарел! Вместо этого используйте fgets().

[Изменить]

Похоже, предупреждение исходит от компоновщика. Вы получаете предупреждение при компиляции с -c? (Который отключает связывание.)

5 голосов
/ 31 июля 2009

Вам вообще не следует использовать функцию gets, на странице руководства сказано, что вместо нее следует использовать fgets.

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

1 голос
/ 11 декабря 2014

Предложите безопасную замену gets().

В существующем коде для замены gets() может быть нежелательно использовать fgets(), поскольку для этой функции требуется дополнительный char для сохранения '\n', который потребляют обе функции, но gets() не сохраняет , Ниже приводится замена, которая не требует большего размера буфера.

Каждый gets(dest) заменяется на:
Если dest является массивом, используйте gets_sz(dest, sizeof dest)
Если dest является указателем на массив char размером n, используйте gets_sz(dest, n)

char *gets_sz(char *dest, size_t size) {
    if (size <= 1) {
        if (size <= 0 || feof(stdin)) {
            return NULL;
        }
    }
    size--;
    size_t i;
    for (i = 0; i < size; i++) {
        int ch = getchar();
        if (ch == EOF) {
            if (i == 0)
                return NULL;
            break;
        }
        if (ch == '\n')
            break;
        dest[i] = (char) ch;
    }
    dest[i] = 0;
    return dest;
}
0 голосов
/ 28 января 2019

-fno-stack-protector - это опция, которая позволяет использовать функцию gets(), несмотря на ее небезопасность.

-Wno-deprecated-declarations отключает предупреждение об устаревании

Вот пример компиляции с gets()

gcc myprogram.c -o myprogram -fno-stack-protector -Wno-deprecated-declarations

Я согласен со всеми, кто говорит, что это совершенно небезопасно, поскольку позволяет программе переполнять буфер. Это может быть довольно опасно, и, следовательно, причина, по которой он устарел в пользу fgets.

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

0 голосов
/ 02 марта 2018

Если вы действительно хотите его использовать, попробуйте флаг -fsyntax-only.

В руководстве на сайте gcc написано:

-fsyntax-only

Check the code for syntax errors, but don't do anything beyond that.
0 голосов
/ 18 ноября 2010

Вопреки распространенному мнению, не все программисты одинаково невнимательны к тому, что пишут. gets() всегда будет стандартным в C90, и его поместили в библиотеку по нескольким веским причинам. Она не более «опасна», чем любая другая строковая функция, если ее использовать надлежащим образом, например, в примерах программ, документации, подмостах модульного теста, домашних заданиях и т. Д.

Более того, gets() повышает удобочитаемость таким способом, которого fgets() никогда не будет. И никогда не нужно прерывать ход мыслей, чтобы посмотреть, в каком порядке приводить свои аргументы.

Следующий обходной путь использует мою другую любимую функцию для удаления новой строки. :)

 #define gets GET_LOST
 #include "stdio.h"
 #undef gets

 #include "limits.h"

 char *gets(char *s)
 {
    return strtok(fgets(s, INT_MAX, stdin), "\n");
 }
...