Здравствуйте, d Bratik, Вы писали:
DB>Подозреваю, что Вы никогда не создавали на C++ развитого GUI. Все программисты на С++ как чумы избегают решения этой задачи. Они говорят, что это им скушно и неинтересно. Однако именно создание пользовательского интерфейса является наиболее важной, сложной и действительно интересной проблемой при создании системы. Именно пользовательский интерфейс определяет используемые алгоритмы и структуры даннных, а не наоборот. И именно для решение этой самой насущной задачи меньше всего подходит С++.
Всё-таки бывают программы, в которых UI (не важно насколько он G) не самое сложное. Компилятор Дельфи например, я надеюсь таков. И скорее всего алгоритмы и структуры данных там не UI определяются.
И вообще любой Engine, который делает что-то нужное, а особенно наукоёмкое, частенько сложнее любого самого навороченного GUI.
Например, система реендринга Word'а скорее всего сложнее всего GUI вместе взятого. Или, например, Photoshop, я так подозреваю, что не в GUI там дело и пользуются им не из-за GUI и программируют там в основном не его
Вообще, КМК, в программировании ценно делать всё как можно проще, а не как можно сложнее. И есть вполне простые, легко масштабируемые подходы к написанию GUI.
Документы, вью, контролы, система нотификаций и т. п. Ну не мне же тебя учить
Если охота лезть в чудеса, то можно всё запутать бесконечно, но не понятно зачем бы это
Всё-таки обычно программе нужен engine, который делает что-то нужное пользователю.
Ну а если ты имеешь уже реализованные моторы, и строишь на их базе продукт, в котором самое сложное и дорогое в разработек -- это GUI, то наверное C++ для тебя действительно может оказаться "пушкой, для стрельбы по воробьям"
М$ предлагали для этих целей всю жизнь VB, возможно с ним Дельфи успешно конкурируют, возможно нет. Но почему именно разработчкики таких програм и только они считаются "настоящими программистами" я лично не понимаю.
C++ -- уникальная штука. Это такой странный гибрид "ужа с ежом", что язык может быть чем-то очень высокоуровневым, но может оказаться чем-то вроде ассемблера. Он почти не прячет от программиста компьютер, на котором работает его программа. Но умудряется делать это псевдопереносимым способом. Мне кажется, что это чудо. Но за чудо приходится платить -- в любом месте программы мы можем оказаться программистами на языке низкого уровня. Так как мы от компа не защищены никак. Но в действительно сложных ситуациях так всё складывается, что приходится прибегать к этому чуду. Ну а в стандартных, зато, приходится платить удорожением разработки.
Только и всего.
Все эмоциональные формулировки не соотвествуют действительному положению вещей и приведены мной исключительно "ради красного словца". За корректными формулировками и неискажённым изложением идей, следует обращаться к их автором или воспользоваться поиском
Здравствуйте, xBlackCat, Вы писали:
BC>Уже такие перцы есть! Смотреть здесь
Это халява. Я как-то видел на много более полезное практически извращение на эту тему.
Это был com файл, который умел разUUEть письма. При этом он был записан только печатными символами и концами строк. И строки все были короткими. Так что его можно было прислать по мылу прямо вместе с инструкциями, ну и потом слать уже нормальные вложения. Ну а уж потом...
Все эмоциональные формулировки не соотвествуют действительному положению вещей и приведены мной исключительно "ради красного словца". За корректными формулировками и неискажённым изложением идей, следует обращаться к их автором или воспользоваться поиском
Re[12]: Почему настоящие программисты избегают C++
Здравствуйте, AVC, Вы писали:
AVC>Рассмотрим простой пример: AVC>
AVC>PROCEDURE InitArray(VAR a: ARRAY OF INTEGER);
AVC> VAR i: LONGINT;
AVC>BEGIN
AVC> FOR i := 0 TO LEN(a)-1 DO
AVC> a[i] := 0
AVC> END
AVC>END InitArray;
AVC>
AVC>Много ли нужно run-time проверок, чтобы удостовериться, что индекс не выходит за границы массива? AVC>Очевидно, ни одной. Потери эффективности нет вовсе!
Только если i — это константа внутри цикла. Что _обязан_ везде_проверять_ компилятор.
Кстати, если в этом есть необходимость — ничего не мешает в этом случае слово const писать на С для адреса и длины массива. Будет то же самое. То, что у кого-то руки кривые (не делает так) — ни о чем не говорит.
Таким образом, на С есть средства, которые позволяют создавать код, АБСОЛЮТНО АНАЛОГИЧНЫЙ вышеприведенному.
Еще есть понятие "защищенного массива". В котором с помощью #ifdef выделить run-time проверку. И включать или выключать ее при компиляции. Где угодно и сколько угодно. Посмотри CArray в MFC например. Он так и работает.
Кстати, как тогда в обероне насчет "ходовой" сортировки? При таких ограниченных циклах только пузырьковую возможно применить. Или ОС предоставит встроенные алгоритмы на все случаи жизни?
AVC>Проверка на выход за границы массива в данном случае полностью происходит на этапе компиляции. AVC>А вот для Си/Си++ это невозможно: там передается не массив, а указатель. Что не одно и то же.
М>>А вот как проверять те замысловатые хитросплетения, которые там на самом деле есть — это под большим вопросом. AVC>А в чем, собственно, заключается этот "большой" вопрос?
Например, как Оберон хранит в памяти директории, файлы, кластеры которые есть на диске.
Тоже в массивах? И они на этапе компиляции создаются?
А буфер для устройства вроде сканера или сетевой карты как сделать.
Устройство в одном из параметров возвращает число байт, которое им обработано или передано в ответ на запрос.
Запросы-ответы идут непрерывно в обе стороны.
Вот когда надо массив с результатом создавать? И как, когда узнать его окончательный размер?
С помощью ОС динамически массив наращивать?
Как вообще предлагается работать с _большими_ массивами переменной длины? Которые могут быть и намного больше размера оперативки. Как такой массив обработать редактором, например.
...А отсюда наливаем, когда рецепт написан совсем неразборчиво...
Re[13]: Почему настоящие программисты избегают C++
Здравствуйте, Михаил, Вы писали:
М>Здравствуйте, AVC, Вы писали:
AVC>>Рассмотрим простой пример: AVC>>
AVC>>PROCEDURE InitArray(VAR a: ARRAY OF INTEGER);
AVC>> VAR i: LONGINT;
AVC>>BEGIN
AVC>> FOR i := 0 TO LEN(a)-1 DO
AVC>> a[i] := 0
AVC>> END
AVC>>END InitArray;
AVC>>
AVC>>Много ли нужно run-time проверок, чтобы удостовериться, что индекс не выходит за границы массива? AVC>>Очевидно, ни одной. Потери эффективности нет вовсе!
М>Только если i — это константа внутри цикла. Что _обязан_ везде_проверять_ компилятор. М>Кстати, если в этом есть необходимость — ничего не мешает в этом случае слово const писать на С для адреса и длины массива. Будет то же самое. То, что у кого-то руки кривые (не делает так) — ни о чем не говорит. М>Таким образом, на С есть средства, которые позволяют создавать код, АБСОЛЮТНО АНАЛОГИЧНЫЙ вышеприведенному.
К сожалению, Си не имеет средств, позволяющих создавать код "аналогичный вышеприведенному".
Добавление const также не решает проблему.
Представим себе эту игрушечную процедуру на Си:
void InitArray(int * const a, const int n)
{
int i;
for (i = 0; i < n; ++i)
a[i] = 0;
}
Кажется, Вы полагаете, что этот код "АБСОЛЮТНО АНАЛОГИЧНЫЙ вышеприведенному".
Но это не так. Для компилятора между указателем a и целым числом nнет связи.
Это значит, что компилятор Си не может гарантировать защиту памяти.
Почему, например, следующий код должен считаться некорректным?
void InitArray(int * const a, const int n)
{
int i;
for (i = -1; i <= n; ++i)
a[i] = 0;
}
Вообще, кто сказал, что a — это массив?
Что мешает написать
void foo()
{
int *ip;
ip = (int *) malloc(sizeof (*ip));
InitArray(ip, 1024);
}
?
Как видите, Си не может бороться даже с явно бредовым кодом.
М>Например, как Оберон хранит в памяти директории, файлы, кластеры которые есть на диске. М>Тоже в массивах? И они на этапе компиляции создаются?
В Обероне массивы (в том числе многомерные) могут создаваться динамически.
Например, создадим матрицу заранее неизвестной размерности:
TYPE Matrix = POINTER TO ARRAY OF ARRAY OF REAL;
PROCEDURE NewMatrix(rows, cols: INTEGER): Matrix;
VAR new: Matrix;
BEGIN
NEW(mat, rows, cols);
RETURN mat
END NewMatrix;
М>Вот когда надо массив с результатом создавать? И как, когда узнать его окончательный размер?
Возьмем пример с той же матрицей.
VAR matrix: Matrix;
Тогда
LEN(matrix, 0) — число строк
LEN(matrix, 1) — число столбцов.
М>С помощью ОС динамически массив наращивать? М>Как вообще предлагается работать с _большими_ массивами переменной длины? Которые могут быть и намного больше размера оперативки. Как такой массив обработать редактором, например.
Так же как и в Си++: создайте класс.
Но существует одно качество, которое нельзя купить, — это надежность. Цена надежности — погоня за крайней простотой. Это цена, которую очень богатому труднее всего заплатить.
Хоар
Re[14]: Почему настоящие программисты избегают C++
Здравствуйте, AVC, Вы писали:
М>>Здравствуйте, AVC, Вы писали:
AVC>К сожалению, Си не имеет средств, позволяющих создавать код "аналогичный вышеприведенному". AVC>Добавление const также не решает проблему. AVC>Представим себе эту игрушечную процедуру на Си: AVC>
AVC>void InitArray(int * const a, const int n)
AVC>{
AVC> int i;
AVC> for (i = 0; i < n; ++i)
AVC> a[i] = 0;
AVC>}
AVC>
AVC>Кажется, Вы полагаете, что этот код "АБСОЛЮТНО АНАЛОГИЧНЫЙ вышеприведенному". AVC>Но это не так. Для компилятора между указателем a и целым числом nнет связи. AVC>Это значит, что компилятор Си не может гарантировать защиту памяти.
inline void body(int* const a, const int i)
{
a[i]=0;
}
void InitArray(int * const a, const int n)
{
int i;
for (i = 0; i < n; ++i)
body(a, i);
}
Хотя не знаю, кому в голову такое написать придет .
Однако, если в body лежит кусок кода в 100К размером (куча вложенных функций) — это будет уже совсем не лишнее. Хотя inline желательно будет убрать.
Второе решение — использовать защищенный класс, в котором есть оператор [] и в нем проверка.
void InitArray(CProtectedArrayOfInt a, const int n)
AVC>Почему, например, следующий код должен считаться некорректным?
(...) AVC>Как видите, Си не может бороться даже с явно бредовым кодом.
И правильно. И так должно быть. Вы бы еще _asm покритиковали — вообще кошмар с этой точки зрения.
Это же идеология С — позволить получить с помощью высокоуровневого языка практически любой мыслимый набор машинных команд. Сколько будет смысла в этом наборе команд — исключительно дело рук разработчика.
М>>Например, как Оберон хранит в памяти директории, файлы, кластеры которые есть на диске. М>>Тоже в массивах? И они на этапе компиляции создаются?
AVC>В Обероне массивы (в том числе многомерные) могут создаваться динамически. AVC>Например, создадим матрицу заранее неизвестной размерности: AVC>
AVC>TYPE Matrix = POINTER TO ARRAY OF ARRAY OF REAL;
AVC>PROCEDURE NewMatrix(rows, cols: INTEGER): Matrix;
AVC> VAR new: Matrix;
AVC>BEGIN
AVC> NEW(mat, rows, cols);
AVC> RETURN mat
AVC>END NewMatrix;
AVC>
М>>Вот когда надо массив с результатом создавать? И как, когда узнать его окончательный размер?
AVC>Возьмем пример с той же матрицей. AVC>VAR matrix: Matrix; AVC>Тогда AVC>LEN(matrix, 0) — число строк AVC>LEN(matrix, 1) — число столбцов.
М>>С помощью ОС динамически массив наращивать? М>>Как вообще предлагается работать с _большими_ массивами переменной длины? Которые могут быть и намного больше размера оперативки. Как такой массив обработать редактором, например.
AVC>Так же как и в Си++: создайте класс.
Ирония осталась непонятой .
Ну, вот такая проблемка есть у драйверов: им совсем некогда динамически память выделять. Байты от устройства потеряются. Или блокировка на ресурсы возникнет в многозадачной среде. Зачем ring0 придумали — поинтересуйтесь!
...А отсюда наливаем, когда рецепт написан совсем неразборчиво...
Re[15]: Почему настоящие программисты избегают C++
М>Хотя не знаю, кому в голову такое написать придет .
Я тебя уверяю — подавляющее большинство разработчиков по инструкции "выделить буфер размером 512 байт" пишут именно так:
Стоит ли удивляться, что потом меняется только одна из двух магических констант (или две из трех, или восемь из десяти)?
Конечно, можно отвыкнуть их от этого. Но практика показывает, что лучше отдать эту нудятину среде/компилятору, чем упражняться в педагогике. Со всех точек зрения.
Кроме ровно одной: "зато если человек написал работающую программу на плюсах — это Программист! А на всех этих Delphi, C#, Java и проч. люди годами пишут успешные приложения, вообще ничего о программировании не зная..."
... << RSDN@Home 1.1.4 beta 5 rev. 395>>
Уйдемте отсюда, Румата! У вас слишком богатые погреба.
N>Может, с годами и опытом проходит желание создать свой контрол, написанный с нуля или почти с нуля (наследуемся от CWnd) ? N>А что легче, быстрее, понятнее etc — написать, например, всплывающую панель, как в VS .NET (или любой другой нестандартный контрол) — написать на С++ или на Делфи? Я совсем недавно сделал свое дерево, у которого единственное сходство со стандартным в том, что это дерево. Я получал удовольствие от того, что понимаю до конца, что написано, и что могу манипулировать данными и вообще языком, как мне захочется.
С годами само не проходит, нужно упорно, насильно заставлять себя доверять чужому коду.. Иначе вся жизнь твоя будет в велосипедах и ничего нового ты написать не успеешь
Здравствуйте, johny5, Вы писали:
J> С годами само не проходит, нужно упорно, насильно заставлять себя доверять чужому коду.. Иначе вся жизнь твоя будет в велосипедах и ничего нового ты написать не успеешь J>
Казалось бы, от чего не доверять тогда стандартным контролам?
Все эмоциональные формулировки не соотвествуют действительному положению вещей и приведены мной исключительно "ради красного словца". За корректными формулировками и неискажённым изложением идей, следует обращаться к их автором или воспользоваться поиском
Re[16]: Почему настоящие программисты избегают C++
Здравствуйте, Sinclair, Вы писали:
S>Здравствуйте, Михаил, Вы писали:
М>>Хотя не знаю, кому в голову такое написать придет . S>Я тебя уверяю — подавляющее большинство разработчиков по инструкции "выделить буфер размером 512 байт" пишут именно так: S>
S>Стоит ли удивляться, что потом меняется только одна из двух магических констант (или две из трех, или восемь из десяти)? S>Конечно, можно отвыкнуть их от этого. Но практика показывает, что лучше отдать эту нудятину среде/компилятору, чем упражняться в педагогике. Со всех точек зрения. S>Кроме ровно одной: "зато если человек написал работающую программу на плюсах — это Программист! А на всех этих Delphi, C#, Java и проч. люди годами пишут успешные приложения, вообще ничего о программировании не зная..."
Т.е., ты хочешь сказать, что в Delphi, C# и Java hardcoded константы можно использовать без проблем?
... << RSDN@Home 1.1.4 beta 7 rev. 447>>
SObjectizer: <микро>Агентно-ориентированное программирование на C++.
Re[17]: Почему настоящие программисты избегают C++
Здравствуйте, eao197, Вы писали:
E>Т.е., ты хочешь сказать, что в Delphi, C# и Java hardcoded константы можно использовать без проблем?
В C# и Java вместо прохода по памяти в ты получишь нормальный index out of bounds. По крайней мере, другие потоки в твоем процессе будут дальше жить. В Delhi для типовых задач нажо писать меньше кода, что дает меньше возможностей напакостить.
Хотя, конечно, предела совершенству нету — забавнее всего смотреть на Delphi-код, написанный незнакомыми с VCL программистами. Все вручную, и все через ж...технологическое отверстие. Как выбрать в комбобоксе элемент №5? Нет, неправильно, никаких ItemIndex. Надо добавить в название каждого итема его номер, вот так: "<1> Item one", "<2> Item two". А потом в цикле перебирать итемы, парсить и проверять. С обязательными штуками типа
If ffxidx <> 0 then
cmb1.itemIndex:= ffxidx else
cmb1.itemindex :=0
(форматирование оригинала сохранено)
... << RSDN@Home 1.1.4 beta 5 rev. 395>>
Уйдемте отсюда, Румата! У вас слишком богатые погреба.
Re[18]: Почему настоящие программисты избегают C++
Здравствуйте, Sinclair, Вы писали:
S>Здравствуйте, eao197, Вы писали:
E>>Т.е., ты хочешь сказать, что в Delphi, C# и Java hardcoded константы можно использовать без проблем?
S>В C# и Java вместо прохода по памяти в ты получишь нормальный index out of bounds. По крайней мере, другие потоки в твоем процессе будут дальше жить.
Имхо, в C# и Java эта ошибка будет на несколько порядков быстрее локализована. А вот будет ли этот index out of bounds exception менее пагубным -- еще вопрос.
Так что проблема в использовании магических констант (что от языка не зависит), а уже следствия в разных языках могут быть разные. И не обязательно в C++ они будут самыми катострофическими, имхо.
... << RSDN@Home 1.1.4 beta 7 rev. 447>>
SObjectizer: <микро>Агентно-ориентированное программирование на C++.
Re[19]: Почему настоящие программисты избегают C++
Здравствуйте, eao197, Вы писали:
E>Имхо, в C# и Java эта ошибка будет на несколько порядков быстрее локализована.
Верно, благодаря Stack Trace E>А вот будет ли этот index out of bounds exception менее пагубным -- еще вопрос.
Никаких вопросов. Проход по памяти -> обрушение процесса. Для десктоп-приложения index out of bounds — не менее смертелен, потому как если он не обработан (а он нифига не обработан), то инварианты нарушены, и с вероятностью 70% любое следующее действие пользователя приведет к наведенной ошибке. Остается только маленький шанс, что "сохранить изменения" все еще будет доступно E>Так что проблема в использовании магических констант (что от языка не зависит), а уже следствия в разных языках могут быть разные. И не обязательно в C++ они будут самыми катострофическими, имхо.
А вот на сервере в неуправляемой среде проход по памяти проносится по всем потокам как метеор, оставляя неконтролируемые разрушения для всех пользователей. Управляемое приложение уронит одну пользовательскую сессию; более того — в steteless модели это затронет только один текущий request. Пользователь давит back в браузере и продолжает работать. Подобный сбой в неуправляемом коде может убить весь сервер.
... << RSDN@Home 1.1.4 beta 5 rev. 395>>
Уйдемте отсюда, Румата! У вас слишком богатые погреба.
Re[20]: Почему настоящие программисты избегают C++
Здравствуйте, Sinclair, Вы писали:
E>>А вот будет ли этот index out of bounds exception менее пагубным -- еще вопрос. S>Никаких вопросов. Проход по памяти -> обрушение процесса. Для десктоп-приложения index out of bounds — не менее смертелен, потому как если он не обработан (а он нифига не обработан), то инварианты нарушены, и с вероятностью 70% любое следующее действие пользователя приведет к наведенной ошибке. Остается только маленький шанс, что "сохранить изменения" все еще будет доступно
Не всегда. Если в C++ мы ошиблись с индексом всего на единичку, то с большой вероятностью мы ничего не убъем. А вот в C#/Java out of range 100% гарантирован
E>>Так что проблема в использовании магических констант (что от языка не зависит), а уже следствия в разных языках могут быть разные. И не обязательно в C++ они будут самыми катострофическими, имхо. S>А вот на сервере в неуправляемой среде проход по памяти проносится по всем потокам как метеор, оставляя неконтролируемые разрушения для всех пользователей.
Это если мы идем по хипу и в большом диапазоне. А ведь в C/C++ память может и на стеке выделяться. И тогда мы за рамки одного потока можем и не выйти.
S>Управляемое приложение уронит одну пользовательскую сессию; более того — в steteless модели это затронет только один текущий request. Пользователь давит back в браузере и продолжает работать. Подобный сбой в неуправляемом коде может убить весь сервер.
Если сервер написан на отдельных cgi, то не убъет.
Я это к тому, что ошибки выхода за пределы своей памяти в C++ опасны как раз не потому, что они вызывают мнгновенный сбой. А потому, что они этот сбой могут провоцировать в будущем, в какой-то почти случайный момент времени.
А исходный посыл в том, что если на C++ писать нормально (без hardcoding-а магичесих чисел в том числе), то и проблем особых не будет. Плюс к тому, программирование на C++ действительно дисциплинирует. И после C++ можно без проблем программировать на чем угодно, включая C# и Java. А вот обратное не верно, ибо C++ разгильдяйства и раздолбайства не прощает.
SObjectizer: <микро>Агентно-ориентированное программирование на C++.
DB>3.Отсутствие встроенной проверки на выход за диапазоны массива. Приводит к необходимости писать «обертки» для классов-контейнеров (в частности, для класса vector).
А vector::at ? Хочешь безопасно, но медленно — vector::at. Небезопасно но быстро — vector::operator[]. Хочешь — итераторы, хочешь — индексы. В этом и сила С++, брат.
... << RSDN@Home 1.1.4 beta 7 rev. 447>>
Re[15]: Почему настоящие программисты избегают C++
М>inline void body(int* const a, const int i)
М>{
М> a[i]=0;
М>}
М>void InitArray(int * const a, const int n)
М>{
М> int i;
М> for (i = 0; i < n; ++i)
М> body(a, i);
М>}
М>
М>Хотя не знаю, кому в голову такое написать придет . М>Однако, если в body лежит кусок кода в 100К размером (куча вложенных функций) — это будет уже совсем не лишнее. Хотя inline желательно будет убрать. М>Второе решение — использовать защищенный класс, в котором есть оператор [] и в нем проверка. М>void InitArray(CProtectedArrayOfInt a, const int n)
Честно говоря, я не понял какую именно проблему Вы решаете этими двумя способами.
Особенно первым.
Что касается второго, то в нем предлагается создать класс, содержащий run-time проверки индекса массива.
Это похвальная попытка скомпенсировать отсутствие в языке строгой типизации.
Предположу, что в определении класса CProtectedArrayOfInt можно найти примерно следующее:
private:
int *p;
size_t size;
Так вот, я просто хочу обратить Ваше внимание на то, что для компилятора p и size — по прежнему две отдельные переменные, не имеющие между собой ничего общего. Если при реализации класса CProtectedArrayOfInt Вы (не дай Бог! ) допустите ошибку, компилятор ничем не сможет Вам помочь.
AVC>>Как видите, Си не может бороться даже с явно бредовым кодом.
М>И правильно. И так должно быть. Вы бы еще _asm покритиковали — вообще кошмар с этой точки зрения. М>Это же идеология С — позволить получить с помощью высокоуровневого языка практически любой мыслимый набор машинных команд. Сколько будет смысла в этом наборе команд — исключительно дело рук разработчика.
Я не буду критиковать asm. Хотя бы потому, что последние годы я пишу компиляторы Си и ассемблеры для новых процессоров, и C вместе с asm меня кормят.
(Кстати, этот опыт последних лет свидетельствует, что программисты, пишущие на Си, проявляют повышенный интерес к отладчику, т.к. зачастую не в состоянии найти ошибку в своих программах без его помощи.)
Также согласен с Вами относительно идеологии Си. Кажется, главное из правил Spirit of C начинается так: "Не мешай программисту..."
Но вот в чем я с Вами не согласен, так это в понимании "высокоуровневости" языков программирования.
На мой взгляд, язык Си (равно как и Си++ в этом случае), не способный передать в подпрограмму даже информацию о размерности массива, не может считаться высокоуровневым.
Весь смысл высокоуровневости — позволить компилятору гарантировать определенные свойства программ, например — безопасность типов (type safety).
С моей стороны это вовсе не эстетская критика.
Я полагаю, что только прирожденный душегуб согласится писать сложное ПО, отвечающее за безопасность людей, на низкоуровневых языках, подобных Си и Си++.
М>>>С помощью ОС динамически массив наращивать? М>>>Как вообще предлагается работать с _большими_ массивами переменной длины? Которые могут быть и намного больше размера оперативки. Как такой массив обработать редактором, например. AVC>>Так же как и в Си++: создайте класс. М>Ирония осталась непонятой . М>Ну, вот такая проблемка есть у драйверов: им совсем некогда динамически память выделять. Байты от устройства потеряются. Или блокировка на ресурсы возникнет в многозадачной среде. Зачем ring0 придумали — поинтересуйтесь!
Мне приходилось писать ПО, работающее автономно в очень жестком real-time, причем в системе безопасности.
Память под буфера отводилась заранее, а затем управлялась маленьким специализированным "распределителем памяти".
Не вижу никакого преимущества у Си/Си++ по сравнению с Обероном в данном случае.
Но существует одно качество, которое нельзя купить, — это надежность. Цена надежности — погоня за крайней простотой. Это цена, которую очень богатому труднее всего заплатить.
Хоар
Re[16]: Почему настоящие программисты избегают C++
AVC wrote:
> Честно говоря, я не понял *какую именно* проблему Вы решаете этими > двумя способами. > Особенно первым. > Что касается второго, то в нем предлагается создать класс, содержащий > run-time проверки индекса массива. > Это похвальная попытка скомпенсировать отсутствие в языке строгой > типизации.
Ррррр.... Никакая статическая типизация не поможет в проверке контроля
выхода за границы массива, если есть динамическое распределение памяти.
> Так вот, я просто хочу обратить Ваше внимание на то, что *для > компилятора* p и size — по прежнему две отдельные переменные, не > имеющие между собой ничего общего. Если при реализации класса > CProtectedArrayOfInt Вы (не дай Бог! ) допустите ошибку, компилятор > ничем не сможет Вам помочь.
А чем мне в этом случае поможет Оберон? В нем будет абсолютно такая же
ситуация.
--
С уважением,
Alex Besogonov (alexy@izh.com)
Posted via RSDN NNTP Server 1.9
Sapienti sat!
Re[17]: Почему настоящие программисты избегают C++
Здравствуйте, Cyberax, Вы писали:
C>AVC wrote:
>> Честно говоря, я не понял *какую именно* проблему Вы решаете этими >> двумя способами. >> Особенно первым. >> Что касается второго, то в нем предлагается создать класс, содержащий >> run-time проверки индекса массива. >> Это похвальная попытка скомпенсировать отсутствие в языке строгой >> типизации.
C>Ррррр.... Никакая статическая типизация не поможет в проверке контроля C>выхода за границы массива, если есть динамическое распределение памяти.
Интересно, откуда такое убеждение?
Конечно, я помню, что Вы фанат Си++. Но ведь пишете Вы не только на этом языке.
Может быть, Вы хотите извлечь какой-то аргумент из терминологической путаницы, заменив мою "строгую" (strict)типизацию на Вашу "статическую"?
В любом случае, это Ваше убеждение неверно.
Рассмотрим тот же игрушечный пример, который я приводил Михаилу.
PROCEDURE InitArray(VAR a: ARRAY OF INTEGER);
VAR i: LONGINT;
BEGIN
FOR i := 0 TO LEN(a)-1 DO
a[i] := 0
END
END InitArray;
Очевидно, что цикл корректен без run-time проверок, т.к. LEN(a) — это не какое-то неизвестное число n, а однозначная характеристика (длина) самого массива a, о чем компилятору Оберона известно, в отличие от компилятора Си/Си++, лишенного подобной информации.
Теперь допустим, что массив был создан динамически:
VAR ap: POINTER TO ARRAY OF INTEGER;
n: INTEGER;
(* ... другие строки исходного текста *)
NEW(ap, n);
InitArray(ap^);
Мы видим, что массив был создан динамически, затем передан в процедуру InitArray.
Разве это повлияло на корректность процедуры InitArray?
Ни в малейшей степени.
Т.е., несмотря на динамическое распределение памяти, проверка корректности индекса массива в процедуре InitArray остается "строгой" и даже "статической".
>> Так вот, я просто хочу обратить Ваше внимание на то, что *для >> компилятора* p и size — по прежнему две отдельные переменные, не >> имеющие между собой ничего общего. Если при реализации класса >> CProtectedArrayOfInt Вы (не дай Бог! ) допустите ошибку, компилятор >> ничем не сможет Вам помочь.
C>А чем мне в этом случае поможет Оберон? В нем будет абсолютно такая же C>ситуация.
Только что я привел пример, что ситуация в Оберона совсем другая.
Размерность массива контролируется компилятором в любой точке программы, в то время как в Си/Си++ информация о размерности массива утрачивается при передаче массива в качестве параметра.
Я уже не говорю о том, что в Си/Си++ нет многомерных открытых (гибких) массивов...
В сущности, можно сказать, что в Си/Си++ вообще нет массивов.
Но существует одно качество, которое нельзя купить, — это надежность. Цена надежности — погоня за крайней простотой. Это цена, которую очень богатому труднее всего заплатить.
Хоар
Re[18]: Почему настоящие программисты избегают C++
AVC wrote:
> Конечно, я помню, что Вы фанат Си++. Но ведь пишете Вы не только на > этом языке. > Может быть, Вы хотите извлечь какой-то аргумент из терминологической > путаницы, заменив мою "строгую" (strict)типизацию на Вашу "статическую"? > В любом случае, это Ваше убеждение неверно. > Рассмотрим тот же игрушечный пример, который я приводил Михаилу. > >PROCEDURE InitArray(VAR a: ARRAY OF INTEGER); > VAR i: LONGINT; >BEGIN > FOR i := 0 TO LEN(a)-1 DO > a[i] := 0 > END >END InitArray; > > > Очевидно, что цикл корректен без run-time проверок, т.к. LEN(a) — это > не какое-то неизвестное число n, а однозначная характеристика (длина) > самого массива a, *о чем компилятору Оберона известно*, в отличие от > компилятора Си/Си++, лишенного подобной информации.
В данном _простейшем_ случае компилятор может проверить корректность
кода (кстати, для С++ есть верефикаторы, делающие тоже самое).
А вот для такого случая уже ничего не получится:
PROCEDURE InitArray(VAR a: ARRAY OF INTEGER);
VAR i: LONGINT;
BEGIN
FOR i := 0 TO LEN(a)-1 DO
a[someFunction(i)] := 0
END
END InitArray;
> Мы видим, что массив был создан динамически, затем передан в процедуру > InitArray. > Разве это повлияло на корректность процедуры InitArray? > Ни в малейшей степени. > Т.е., несмотря на динамическое распределение памяти, проверка > корректности индекса массива в процедуре InitArray остается "строгой" > и даже "статической".
Зато указатель уже не является массивом, а это очень часто нужно для
программ низкого уровня.
> C>А чем мне в этом случае поможет Оберон? В нем будет абсолютно такая же > C>ситуация. > Только что я привел пример, что ситуация в Оберона *совсем другая*.
Да. Компилятор может поймать несколько простых случаев нарушения границ,
но при этом требует повсеместного использования специальных массивов.
> Размерность массива контролируется компилятором *в любой точке > программы*, в то время как в Си/Си++ информация о размерности массива > утрачивается при передаче массива в качестве параметра.
Для передачи размерности есть std::vector (который, кстати, понимают
верефикаторы).
> Я уже не говорю о том, что в Си/Си++ нет многомерных открытых (гибких) > массивов...
boost::multi_array — гибкости во много раз больше Обероновских.
--
С уважением,
Alex Besogonov (alexy@izh.com)
Posted via RSDN NNTP Server 1.9
Sapienti sat!
Re[16]: Почему настоящие программисты избегают C++
Здравствуйте, AVC, Вы писали:
AVC>Так вот, я просто хочу обратить Ваше внимание на то, что для компилятора p и size — по прежнему две отдельные переменные, не имеющие между собой ничего общего. Если при реализации класса CProtectedArrayOfInt Вы (не дай Бог! ) допустите ошибку, компилятор ничем не сможет Вам помочь.
Тогда не надо самому писать такие классы. Пользуйтесь готовыми. Я не понимаю, чем разработчикм С++ной библиотеки хуже создателей Оберона. Уже попахивает ладаном, свечами, бубнами и т.д.
AVC>(Кстати, этот опыт последних лет свидетельствует, что программисты, пишущие на Си, проявляют повышенный интерес к отладчику, т.к. зачастую не в состоянии найти ошибку в своих программах без его помощи.)
Отладчик, в сочетании с развитой системой навигации по коду — это просто наиболее удобный инструмент. Почему ему и предпочтение. Конечно если это производственный процесс, а не соревнование вундеркиндов.
AVC>Также согласен с Вами относительно идеологии Си. Кажется, главное из правил Spirit of C начинается так: "Не мешай программисту..." AVC>Но вот в чем я с Вами не согласен, так это в понимании "высокоуровневости" языков программирования. AVC>На мой взгляд, язык Си (равно как и Си++ в этом случае), не способный передать в подпрограмму даже информацию о
размерности массива, не может считаться высокоуровневым. AVC>Весь смысл высокоуровневости — позволить компилятору гарантировать определенные свойства программ, например — безопасность типов (type safety).
Еще раз повторю — пользуйтесь библиотеками! Естественно, голый язык с несколькими десятками ключевых слов вряд ли будет кому-то сильно полезен. С++ (не С!) позволяет те же массивы "тюнинговать" как угодно.
AVC>С моей стороны это вовсе не эстетская критика. AVC>Я полагаю, что только прирожденный душегуб согласится писать сложное ПО, отвечающее за безопасность людей, на низкоуровневых языках, подобных Си и Си++.
Но вот почему-то пишут и пишут, сволочи...
AVC>Мне приходилось писать ПО, работающее автономно в очень жестком real-time, причем в системе безопасности. AVC>Память под буфера отводилась заранее, а затем управлялась маленьким специализированным "распределителем памяти". AVC>Не вижу никакого преимущества у Си/Си++ по сравнению с Обероном в данном случае.
Возникает впечатление, что проекты были существенно "бюджетные", что вызывало утечки мозгов и в конечном счете привело к таким заблуждениям насчет языка.
На мой взгляд, здесь обсуждаются в основном "детские" ошибки, нехарактерные для "продвинутых". То есть вылавливание которых не являются проблемой. И не потому что кода мало или алгоритмы простые. Просто он написан ТАКИМ ОБРАЗОМ, что вероятность ошибки МАЛА. И на порядок меньше, чем в боготворимых выше языках.
...А отсюда наливаем, когда рецепт написан совсем неразборчиво...
DB>>1.Отсутствие модулей. Имитация понятия модуль в виде пары h-файл – cpp-файл приводит к многочасовым компиляциям системы.
ER>Можно все в хэдере писать. Никто не запрещает.
тогда будут огромные inline функции и *.obj будет намного большего размера..