LINUX.ORG.RU

Литература, пример проекта обработки ошибок на С

 


0

3

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

Ответ на: комментарий от slovazap

Прикольно. Статистика по количеству коммитов за период на хостинге, который рапортует, что у него только 2% проектов имеют умеренную или высокую активность, а 80% вообще неактивны совсем. Вот тут диаграммка внизу страницы, если что.

На Гитхабе C в топ-10 находится.

Так что пока ваши заявления об устаревании C безосновательны.

uuwaan ★★
()
Ответ на: комментарий от reprimand

Ты себе не представляешь сколько кода на C находится НЕ в открытом доступе.

О, код который никто никогда не видел. Действительно, как же я его не учёл.

На Гитхабе C в топ-10 находится.

А C++ в топ-5.

Господи, ясли защищают сишечку, никогда не думал что до такого доживу.

slovazap ★★★★★
()
Ответ на: комментарий от slovazap

О, код который никто никогда не видел. Действительно, как же я его не учёл.

Который обслуживает куеву тучу лямов дейвайсов, ага.

На Гитхабе C в топ-10 находится.

Ты на почве собственных расстройств цитируешь чужие слова, которые ко мне никак не относятся?

Господи, ясли защищают сишечку, никогда не думал что до такого доживу.

У самого-то писька выросла?

reprimand ★★★★★
()
Ответ на: комментарий от RazrFalcon

Ну ты писал:

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

Шаблоны и прочие плюшки я в плюсах видел, а «строгую типизацию», что бы это ни означало, — нет. Вот мне и интересно, что ты имел в виду.

Softwayer ★★
()
Ответ на: комментарий от Softwayer

Возможно я не точно выразился, но я подразумевал отсутствие необходимости с-кастов в C++. Соответственно я на этапе компиляции знаю, что с типами всё ок и я не кастую левую память к своей структуре.

RazrFalcon ★★★★★
()
Ответ на: комментарий от slovazap

Господи, ясли защищают сишечку, никогда не думал что до такого доживу.

Да ладно. В то, что вокруг C есть своя устойчивая тусовка нет ничего удивительного. Во-первых, пока для C не было альтернативы, которая давала бы такую же скорость, такой же доступ к ресурсам, но была бы безопаснее и не имела сложности C++. Станет ли такой альтернативой тот же Rust — надо еще посмотреть.

Во-вторых, сейчас огромное количество народу просто не знает, что такое C++, чем C++ отличается от C, как писать на C++, чтобы и ноги не отстреливать, и код получался не сильно медленнее C-шного. У многих за плечами Java, JavaScript, Python. Ну может Erlang, какой-нибудь. Надобность в C/С++ возникает редко, а когда возникает, то проще в минимальной степени освоить C, чем С++. А когда некоторый опыт работы с C у них появляется, то при необходимости написать на нейтиве что-то побольше, чем NIF для Erlang-а, естественным образом выбирается C. Т.к. опыта работы с C++ нет, а репутация у C++ та еще.

Тут выше упоминали вычислительный код на C. Это как раз в тему. Вычисления очень разные бывают. Если при необходимости иметь дело со СЛАУ выгоды от C++ становятся очевидны довольно быстро (особенно в методах конечных и граничных элементов, где матрицы хитрые — диагональные, ленточные или даже полуленточные и все это естественным образом прячется в C++ классах), то вот в других областях (методы конечных разностей, к примеру) C++ практически ничего существенного к С не добавляет. А с учетом того, что вычислительной математикой зачастую занимаются математики, у которых чисто утилитарный взгляд на программирование и соответствующее качество кода, то они берут простой С и используют его как Fortran. Или вообще генерируют C код из какого-нибудь высокоуровневого представления.

