Как стать автором
Обновить

Комментарии 26

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

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

Вообще, если не указать void, значит функция может принимать сколько угодно параметров.

Этот пример компилируется:

#include <stdio.h>

static void print_hello() {
    puts("Hello World");
}

int main(void) {
    print_hello();
    print_hello("lol", "kek");
}

clang выводит предупреждение:

test.c:9:29: warning: too many arguments in call to 'print_hello'
    print_hello("lol", "kek");
    ~~~~~~~~~~~             ^
1 warning generated.

До gcc пока не добрался, но, по-моему, он не выводит предупреждение в таких случаях.

Если же добавить void, пример не скомпилируется:

test.c:9:17: error: too many arguments to function call, expected 0, have 2
    print_hello("lol", "kek");
    ~~~~~~~~~~~ ^~~~~~~~~~~~
test.c:3:13: note: 'print_hello' declared here
static void print_hello(void) {
            ^
1 error generated.

Я добрался до gcc, он и правда не выводит предупреждение, если не указать void вместо списка аргументов, причём даже с флагами -Wall и -Wextra. У меня, если что, gcc версии 13.2.1

/* объявление функции без аргументов */
int no_args();
/* тоже объявление функции без аргументов */
int no_args(void);

Первый вариант означает, что тип и кол-во аргументов не определены (можно писать no_args(1,2,3)), второй вариант означает, что аргументов у функции нет. Первый вариант можно отнести к быдлокоду, он ещё жив, полагаю, для совместимости...

https://habr.com/ru/companies/badoo/articles/503140/comments/#comment_21653930

Или можно компилировать с `-std=c2x` :)

НЛО прилетело и опубликовало эту надпись здесь

Кроме gcc ещё clang вроде их поддерживает.

Даже TinyCC поддерживает. Правда, только в транке, и только в качестве синтаксического сахара (т.е. на unwind выполнятся не будут).

Старший бит отвечает за знак, остальные за само число.

И тут студент получает контрольный вопрос в голову: почему 1 0000000₂ — это (-128), а не (-0).

Ошибка:

0 - это старший байт и он отвечает за знак.

Не байт, а бит.

Undefined Santizer - Санитайзер, который...

Слово Behavior "выпало":

UndefinedBehaviorSanitizer, a fast undefined behavior detector

https://gcc.gnu.org/onlinedocs/gcc-13.2.0/gcc/Instrumentation-Options.html#index-fsanitize_003dundefined

Кстати, в первый раз увидел в тексте документации GCC ссылку на llvm.org.

У Вас scanf написан как sacnf.
"А как sacnf данные получает?"

Безопасное программирование на Си

Самый безопасный способ заниматься безопасным программированием на Си - не писать на Си. Отсутвие честных типов делает задачу фактически невыполнимой. Если не следовать какому-нибудь MISRA-гайдлайну и не торчать постоянно в статическом анализаторе - безопасный код на Си будет являться тавтологией.

Не писать на си иногда не вариант, я вот понял, что всякую низкоуровневую фигню ни на плюсах, ни на расте я писать не желаю. Можно, кстати, упороться и писать доказуемо корректные программы на си. А тавтология - это использование одного и того же слова в предложении, разве нет?

попробуйте zig или odin. у первого говорят даже интероперабельность с си максимально приятная.

Доказуемо корректные программы тоже не совсем про безопасность - вполне можно написать доказуемо корректный эксплойт.

Да, с тавтологией это я глупость сморозил. Там какое-то другое слово должно было быть.

Zig показался прикольным, с перспективами, как мне кажется. Есть ещё c2lang - похож на Си, но с методами и некоторыми дополнительными приятными фишками (типа моделей, публичные/приватные функции), недавно компилятор для c2lang даже переписали на сам c2lang, у него полная совместимость с Си и портировать либы можно очень быстро (вроде его даже можно компилировать в Си).

А про тавтологию, может "оксюморон" имели ввиду?

попробуйте zig или odin

Пока zig не выйдет в релиз, смотреть на него особо не хочется. В последний раз я столкнулся с тем, что мне приходилось вместо документации читать исходники, потому что в документации нужной мне информации не было. А вот на odin надо будет посмотреть

Спасибо за статью, привет с МГТУ СМ, а будет ли в будущем статья на тему форматирования вывода scanf и printf , а также указатели?

Здравствуйте.
В будущем планировалась статья, посвященная расширению подхода к выявлению ошибок в том числе при работе с памятью, а именно: вывод компилятора -> (описано в данной статье) -> стат.анализ средствами clang -> динамический анализ средствами ASan, MSan \ Valgrind -> сбор покрытия.
Также планирую рассмотреть типовые ошибки при работе с массивами и памятью.
Возможно будет переход к фаззинг тестированию

Про форматированной ввод/вывод планов не было, этому посвящен отдельный абзац статьи. А что именно Вам интересно?

P.s. Статья писалась для студентов МИФИ, рад, что студентов МГТУ она тоже заинтересовала)

scanf вообще лучше не использовать. А какие могут быит проблемы с printf, если сейчас компиляторы выводят предупреждения о несоответствии заявленного формата вывода и переданных аргументов?

Чем Вас не устраивает scanf для ввода целых чисел? Тем более в лабораторных работах первого курса?

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

Мне понравилась шутка, про безопасное программирование на си:)

Зарегистрируйтесь на Хабре, чтобы оставить комментарий

Публикации

Истории