Здравствуйте, AlikGut, Вы писали:
AG>Здравствуйте, d Bratik, Вы писали:
DB>>Подозреваю, что Вы никогда не создавали на C++ развитого GUI. Все программисты на С++ как чумы избегают решения этой задачи. Они говорят, что это им скушно и неинтересно. Однако именно создание пользовательского интерфейса является наиболее важной, сложной и действительно интересной проблемой при создании системы. Именно пользовательский интерфейс определяет используемые алгоритмы и структуры даннных, а не наоборот. И именно для решение этой самой насущной задачи меньше всего подходит С++.
AG> что-то я наверное совсем уже правильно понимать стал этот топик — там болдом выделено. это как вообще?? если я использую в ГУИ два лист-бокса для отображения каких-то данных, то я по такому определению должен заводить у себя два стринг массива что ли?? и все алгоритмы писать над строками, в них хранящихся?? это маразм, имхо, — каким образом и почему ГУИ вообще должен быть както определять внутреннюю реализцаию ?? "патаму шта из map не могу получить ключи" — не катит — нада както мочь это делать.
Привожу простой пример. Программисты обычно сначала проектируют модель данных в БД (таблицы, реляционные связи и т.д.), а потом только берутся за пользовательский интерфейс. И оказывается, что какие-то данные пользователю лучше всего представлять в виде дерева. При попытке построить дерево все начинает жутко тормозить, из-за того, что модель данных в пользовательском интерфейсе совершенно не согласуется с моделью данных в БД.
Эта проблема наблюдается сплошь и рядом, причем в самых серьезных продуктах и системах. Она часто решается путем отказа от удобств в GUI, который работает не так, как удобно пользователю, а так, как удобно программисту.
Re[14]: Почему настоящие программисты избегают C++
Здравствуйте, Kubera, Вы писали:
K>Функция вычисления среднего арифметического не должна бросать исключений. Это нонсенс , если вместо среднего арифметического при определённых входных параметрах функция будет выкидывать ошибку! А вот её реализация обязана учитывать переполнение, точнее избегать его. Влад, с чем ты не согласен?
Попробую более доходчиво: Функция не учитывающая переполенеие уже ошибочна.
Так понянее?
... << RSDN@Home 1.1.4 beta 3 rev. 279>>
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Здравствуйте, Шахтер, Вы писали:
Ш>Ты внимательно прочитал этот код?
Да, с "++" он не прав. Но он же следующим постом извинился же за это?
В общем, если не докапываться до частностей, то притензию можно принять. Так как проблема действительно может возникнуть, а смысла в использовании беззнаковых целых небыло.
... << RSDN@Home 1.1.4 beta 3 rev. 279>>
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Здравствуйте, achp, Вы писали:
A>Здравствуйте, VladD2, Вы писали:
VD>>Переписывается все что хочешь. Вот только когда баг найдется. Люди лепят баги не специально.
A>Если я пишу unsigned n, то я всегда должен осознавать, какие правила арифметики будут применяться к n. Написание int n также не всегда позволяет избежать "задумчивости".
"Осознавать" на практике означет отказ от интуитивного поведения и жесточайший контроль. Это плохой подход. Конструкции С++ в основном интуитивны. И когда встречается нечто требующее контроля усилием воли, процесс разработки значительно усложняется.
Это точно так же как с неиниыилизированными переменными. Конечно всегда нужно помнить о необходимости их инициализации. Но это не интуитивно и чревато банальными, но трудными в поиске ошибками.
VD>>Вот такие самоуверенные обычно первыми по граблям и ходят.
A>Машинная арифметика — это не то же самое, что общепринятая арифметика. A> Это фундаментально важно понимать. Есть языки программирования, которые стремятся "затушевать" эту разницу; тем не менее, языки вроде Си++ и Си-Шарпа, опирающиеся именно на машинную арифметику, почему-то находят большее применение. Если, имея unsigned n1, n2, пишешь n1 — n2, нужно четко понимать, что получится, будь n1 < n2.
Заметь в коллекций из фрэймворка используются int и long, а не их беззнаковые аналоги. Это сделано именно исходя из интуитивности и удобства. Так что языки тут в общем-то не причем. Тут уже виноваты те кто проектировал библиотеки.
Ну, а почему в C++ и C# имеются беззнаковыи и переполнения совершенно понятно. Погоня за эффектиностью. Если плевать на нее, то можно было бы просто ввести тип int который не имел бы размеров и ограничеий (как в Руби и Питоне). А для контроля значений вообще лучше подошел бы тип с ограничениями. Но это не эффективно.
Тем не мее в Шапр хотя бы введена возможность контроля переполения (ключи компилятора плюс операторы и предложения checker/unchecker. В С++ же нет ничего. И вся отвественность польностью лежит на программисте. Это не хорошо, по-моему.
A>Что касается Си и Си++, то, на мой взгляд, это их недостаток, что отсутствуют переносимые средства обнаружения переполнений. Но и такие, как checked в Си-Шарпе не очень-то полезны.
Да как раз очнь даже полезны. Это компромис между надежность и скорость. Я в любой момент включив одну галку в VS могу получить приложение с контролем переполения и убедиться что хотя бы нет явных ошибок. Ну, а далее если есть проблемы то могу подумать как их проще устранить. Если скорость не важна, то ввести проверку. Если важна, или недопустимы вылеты, то делать ручной контроль.
... << RSDN@Home 1.1.4 beta 3 rev. 279>>
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Здравствуйте, nixite, Вы писали:
N>мне кажется если была перенесена такая арифметика как есть, то нужны и полные средства работы с этой арифметикой, такие какие предоставляет ассемблер. (правда ассемблер ассемблеру рознь, но пусть будет хотябы x86)
Согласен. Возможно было бы разумно иметь опреторы выполняющие действия с контролем переполения. Но это могло бы сильно усложнить язык.
... << RSDN@Home 1.1.4 beta 3 rev. 279>>
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Здравствуйте, AlexBS, Вы писали:
AE>>12. За отсутствие менеджера конфигураций. Так чтобы сделать Debug и Release хотябы, и пользоваться просто переключая их. ABS>А зачем? Во всех конфигурациях размеры файлов и скорость выполнения одна и таже. Не забивай себе голову
Настоящие програмисты юзают MAKEFILE и рулят эти конфиги как хотят.
AE>>15. За то что она не MDI. Это ужасно "УДОБНО". Приходится очищать рабочий стол перед открытием делфи, да и две запущенные — это головняк ("КРУТО"), поскольку никогда не знаешь в редакторе какой находишся. Иногда по ALT-TAB переключается только редактор, а главное окно нет. ABS>А если на главное окно попадает фокус и в редакторе активный модуль без формы, то с клавиатуры сфокусировать редактор невозможно.
Настоящие програмисты юзают командную строку и редактор типа FAR. Так круче.
AE>>16. За WITH благодаря которому дебаггер не показывае значение переменных типа with TComeCObject.Create(...) do Visible := TRUE; AE>> Значение Visible — не увидишь никогда. Только если with SomeObject do SomeProperty := SomeValue; то в ТОЛЬКО окне свойств надо подставить SomeObject.SomeProperty и только тогда будет значение
Хм... А че и в асемблере не видно. Или дебагер асма не поддерживает?
ABS>Да... от WITH толку столько же, как и от комментариев на китайском — вроде все есть, а к чему относится, непонятно.
WITH это дела вкуса.
ABS>На последок хотелось бы заметить про идиотский var в описаниях функций, где он зачастую просто мешает!
ABS>Например, ReadProcessMemory ABS>
ABS>Ну нахрена мне всегда(!!) заводить бесполезную переменную для параметра var lpNumberOfBytesRead: DWORD, когда она в 99% случаях просто ненужна! ABS>А таких функций уйма!
Здравствуйте, ss_sa, Вы писали:
_>Здравствуйте, AlexBS, Вы писали:
AE>>>12. За отсутствие менеджера конфигураций. Так чтобы сделать Debug и Release хотябы, и пользоваться просто переключая их. ABS>>А зачем? Во всех конфигурациях размеры файлов и скорость выполнения одна и таже. Не забивай себе голову
_>Настоящие програмисты юзают MAKEFILE и рулят эти конфиги как хотят.
Причем здесь MAKEFILE? Разговор про делфи. Причем на тему полезности Debug/Release конфигураций, а не на счет управления ими.
AE>>>15. За то что она не MDI. Это ужасно "УДОБНО". Приходится очищать рабочий стол перед открытием делфи, да и две запущенные — это головняк ("КРУТО"), поскольку никогда не знаешь в редакторе какой находишся. Иногда по ALT-TAB переключается только редактор, а главное окно нет. ABS>>А если на главное окно попадает фокус и в редакторе активный модуль без формы, то с клавиатуры сфокусировать редактор невозможно.
_>Настоящие програмисты юзают командную строку и редактор типа FAR. Так круче.
Еще раз повторюсь, к делфи никакого отношения не имеет. Иначе идет под хвост вся крутость проектирования GUI, на что делает упор автор топика,
AE>>>16. За WITH благодаря которому дебаггер не показывае значение переменных типа with TComeCObject.Create(...) do Visible := TRUE; AE>>> Значение Visible — не увидишь никогда. Только если with SomeObject do SomeProperty := SomeValue; то в ТОЛЬКО окне свойств надо подставить SomeObject.SomeProperty и только тогда будет значение
_>Хм... А че и в асемблере не видно. Или дебагер асма не поддерживает?
это ты к чему?
ABS>>Да... от WITH толку столько же, как и от комментариев на китайском — вроде все есть, а к чему относится, непонятно.
_>WITH это дела вкуса.
Безусловно, только большенство делфи-программистов ставят его на первые места в список самых крутых фичь делфи.
ABS>>На последок хотелось бы заметить про идиотский var в описаниях функций, где он зачастую просто мешает!
ABS>>Например, ReadProcessMemory ABS>>
ABS>>Ну нахрена мне всегда(!!) заводить бесполезную переменную для параметра var lpNumberOfBytesRead: DWORD, когда она в 99% случаях просто ненужна! ABS>>А таких функций уйма!
_>Вот здесь делфи не причем это фича Винды
_>BOOL ReadProcessMemory( _> HANDLE hProcess, _> LPCVOID lpBaseAddress, _> LPVOID lpBuffer, _> SIZE_T nSize, _> SIZE_T* lpNumberOfBytesRead _>);
_>В C++ тоже достает заводить переменые для допустим _>ReadFile(..., LPDWORD lpNumberOfBytesRead, ....)
_>Кстати переменые иногда можно и не заводить а передать указатель NULL. _>В дельфи наверное так: ReadProcessMemory(THandle,lpBase,lpBuffer,nSize,nil);
_>Чтите MSDN, он рулез!
Спасибо за урок про переменные, но к сожалению ReadProcessMemory(THandle,lpBase,lpBuffer,nSize,nil) при таком описании не прокатит — загляни в Object Pascal Language Reference — он рулез
Здравствуйте, AlexBS, Вы писали:
_>>Настоящие програмисты юзают MAKEFILE и рулят эти конфиги как хотят.
ABS>Причем здесь MAKEFILE? Разговор про делфи. Причем на тему полезности Debug/Release конфигураций, а не на счет управления ими.
Ну в С++ Builder этот MAKEFILE генерировался из меню и соответственно ключами компилятора можно было много чего нарулить, вот нашел старый Делфи 2.0 там этого действительно нет.
Делфи-
ABS>>>А если на главное окно попадает фокус и в редакторе активный модуль без формы, то с клавиатуры сфокусировать редактор невозможно.
_>>Настоящие програмисты юзают командную строку и редактор типа FAR. Так круче. ABS>Еще раз повторюсь, к делфи никакого отношения не имеет. Иначе идет под хвост вся крутость проектирования GUI, на что делает упор автор топика,
По опыту проектирование GUI занимает от силы 10% програмирования, долго ли кнопочки накидать на форму, хотя в Дельфи конечно удобно програмировать GUI.
AE>>>> Значение Visible — не увидишь никогда. Только если with SomeObject do SomeProperty := SomeValue; то в ТОЛЬКО окне свойств надо подставить SomeObject.SomeProperty и только тогда будет значение
_>>Хм... А че и в асемблере не видно. Или дебагер асма не поддерживает?
ABS>это ты к чему?
А к тому что в если переключить дебаггер в асм то можно любую переменную найти.
Turbo Debugger | View | CPU
ABS>>>Да... от WITH толку столько же, как и от комментариев на китайском — вроде все есть, а к чему относится, непонятно.
_>>WITH это дела вкуса.
ABS>Безусловно, только большенство делфи-программистов ставят его на первые места в список самых крутых фичь делфи.
Ну как говорится каждому свое
_>>Кстати переменые иногда можно и не заводить а передать указатель NULL. _>>В дельфи наверное так: ReadProcessMemory(THandle,lpBase,lpBuffer,nSize,nil);
ABS>Спасибо за урок про переменные, но к сожалению ReadProcessMemory(THandle,lpBase,lpBuffer,nSize,nil) при таком описании не прокатит — загляни в Object Pascal Language Reference — он рулез
nil ведь нулевой указатель?
Вообще то я подразумевал не описание а программу:
var
hProcess: THandle;
lpBaseAddress: Pointer;
lpBuffer: Pointer;
nSize: DWORD;
Здравствуйте, ss_sa, Вы писали:
AE>>>>> Значение Visible — не увидишь никогда. Только если with SomeObject do SomeProperty := SomeValue; то в ТОЛЬКО окне свойств надо подставить SomeObject.SomeProperty и только тогда будет значение
_>>>Хм... А че и в асемблере не видно. Или дебагер асма не поддерживает?
ABS>>это ты к чему?
_>А к тому что в если переключить дебаггер в асм то можно любую переменную найти. _>Turbo Debugger | View | CPU
Да не в этом дело. Показывает то оно и так, только WITH сбивает область видимости, т.к. IDE не может проследить, относится ли идентификатор под курсором каким либо образом к WITH-объекту. Вот поэтому ничего не показывает.
_>>>Кстати переменые иногда можно и не заводить а передать указатель NULL. _>>>В дельфи наверное так: ReadProcessMemory(THandle,lpBase,lpBuffer,nSize,nil);
_>nil ведь нулевой указатель?
_>Вообще то я подразумевал не описание а программу:
_>var _>hProcess: THandle; _>lpBaseAddress: Pointer; _>lpBuffer: Pointer; _>nSize: DWORD;
_>hProcess=OpenProcess(...); _>lpBaseAddress=$dddddd; _>nSize=1000; _>lpBuffer=LocalAlloc(??,nSize); _>ReadProcessMemory(THandle,lpBase,lpBuffer,nSize,nil);
_>Вобщем давно я просил паскаль тогда еще и дельфи не было )
Так нельзя, т.к. nil — константа, а по описанию требуется переменная (об этом говорит кейворд var). Я про это и говорю, что при таком дурацком описании хеадеров функций невозможно забить нулем ненужный параметер, а обязательно заводить переменную!
Лечатся то такие ситуации очень просто, например путем замены var lpNumberOfBytesRead: DWORD на const lpNumberOfBytesRead: PDWORD. Но основная проблема в том, что эта функция (как и все остальные) описана в Windows.pas, т.е. поменять ее никак нельзя.
Re[16]: Почему настоящие программисты избегают C++
Здравствуйте, d Bratik, Вы писали:
DB>Правильно писать именно так: DB>for(size_t i=0; i < vec.size(); ++i) DB>{ DB>}
Уважаемый де Братик!
Я открою Вам страшный секрет. Расскажу, как Ваш пример написал бы не "настоящий программист, избегающий С++", а лох какой-нибудь.
Замечу, что постановка задачи "пройтись по всем элементам кроме последнего" подразумевает наличие хотя бы одного элемента. Проход без последнего элемента по пустому контейнеру есть вопрос спорный, и лучше бы его обработать отдельно. Т.е. примерно так:
if (!vec.empty())
{
std::for_each(vec.begin(), vec.end() - 1, WhateverYouWant());
}
else
{
// А тут или ничего, или assert, или throw, или запись в лог в конце концов.
}
Так что C++ нормальной язык, просто Вы не умеете его готовить.
Здравствуйте, AlexBS, Вы писали:
ABS>Лечатся то такие ситуации очень просто, например путем замены var lpNumberOfBytesRead: DWORD на const lpNumberOfBytesRead: PDWORD. Но основная проблема в том, что эта функция (как и все остальные) описана в Windows.pas, т.е. поменять ее никак нельзя.
Ну можно, можно поменять. Сделай свой импорт — ничего сверхестественного в Windows нет. И для счастья достаточно написать свой модуль в uses после Windows — правила перекрытия идентификаторов в Pascal обеспечат нужный результат.
... << RSDN@Home 1.1.4 beta 4 rev. 303>>
Уйдемте отсюда, Румата! У вас слишком богатые погреба.
Здравствуйте, AlikGut, Вы писали:
AG> что-то я наверное совсем уже правильно понимать стал этот топик — там болдом выделено. это как вообще?? если я использую в ГУИ два лист-бокса для отображения каких-то данных, то я по такому определению должен заводить у себя два стринг массива что ли?? и все алгоритмы писать над строками, в них хранящихся?? это маразм, имхо, — каким образом и почему ГУИ вообще должен быть както определять внутреннюю реализцаию ?? "патаму шта из map не могу получить ключи" — не катит — нада както мочь это делать.
Братик имеет в виду, что проектирование системы в идеальном случае должно быть устроено вот так:
— сначала идет исследование предметной области и определение проблематики.
— затем архитектор придумывает решение поставленной задачи в виде точного описания наблюдаемого поведения системы. С точки зрения наших западных коллег, на этом и заканчивается архитектура. Все остальное — банальный инженерный труд по реализации спецификаций.
— выполняется прототипирование документированного наблюдаемого поведения, и все сценарии использования тестируются на удобство и практичность
— решение корректируется в соответствии с результатами прототипирования
— выбирается адекватная платформа (языки, технологии, API)
— разрабатывается модель реализации системы в выбранной платформе
— в соответствии с моделью выстраиваются алгоритмы и структуры (интерфейсы и классы, или функции, или таблицы и хранимые процедуры — depends)
— проводится QA.
В случае, если значительная часть наблюдаемого поведения системы включает взаимодействие с пользователем, то конечно же вопросы UI выходят на первый план. К слову, это вовсе не обязательно — есть огромное количество задач, где взаимодействия с человеком не требуется. Берем любой RFC с IETF — он отлично документирует наблюдаемое поведение системы в терминах команд, параметров, состояний и т.п. И среди этого есть очень и очень сложные задачи, на фоне которых самый сложный GUI смотрится блекло.
К счастью, реально сложные требования к поведению софта встречаются в природе достаточно редко.
Одним из самых распространенных способов сделать плохое приложение является разработка в приближении полного отсутствия пользователя. А уж потом делаются мучительные попытки приклеить адекватный GUI к неудачно выбранной модели.
... << RSDN@Home 1.1.4 beta 4 rev. 303>>
Уйдемте отсюда, Румата! У вас слишком богатые погреба.
Здравствуйте, Sinclair, Вы писали:
S>Здравствуйте, AlexBS, Вы писали:
ABS>>Лечатся то такие ситуации очень просто, например путем замены var lpNumberOfBytesRead: DWORD на const lpNumberOfBytesRead: PDWORD. Но основная проблема в том, что эта функция (как и все остальные) описана в Windows.pas, т.е. поменять ее никак нельзя. S>Ну можно, можно поменять. Сделай свой импорт — ничего сверхестественного в Windows нет. И для счастья достаточно написать свой модуль в uses после Windows — правила перекрытия идентификаторов в Pascal обеспечат нужный результат.
Это все и так понятно. Другое дело в самом подходе к хеадерам. Т.е. если мне понадобятся (просто к примеру) 100 подобных функций, то мне что, их все переопределять?
Вообше, зачем делать этот долбанный var в хеадере функци, которая импортируется из винды?
Здравствуйте, d Bratik, Вы писали:
DB>Я потом так и понял. Наверное практически все Ваши закачики сидят на Windows, а версия для Solaris делается для проформы (заказчиков можно по пальцам пересчитать).
Ошибаетесь Большинство сидит под Linux-ом (особенно Telecom сектор). Под Solaris-ом тоже много, но они постепенно мигрируют под Linux.
Но вообще, в проектах народ сидит одновременно под разными системами. Что-то удобней делать в одной системе, что-то в другой.
Душа обязана трудиться! (с) Н.Заболоцкий.
Re[10]: Почему настоящие программисты избегают C++
Здравствуйте, _Obelisk_, Вы писали:
_O_>Здравствуйте, d Bratik, Вы писали:
DB>>Я потом так и понял. Наверное практически все Ваши закачики сидят на Windows, а версия для Solaris делается для проформы (заказчиков можно по пальцам пересчитать).
_O_>Ошибаетесь Большинство сидит под Linux-ом (особенно Telecom сектор). Под Solaris-ом тоже много, но они постепенно мигрируют под Linux. _O_>Но вообще, в проектах народ сидит одновременно под разными системами. Что-то удобней делать в одной системе, что-то в другой.
Неужели большинство именно под Linux-ом, а не под WIndows-ом? Вы переспросите отдел маркетинга. И сколько в процентном отношении пользователей сидит на Solaris?
Еще пару вопросов. Интересно, как выполняется поддержка и разработка новых версий? Ведь программа-то на MFC. Это значит, что сначала появляется версия под Windows. Потом эта версия портируется под Linux, на котором есть Wine (эмулятор WinAPI). А как же делается Solaris-версия? Как там эмулируется WinAPI и MFC? И если действительно как-то эмулируется, то как обстоят дела, если пользовательский интерфейс использует multi-threading?
Может нам отдельную тему организовать, посвященную вопросам кросс-платформенной разработки на С++.
Re[16]: Почему настоящие программисты избегают C++
Здравствуйте, d Bratik, Вы писали:
DB>Правильно писать именно так: DB>for(size_t i=0; i < vec.size(); ++i) DB>{ DB>}
DB>Чтобы понять, почему, рекомендую почитать вот это: DB>http://www.cas.mcmaster.ca/~emil/publications/reentrance
ха-ха, реентерабельность, значит?
типа за время выполнения тела цикла количество элементов контейнера изменится?
А каким боком предполагается узнавать, где именно он изменился, чтобы не обрабатывать элементы дважды и не оставлять новые необработанными?
Здравствуйте, VladD2, Вы писали:
VD>Здравствуйте, Kubera, Вы писали:
K>>Функции, логика которых не предусматривает ошибочных ситуаций, не должны кидать исключений. А функция вычисления среднего арифметического относится как раз к таким. Т.е. предложенное тобой решение с генерацией исключения неверно.
VD>Функция не учитывающая переполенеие уже ошибочна.
Результат усреднения не может содержать переполнения