В-третьих, есть еще и принципиальные противники C++. Хрен знает по каким причинам, но заточили у себя зуб на C++ и принципиально пропагандируют свою позицию. Тот же автор ZeroMQ. Он же отказался при разработке ZeroMQ от кучи C++ных возможностей. А потом разразился тирадой о том, насколько C++ хуже C. И он не один такой. В сети запросто можно найти кучу стенаний о том, что в C++ за шаблонами магия и никто не понимает, во что шаблоны разворачиваются. При этом большинство из таких стенальщиков пишут отнюдь не hard real-time на устройствах с 8K RAM.

Ну и еще аргументов в пользу C можно подкинуть.

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

eao197 ★★★★★
()
Ответ на: комментарий от Softwayer

Если в C++ коде не используются c-style-casts и reinterpret_cast, то где именно происходит потеря строгой типизации?

eao197 ★★★★★
()
Ответ на: комментарий от RazrFalcon

Ну вместо С-кастов 4 штуки своих — можно подумать, хорошее что. И в достаточно низкоуровневом коде ими приходится довольно активно пользоваться: указатель скастить к uintptr_t, narrowing conversions (явный каст приходится использовать, если при сборке проекта предупреждения компилятора трактуются как ошибки), да и сишные функции, рассчитанные на использование с flexible array members, тоже никто не отменял. Получается, отличие от С в этом плане разве что в наличии типизированного new, что едва ли что-то кардинально меняет.

Softwayer ★★
()
Ответ на: комментарий от Softwayer

Если у вас весь С++ код покрыт с-кастами, то у меня для вас плохие новости. Если вы пишите свой контейнер или какую-то низкоуровневую лабуду - да, ок, но в повседневно коде кастов нужно избегать. Любых.

Получается, отличие от С в этом плане разве что в наличии типизированного new

Шта? У нас типизация используется только при создании объекта? Ну тогда да, разницы нет.

RazrFalcon ★★★★★
()
Ответ на: комментарий от eao197

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

Softwayer ★★
()
Ответ на: комментарий от RazrFalcon

Если у вас весь С++ код покрыт с-кастами, то у меня для вас плохие новости.

Ну касты плюсовые, но да, они часто используются, потому что код достаточно низкоуровневый, да ещё и виндовый (забавно видеть, как PSIZE_T и size_t* оказываются разными типами), так что без них никак.

У нас типизация используется только при создании объекта?

А когда ещё нужно кастовать «левую память» к нужному типу, кроме как при использовании malloc?

Softwayer ★★
()
Ответ на: комментарий от Softwayer

ведь есть неявные касты, приводящие к множеству ошибок

Давайте на примерах.

можно складывать выражения совершенно разных типов, даже если это гарантированно приводит к потере точности

Если в языке есть возможность сложить int и float, то где здесь нарушение типизации? Тот же float и string у вас же сложить не получится.

или указатель (в который сконвертировался массив при передаче в функцию) с числом — в сильно типизированном языке такой код должен быть некорректным.

Во-первых, смотря какой массив. std::vector или std::array ни в какие указатели просто так не конвертируются.

Во-вторых, это же арифметика указателей. У вас есть указатель на T. Вы добавляете к нему число (т.е. сдвигаете указатель) и у вас вновь оказывается указатель на T. Вроде никакого нарушения типизации нет.

eao197 ★★★★★
()
Ответ на: комментарий от eao197

У меня ровно противоположное восприятие. Я знаю С++ (более-менее) и не знаю С. Вот вообще. Если мне скажут писать на ansi, то я вообще хз что делать. Поэтому меня всё время удивляют рассказы, как из соседней темы про деструкторы, что ручное освобождение памяти, ручное задание размеров массивов, ручная итерация - это быстрее, проще и надёжнее.

В плюсах я пишу for (x : y) и проблем не знаю. А люди городят 100500 строк на простой цикл, ибо можно забыть очистить памяти, да и контейнер у нас - связный список, с сырыми указателями, мало ли что. И потому жалуются, что в С++ всё сложно.

8-ми битные контроллеры - ок. Но десктоп/мобилки. Смысла не вижу. Даже если, каким-то чудом, С++ версия будет на 20-30% медленнее, но надёжнее, - то это здравая жертва.

