LINUX.ORG.RU

История изменений

Исправление byko3y, (текущая версия) :

// вот тут мы проверяем инвариант - результат сложения не вызовет переполнение result

Это не инвариант, а вполне себе постусловие. Инвариантом в данном случае может являться кратность числу a или b, которая нарушается при переполнении.

Теперь напоминаю, о чем была речь:

Как ты можешь гарантировать, что никто нигде в тысячах блоков вызовов sdsnew/sdsfree не изменит указатель на строку?

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

Я не понимаю, при чем тут проверка при инициализации к безопасности операций языка. Язык Си дает изначально крайне опасные методы работы с данными, которых не было у кобола, не было у фортрана, хотя это более ранние языки, чем Си. C++ и паскаль могут дать 100% гарантию того, что при работе со строками стандартными методами ты никогда не получишь ошибку работы с памятью

А ты мне суешь какие-то переполнения чисел и деления на ноль. Контракт «управляющая ссылка на динамическую облатсь памяти не может изменяться» вполне себе реализуем в компиляторе без каких-либо сверхъестественных приемов и без проверок во время выполнения программы.

Переход на сишные указатели = выход за стандартные методы

твое s++ - это такой же выход за рамки стандартных, заданных способов работы с либой, и? тебя же это не смущало. а тут ты внезапно стал рассказывать о том что, дескать, пользоваться надо как надо, а не как попало

Да, теоретически бибилотека могла бы реализовать некий абсолютно непрозрачный тип, которым нельзя было бы пользоваться как строкой, а только через соответствующие функции библиотеки, которые принимают этот конкретный тип строк. Проблема в том, что в Си нет средств для того, чтобы гарантировать, что никакая функция не нарушает этого правила. Допустим, ты сделаешь «typedef sds intptr_t», однако, какой-то неаккуратный програмист сделает «s1+s2» — и привет. Хуже всего то, что это не просто чтение, а и высвобождение памяти.

Даже если допустить, что мы как-то выдрессировали программистов, и все они на 100% избегают арифметики — как избежать ошибки работы с памятью при присвоении указателей на строки? Double-free — это самая популярная ошибка при работе с указателями. (update: конечно же, «use after free» — это самая популярная. Но и «double free» тоже достаточно востребована).

В итоге при работе с крестовыми или паскалевыми строками для безопасного выполнения мне ничего не нужно делать, а просто брать любые стандартные методы и код 100% будет работать безопасно, поскольку компилятор укажет на ошибку — а для Си нужно прекладывать неординарные уссилия для ручной проверки корректности операций, которая даст сбой, пусть даже один из тысячи раз — и что, мне от этого легче будет? Почему я и пишу, что с такими же успехами ты мог бы писать, что с sds-строками безопасно работать в ассемблере — главное, пользуйся только функциями библиотеки, и все будет в порядке. А то, что в базовом языке наблюдается полный угар и малейшее неаккуратное движение дает труднообнаруживаемую ошибку — это тебя почему-то не волнует. И нет, этой проблемы нет в крестах, где нужно прикладывать неординарные усилия просто для того, чтобы ошибку написать.

Исходная версия byko3y, :

// вот тут мы проверяем инвариант - результат сложения не вызовет переполнение result

Это не инвариант, а вполне себе постусловие. Инвариантом в данном случае может являться кратность числу a или b, которая нарушается при переполнении.

Теперь напоминаю, о чем была речь:

Как ты можешь гарантировать, что никто нигде в тысячах блоков вызовов sdsnew/sdsfree не изменит указатель на строку?

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

Я не понимаю, при чем тут проверка при инициализации к безопасности операций языка. Язык Си дает изначально крайне опасные методы работы с данными, которых не было у кобола, не было у фортрана, хотя это более ранние языки, чем Си. C++ и паскаль могут дать 100% гарантию того, что при работе со строками стандартными методами ты никогда не получишь ошибку работы с памятью

А ты мне суешь какие-то переполнения чисел и деления на ноль. Контракт «управляющая ссылка на динамическую облатсь памяти не может изменяться» вполне себе реализуем в компиляторе без каких-либо сверхъестественных приемов и без проверок во время выполнения программы.

Переход на сишные указатели = выход за стандартные методы

твое s++ - это такой же выход за рамки стандартных, заданных способов работы с либой, и? тебя же это не смущало. а тут ты внезапно стал рассказывать о том что, дескать, пользоваться надо как надо, а не как попало

Да, теоретически бибилотека могла бы реализовать некий абсолютно непрозрачный тип, которым нельзя было бы пользоваться как строкой, а только через соответствующие функции библиотеки, которые принимают этот конкретный тип строк. Проблема в том, что в Си нет средств для того, чтобы гарантировать, что никакая функция не нарушает этого правила. Допустим, ты сделаешь «typedef sds intptr_t», однако, какой-то неаккуратный програмист сделает «s1+s2» — и привет. Хуже всего то, что это не просто чтение, а и высвобождение памяти.

Даже если допустить, что мы как-то выдрессировали программистов, и все они на 100% избегают арифметики — как избежать ошибки работы с памятью при присвоении указателей на строки? Double-free — это самая популярная ошибка при работе с указателями.

В итоге при работе с крестовыми или паскалевыми строками для безопасного выполнения мне ничего не нужно делать, а просто брать любые стандартные методы и код 100% будет работать безопасно, поскольку компилятор укажет на ошибку — а для Си нужно прекладывать неординарные уссилия для ручной проверки корректности операций, которая даст сбой, пусть даже один из тысячи раз — и что, мне от этого легче будет? Почему я и пишу, что с такими же успехами ты мог бы писать, что с sds-строками безопасно работать в ассемблере — главное, пользуйся только функциями библиотеки, и все будет в порядке. А то, что в базовом языке наблюдается полный угар и малейшее неаккуратное движение дает труднообнаруживаемую ошибку — это тебя почему-то не волнует. И нет, этой проблемы нет в крестах, где нужно прикладывать неординарные усилия просто для того, чтобы ошибку написать.