Помимо -Wall и -Wextra, какие еще инструменты доступны для обнаружения как можно большего количества ошибок или предупреждений? - PullRequest
2 голосов
/ 04 мая 2020

Приведенный ниже код отлично вычисляет факториал числа.

#include <stdio.h>

long int f_fact(int i);

int main() {
    int a;
    long int factorial;

    printf("Please enter a number\n");
    scanf("%d", &a);

    factorial = f_fact(a);
    printf("The factorial is %ld\n", factorial);

    return 0;
}

long int f_fact(int i) {
    int j;
    long int factorial = 1;

    for (j = 2; j <= i; ++j) {
        factorial = factorial * j;
    }
    return (factorial);
}

Однако этот другой код этого не делает. Единственная разница - это for (j = 2; j <= i; ++i) вместо for (j = 2; j <= i; ++j).

#include <stdio.h>

long int f_fact(int i);

int main() {
    int a;
    long int factorial;

    printf("Please enter a number\n");
    scanf("%d", &a);

    factorial = f_fact(a);
    printf("The factorial is %ld\n", factorial);

    return 0;
}

long int f_fact(int i) {
    int j;
    long int factorial = 1;

    for (j = 2; j <= i; ++i) {
        factorial = factorial * j;
    }
    return (factorial);
}

Мой вопрос: как мне лучше всего обнаружить эти маленькие ошибки в коде? Прямо сейчас у меня активированы -Wall и -Wextra, но даже с теми, которые я получаю: Errors: 0 и Warnings: 0, что немного усложняет выявление проблемы. Какие-нибудь рекомендации, как лучше разобраться с ошибками? Спасибо!

Ответы [ 3 ]

3 голосов
/ 05 мая 2020

Компилятор не может проверять логические ошибки. Возможно, вы написали эту инструкцию специально.

О, чтобы проверить еще несколько автоматически обнаруживаемых проблем, G CC знает -pedantic, но, пожалуйста, прочтите полную документацию. И вы можете попробовать функции clang.

Это та область, где в игру вступает модульное тестирование. Начните с хорошей книги, попробуйте несколько фреймворков, а затем проверьте свой лог c.

0 голосов
/ 05 мая 2020

Вы уже знаете и используете -Wall -Wextra, которое может быть дополнено -Werror для обнаружения потенциальных ошибок путем отметки ряда классических c проблем.

Хотя вы можете добавить дополнительные параметры компилятора, чтобы попробовать и обнаруживать другие проблемы, но обнаружить ошибки logi c сложно. Простые опечатки могут быть обнаружены, если, например, переменная установлена, но не используется, но ваша ошибка все равно останется go незамеченной.

Другие меры предосторожности включают стиль кодирования и соглашения об именах: очень строгие правила стиля, особенно последовательное использование пробелов и отступов, помогают сделать код более читабельным и оставляют меньше места для скрытия глупых ошибок. Соглашения об именах тоже помогают: в вашем примере следует называть аргумент не i, а n. i - это имя по умолчанию для индексной переменной, как вы сами убедились, поэтому правильное имя аргумента эффективно предотвратило бы эту ошибку:

long int f_fact(int n) {
    long int factorial = 1;

    for (int i = 2; i <= n; i++) {
        factorial *= i;
    }
    return factorial;
}

Вот несколько дополнительных флагов, которые я использую для своих проектов в дополнение до -Wall -Wextra-Weverything для clang):

  • избежать проблем с потенциально подписанным char типом: -funsigned_char -Wchar-subscripts
  • предотвратить printf со строками переменного формата: -Wformat-nonliteral
  • создать строковые литералы const: -Wwrite-strings
0 голосов
/ 05 мая 2020

" Мой вопрос: как мне лучше всего обнаружить эти маленькие ошибки в коде? "

К сожалению, нет параметров компилятора для обнаружения логические проблемы , ни в G CC, ни в Clang.

Использование неуместного объекта в месте, где может быть вставлен объект того же типа, не может быть обнаружено компилятором, потому что это логическая проблема. Компилятор может обнаруживать только проблемы syntacti c.

Если предполагается, что память не повреждена, ее невозможно найти даже с помощью некоторых дополнительных инструментов анализатора кода, таких как AddressSanitizer или Valgrind.

Единственное, что вы можете сделать, чтобы предотвратить такие ошибки, - это соблюдать осторожность при кодировании.

Избегайте слишком частого копирования и вставки и лучше сосредоточьтесь на написании кодируйте части отдельно.

Что касается предоставленной проблемы, избегайте копирования l oop головок или их частей, особенно внутри вложенных циклов.


Но чтобы ответить на ваш вопрос:

Помимо -Wall и -Wextra, какие еще инструменты доступны для обнаружения как можно большего количества ошибок или предупреждений?

Существуют -Wpedantic / -pedantic, -Wall и -Werror для G CC, например.

Вы можете найти их и другие, перечисленные с соответствующими пояснениями, здесь:

https://gcc.gnu.org/onlinedocs/gcc/Warning-Options.html#Warning -Options


Для Clang у вас fe -Weverything. Список вариантов диагностики c с их описанием вы можете найти здесь:

https://clang.llvm.org/docs/DiagnosticsReference.html

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...