RazrFalcon ★★★★★
()
Ответ на: комментарий от Softwayer

можно складывать выражения совершенно разных типов

Примитивные типы - это легаси от С. Тут не поспоришь. Но никто не мешает скелпать свои обёртки со static_assert и constexpr, получив тонну ништяков, в отличии от С.

гарантированно приводит к потере точности

Шта? У вас претензии к ieee 754, а не к С++. Или вы про:

int i = 5 + 0.5;
Ну так эти конвертации описаны в стандарте и не являются случайными.

RazrFalcon ★★★★★
()
Ответ на: комментарий от Softwayer

А когда ещё нужно кастовать «левую память» к нужному типу, кроме как при использовании malloc?

Идея в том, что если у меня std::vector<MyClass>, то с вероятностью 99.9% там всегда будет MyClass. Что удобно, в отличии от int *p1 = (int*)malloc(sizeof(int)*size);

RazrFalcon ★★★★★
()
Ответ на: комментарий от RazrFalcon

std::vector<MyClass>, то с вероятностью 99.9% там всегда будет MyClass

Чта? Кто помешает что-нибудь другое в этом буфере развернуть? Касты есть, placement new есть, в чем фундаментальная разница и отличие от

struct my_struct *p1 = (struct my_struct*)malloc(sizeof(struct my_struct)*size);
? С вероятностью 99.9 там будет my_struct. Каст тебя смущает, оберни все в my_struct_new. Тем более есть g_new и тому подобное.

  std::vector<int>* vec = new std::vector<int> (10);

  float* a = new (vec) float;

  *a = 11.1;

И никаких сишных кастов. Кресты так же позволяют стрелять себе в голову сколько угодно, если есть желание и упоротость. Строгая типизация, бгг.

Freyr69 ★★★
()
Последнее исправление: Freyr69 (всего исправлений: 2)
Ответ на: комментарий от Freyr69

std::vector<int>* vec = new std::vector<int> (10);

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

И в этом, конечно же, проблема C++. И поэтому писать нужно на чистом C. Там всем этим можно заниматься не имея желания и упоротости.

Объясните, плз, зачем вы std::vector<int> через new создавали?

eao197 ★★★★★
()
Ответ на: комментарий от eao197

И в этом, конечно же, проблема C++.

И поэтому писать нужно на чистом C.

Объясните, плз, зачем вы std::vector<int> через new создавали?

Ну если ты уже столько за меня додумал, то я разрешаю тебе додумать ответ и на этот вопрос самому. Почитал бы хоть, о чем дискуссия, дабы не позориться.

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

Как не посмотрю, а ныне в тредах по си боль крестовиков в первых же постах.

Freyr69 ★★★
()
Последнее исправление: Freyr69 (всего исправлений: 2)
Ответ на: комментарий от Freyr69

Кресты так же позволяют стрелять себе в голову сколько угодно, если есть желание и упоротость

А в Си это может случиться без всякого желания.

tailgunner ★★★★★
()
Ответ на: комментарий от tailgunner

А в Си это может случиться без всякого желания.

Это и в крестах может случиться без всякого желания. Да что там, это и в хаскиле может случится или кложуре, благодаря ленивости или просто какому-нибудь ffi багу.

Freyr69 ★★★
()
Ответ на: комментарий от Freyr69

Freyr69> Кресты так же позволяют стрелять себе в голову сколько угодно, если есть желание и упоротость

Freyr69> Это и в крестах может случиться без всякого желания

Определись уже, при желании или без желания.

это и в хаскиле может случится или кложуре, благодаря ленивости или просто какому-нибудь ffi багу.

Ты так много знаешь.

tailgunner ★★★★★
()
Ответ на: комментарий от tailgunner

Определись уже, при желании или без желания.

Одно другое не исключает. У простых и предсказуемых языков не бывает стандартов на 2500 страниц.

Freyr69 ★★★
()
Последнее исправление: Freyr69 (всего исправлений: 1)
Ответ на: комментарий от Freyr69

Эк вас, батенька, от простого вопроса разорвало.

Тем не менее, зачем вам потребовалось vector через new создавать? Java головного мозга?

Ну и сами почитайте о чем речь идет: в C++ строгая типизация пропадает там, где начинаются касты. Что вы и продемонстрировали. С++ в этом не виноват. В plain old C с этим точно ничуть не лучше.

eao197 ★★★★★
()
Ответ на: комментарий от eao197

в C++ строгая типизация пропадает там, где начинаются касты.

Верно, а также а арифметике. Я и не говорил, что в си лучше, вопрос был о строгой типизации в крестах.

  std::string a = "Hello";

  int x = a[1];

  std::cout << x << std::endl;
101

Строгая типизация, такая строгая.

Freyr69 ★★★
()
Последнее исправление: Freyr69 (всего исправлений: 1)
Ответ на: комментарий от Freyr69

А вообще забавно, как в тред о языке си сразу же подрывается толпа оголтелых хамоватых фанатиков

Отлично. Этой части достаточно.

RazrFalcon ★★★★★
()
Ответ на: комментарий от Freyr69

Кресты так же позволяют стрелять себе в голову сколько угодно
если есть желание и упоротость.

В этом и есть преимущество С++. Небезопасный С код очень сложно повторить в плюсах.

Ясно дело, если сильно захотеть, то можно получить прямой доступ к памяти, как в С, но зачем?

RazrFalcon ★★★★★
()
Ответ на: комментарий от eao197

Какие проблемы с типизацией вы здесь видите?

Ну я не знаю, мне кажется, что float, например, и ``литера" — разные типы данных. Но может я как-то неправильно понимаю термин ``строгая типизация". float x = «Hello»[2] не должно быть валидным кодом в языке со строгой типизацией.

что в C

Так си — язык со слабой типизацией, да и в целом с очень слабой системой типов. Но си это позволительно, там просто высокоуровневый ассемблер.

Freyr69 ★★★
()
Ответ на: комментарий от Freyr69

Ну я не знаю, мне кажется, что float, например, и ``литера" — разные типы данных.

Мне кажется, что вы недостаточно знаете C и C++. Там нет типа «символ». Есть числовые типы char, short, wchar_t, int (а так же int8_t, int16_t, int32_t), каждый из которых может использоваться для представления символов в том или ином виде (а у типа wchar_t еще размерность меняется в зависимости от платформы). Зная это нет ничего удивительного в том, что значение одного числового типа (char) можно присвоить переменной другого числового типа (int или float).

Но может я как-то неправильно понимаю термин ``строгая типизация".

Строгая типизация подразумевает, что вы не можете просто так выдать объект типа T за объект типа Y. Т.е. если у вас есть:

struct A { void f(); ... };
struct B { void f(); ... };
То вы не можете сделать вот так:
void call_f(const A & a) { a.f(); }
B b;
call_f(b);

Другое дело, что строгость в C++ присутствует только в compile-time, но не в runtime. Поэтому, если в результате какой-то ошибки в runtime у вас в call_f все-таки попала ссылка на объект типа B, то в результате вызова может произойти все, что угодно.

eao197 ★★★★★
()
Ответ на: комментарий от eao197

Строгая типизация подразумевает, что вы не можете просто так выдать объект типа T за объект типа Y

Ну вот я выдал объект типа char за объект типа float.

float x = "Hello"
. Это пример строгой типизации?

Есть числовые типы char, short, wchar_t, int

Вот именно, что типы, разные, между которыми есть неявные приведения.

struct A { void f(); ... };

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

Freyr69 ★★★
()
Последнее исправление: Freyr69 (всего исправлений: 1)
Ответ на: комментарий от Freyr69

Ну вот я выдал объект типа char за объект типа float.
float x = «Hello»

Выфсеврети: https://godbolt.org/g/AIkKyD

Вот именно, что типы, разные, между которыми есть неявные приведения.

Вообще-то эти приведения описаны в стандарте языка.

Но в каком-нибудь окамле

ЕМНИП, в OCaml-е для сложения/умножения целых используется несколько другая нотация, чем для сложения/умножения вещественных. Т.е. a+b — это для int-ов, а a+.b — для float-ов. Если считать этот маразм образцом строгой типизации, тогда да, в C++ (как и в куче других языков, более безопасных, чем C++) до такой строгости еще не дошли.

eao197 ★★★★★
()
Ответ на: комментарий от Freyr69

Ну оно и в сишке так

В сишке не совсем так. Там нет ссылок, а указатели легко преобразуются в void и обратно: https://godbolt.org/g/0YNYq3

eao197 ★★★★★
()
Ответ на: комментарий от Freyr69

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

Ну и чтобы закрыть тему отсутствующего в C++ типа «символ». Главное отличие C++ от C состоит в том, что в C++ вы можете ввести свой тип ascii_character:

class ascii_character {
  char ch_{};
public :
  ascii_character() = default;
  explicit ascii_character(char ch) : ch_{ch} {}
  ...
}
После чего использовать его в качестве параметра для std::basic_string, т.е. получить что-то вроде:
using ascii_string = std::basic_string<ascii_character>;
И у вас для ваших символов будут разрешены только те операции, которые вы сами определите. Не хотите иметь неявных преобразований из ascii_character в float, их у вас и не будет.

А эффективность работы с таким ascii_character не будет отличаться от эффективности работы с char (за исключением редких случаев).

В plain old C вы этого в принципе не достигнете.

eao197 ★★★★★
()
Ответ на: комментарий от eao197

Выфсеврети: https://godbolt.org/g/AIkKyD

float x = «Hello»[1]

Вообще-то эти приведения описаны в стандарте языка.

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

OCaml-е для сложения/умножения целых используется несколько другая нотация

Это разные функции. В окамле нет ad-hoc полиморфизма искаропки, только параметрический. Но это не имеет отношения к слабой типизации, в хаскиле ad-hoc полиморфизм есть, но + работает только для одинаковых типов (a'->a'->a'), нельзя вызвать функцию сложения для int и float (если такая не объявлена), так как типы неявно не приводятся. Это и есть строгая типизация.

Главное отличие C++ от C состоит в том, что в C++ вы можете ввести свой тип ascii_character:

Могу, да. Кто-то и пол сишки обернул в gobject, gstring, gvalue, там только выглядит это чуть более громоздко из-за отсутствия перегрузки операторов и некоторых других мелочей.

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

Freyr69 ★★★
()
Ответ на: комментарий от Freyr69

нельзя вызвать функцию сложения для int и float (если такая не объявлена), так как типы неявно не приводятся. Это и есть строгая типизация.

Вопросов больше не имею.

eao197 ★★★★★
()
Ответ на: комментарий от eao197

Если в языке есть возможность сложить int и float, то где здесь нарушение типизации?

Если в языке есть возможность сложить int и float, то это язык со слабой типизацией.

Во-первых, смотря какой массив. std::vector или std::array ни в какие указатели просто так не конвертируются.

Да, вектор не конвертируется, но вектор — это вектор, а речь шла о массиве. std::array, к сожалению, вовсе не drop-in замена сырых массивов, т.к. требует явного указания длины во время компиляции (и даже не умеет её выводить при конструировании из initializer_list).

Вы добавляете к нему число (т.е. сдвигаете указатель) и у вас вновь оказывается указатель на T. Вроде никакого нарушения типизации нет.

Да, нарушений с точки зрения семантики С++ здесь нет, т.к. это язык со слабой системой типов.

Softwayer ★★
()
Ответ на: комментарий от Softwayer

Если в языке есть возможность сложить int и float, то это язык со слабой типизацией.

У меня для вас плохие новости. С такими критериями в языки со слабой типизацией попадает чуть меньше, чем все. Включая Java, C#, Python, Ruby, Erlang и т.д.

eao197 ★★★★★
()
Ответ на: комментарий от Softwayer

std::array, к сожалению, вовсе не drop-in замена сырых массивов, т.к. требует явного указания длины во время компиляции (и даже не умеет её выводить при конструировании из initializer_list).

auto a = make_array( 1, 2, 3, 4, 5 );
anonymous
()
Ответ на: комментарий от eao197

верно, но это новости для вас, похоже, а не для условных «нас». условные «мы» в курсе, да.

AndreyKl ★★★★★
()
Ответ на: комментарий от eao197

Java, C#

Ну за неимением общепринятого формального определения, что считать слабой системой типов, а что сильной, трудно их куда-то однозначно отнести. Я бы отнёс к слабой, хотя в них она ощутимо сильнее, чем в тех же крестах.

Python, Ruby, Erlang

Ну а у этих господ вообще какой-то цирк вместо системы типов

Softwayer ★★
()
Ответ на: комментарий от Softwayer

Ну а у этих господ вообще какой-то цирк вместо системы типов

Нет, просто мы с вами, скорее всего, не договорились об определениях.

Для меня строгая/сильная типизация — это невозможность выдать объект одного типа за объект другого типа. Вот пример слабой типизации: https://godbolt.org/g/0YNYq3 — здесь программист легко выдает указатель на A за указатель на B и никто ему по рукам не бьет.

Для вас — это отсутствие неявных преобразований типов.

eao197 ★★★★★
()
Последнее исправление: eao197 (всего исправлений: 1)
Ответ на: комментарий от anonymous

Это здорово, но присутствует только в library fundamentals TS, а не в каком-либо из существующих стандартов (и в С++17, видимо, тоже не будет).

Softwayer ★★
()
Ответ на: комментарий от eao197

Но разве возможность, например, вызвать функцию, принимающую int, от значения типа long — это не возможность выдать объект одного типа за объект другого типа?

Softwayer ★★
()
Ответ на: комментарий от Softwayer

Формально — нет. Функция ждет int, и получает int. Вызывающая сторона передает int путем преобразования значения типа long. Это преобразование выполняется согласно специально оговоренных правил.

Другое дело было бы, если бы вызывающая сторона заталкивала в стек/регистр long при вызове, а функция извлекала бы из стека/регистра int.

Ну и надо бы различать 1 + 0.2f и int i = 0.2f. В первом случае вообще никаких проблем нет. Во втором случае есть неявно приведение значения из float к int, что может привести к неприятностям. Но проблема же не в сложении int-а с float-ом.

eao197 ★★★★★
()
Ответ на: комментарий от eao197

Позвольте процитировать вики:

Например, яркими примерами слабой системы типов являются те, что лежат в основе языков Си и C++. Их характерными атрибутами являются понятия приведения типов и каламбуров типизации. Эти операции поддерживаются на уровне компилятора и часто вызываются неявно.

anonymous
()
Ответ на: комментарий от anonymous

Ну что ж, если доминирующая точка зрения состоит в том, что складывание int-ов с float-ами — это нарушение строгой типизации, то пусть так и будет. Значит в C++ нет строгой типизации.

eao197 ★★★★★
()
Ответ на: комментарий от reprimand

У самого-то писька выросла?

Наконец-то, кто-то начал задавать правильные вопросы.

rupert ★★★★★
()
Ответ на: комментарий от XMs

выставляй errno, когда надо

Ты о чём? errno — это что? Имей ввиду я чистосишник.

Автор, у тебя Си или Си++? Это два разных языка, если что.

anonymous
()
Ответ на: комментарий от anonymous

Ты о чём? errno — это что?

man errno.


я чистосишник

Это и есть pure C

XMs ★★★★★
()
Ответ на: комментарий от mersinvald

bound-checking в некоторых (ржавых) языках отключается в релиз-билде

Нет, не отключается.

соотвественно все грабли при отладке поймаются

Нет, не все.

Esper
()
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.