A>Что нужно было сделать? Проверить, можно ли в файл записать? A>
A>bool try(char* path)
A>{
A> FILE* f;
A> if((f = fopen(path, "w")) == NULL)
A> return 0;
A> if(!fprintf(f, "Hello...\n"))
A> {
A> fclose(f);
A> return 0;
A> }
A> return 1;
A>}
A>
A>Это если я конечно ничего не путаю насчёт возвращаемого значения printf'а.
Если в файл нельзя писать, то fopen вернет NULL
fprintf обломается только от переполнения тома, или от того, что винчестер сыпаться начал.
AF> Почему же сказок? Человеку надо видеть что ему править. Мысль о том, что код может не содрежать примитивных ошибок — вроде незакрытого вовремя дескриптора, а содержать ошибки концептуальные, семантические — в голову видимо не приходит...
Си++ от них никак не гарантирует. Тут надо иметь голову, и если ее нет — ни один язык не поможет.
А то, что человеку надо видеть то, что он делает — вот пример. Казалось бы — прекрасная идея — написать объект, который будет брать лок в конструкторе, и отдавать в деструкторе. Локи все вовремя отдадутся типа
Ан нет. Нет визуальной подсказки о том, что лок отдали. Только закрывающая фигурная скобка. В итоге увеличиваются шансы запутаться в том, в каком именно месте кода отдается лок.
AF> Вероятнее всего для Вас — важнее детали процесса, или же смысл процесса заключается в деталях. Такие взгляды довольно распространены среди системных программистов.
AJD>Если мы говорим про контролы с классом SCROLLBAR — то перехват сообщений WM_PAINT, WM_NCPAINT спасет отца русской демократии. Если же говорим про стандартные скролбары
Кстати, их наличие — равно как и вообще концепция nonclient area — одна из мерзейших фич USERа.
Здравствуйте, Maxim S. Shatskih, Вы писали:
AJD>>Если мы говорим про контролы с классом SCROLLBAR — то перехват сообщений WM_PAINT, WM_NCPAINT спасет отца русской демократии. Если же говорим про стандартные скролбары
MSS>Кстати, их наличие — равно как и вообще концепция nonclient area — одна из мерзейших фич USERа.
Почему?
"For every complex problem, there is a solution that is simple, neat,
and wrong."
Дык не в этом вопрос. Можно и fstream заюзать.
Вопрос в том, чем этот подход (fopen/fstream) радикально хуже того ужаса, что был процитирован выше — с какими-то хэндлами и прочими вкусностями?
Здравствуйте, Maxim S. Shatskih, Вы писали:
MSS>Вернемся к SMART (протокол съема с ИДЕ винчестера инфы о том, как скоро он посыпется). Человек написал ради этого класс. Зачем? Три вызова — CreateFile, DeviceIoControl, CloseHandle. Вот зачем там — класс?
чтобы не вызывать каждый раз вручную этот самый CloseHandle
Девять раз программер его напишет, на десятый точно забудет
И вообще — ну пусть класс. Что от этого плохого будет?
Только не надо снова про перегруженные операторы и виртуальные функции. В данном случае появление в классе таких "зверей" — это уже клиника, и от языка не зависит.
MSS>Про драйвера. Задумался вчера всерьез над темой "Си++ в драйверах", и получилось вот что. Там некое количество внешних структур, с которыми приходится работать, и которые приходят извне. Ну и толку будет оборачивать NDIS_PACKET в класс? Что это даст-то? Взаимодействие с окружающей ОС все равно делается в терминах NDIS_PACKET, и зачем вокруг него врапперы плодить?
Вот и надо было сказать просто: "весь остальной код написан на С по историческим причинам, поэтому применение C++ во взаимодействии с ним дает мало пользы"
Здравствуйте, Maxim S. Shatskih, Вы писали:
MSS>Ага, новичок. С 93го года на этом языке работаю. MSS>Более того. Для UI я им и по сей день пользуюсь, естественно.
Многие мои знакомые пользуються компьютером много лет, но дальше инсталляции игр, из развитие в IT области не пошло. Печально что вы используете гоночный автомобиль для перевозки картошки. И ещё более грустно, что вы и не подозреваете и даже отказыветесь увидеть то, о чём вам тут все говорят. Есть старая добрая поговорка — "если тебе 10 человек сказали, что ты пьян, то иди проспись ,)"
Да и программирование UI никогда не считалось уважаемым занятием.
B>> Э, какой горячий джигит ,). B>> Кроме x89 архитектуры процессоров есть ещё десятки других платформ, иногда очень >>экзотических. И для этих платформ нет С++ компилятора, а есть только С. MSS>Учите матчасть. gcc портирован на такую экзотику, что вряд ли бывала в России. И для экзотических платформ в наше время — портируют gcc, а не пишут свой компилятор.
Платформ гораздно больше . Я смотрю на свой рабочий стол — принтер, модем, мобилка, часы с записной книжкой, DECT телефон, монитор, UPS(под столом . И везде стоят микроконтроллеры и микропроцессоры. Портировать под каждый девайс gcc — дорого и можно столкнуться с лецензионными проблемами, да и зачем из пушки да по воробьям. Поэтому, как правило производитель всякой мелочи имеет свой компилятор С.
Как вы думаете — проприетарный BIOS вашей материнки скомпилирован gcc ,) ?
>>То есть это вопрос переносимости, который очень актуален для некоторых промышенных >>отраслей. MSS>Бред. См. выше.
Хотя это бред не основное направление мой проффесиональной деятельности, но и он мне денег приносит. БОЛЬШЕ БРЕДА!
B>> А лет через 10-20 и С++ тоже могут на свалку викинуть, как когда то перфокарты. MSS>То-то UNIX 30 лет живет без существенных изменений Есть такое понятие — классика.
Слышали про закон Мура, он относиться не только к числу транзисторов на квадратный метр. И 30 двадцатого века, это совсем не то что 30 лет двадцать первого. Да через 10 лет С++ будит жить поживать, но спрос на его специалистов значительно снизиться. Следите за прогрессом — появление новых языков программирования; новых методологий; поддержка виртуализации операционных систем на уровне железа; да и вообще огромные темпы развития вычислительных мощностей; новые интелектуальные 3D интерфейсы сладящие за нашими глазами, дыханием, биотоками, понимающими нашу речь; Всё это, по Карлу Марксу, просто не может не дать качественного скачка, после которого следующие поколение будет ужасаться при виде клавиатуры и мышки.
Здравствуйте, Maxim S. Shatskih, Вы писали:
AF>> Почему же сказок? Человеку надо видеть что ему править. Мысль о том, что код может не содрежать примитивных ошибок — вроде незакрытого вовремя дескриптора, а содержать ошибки концептуальные, семантические — в голову видимо не приходит...
MSS>Си++ от них никак не гарантирует. Тут надо иметь голову, и если ее нет — ни один язык не поможет.
MSS>А то, что человеку надо видеть то, что он делает — вот пример. Казалось бы — прекрасная идея — написать объект, который будет брать лок в конструкторе, и отдавать в деструкторе. Локи все вовремя отдадутся типа
MSS>Ан нет. Нет визуальной подсказки о том, что лок отдали. Только закрывающая фигурная скобка. В итоге увеличиваются шансы запутаться в том, в каком именно месте кода отдается лок.
Очень напоминает аргумент конца 70-х против {}. Тогда на полном серьёзе писались научные статьи, доказывающие — примерно с такой же аргументацией, что без BEGIN ... END код вообще писать нельзя, что мол {} никто не заметит и {} — главный источник ошибок...
То же самое и здесь.с локами. Брать новичка, который не имеет представления об ОСНОВАХ языка (а то, что автоматические переменные уничтожаются при выходе из блока — очевидные основы) и отдавать ему написание многопоточного кода — будет грубейшей ошибкой. Потому, как он и на C ужас что напишет — и ещё не известно — где страшнее.
Я видел кучу кода а-ля:
Ну да, править тут ошибку — очень легко, но зачем? Использовался бы здесь класс обёртки — вопроса бы не возникло.
Так что мы таки приходим к естественному выводу — дело в мастерстве, а не в языке...
Здравствуйте, Maxim S. Shatskih, Вы писали:
AF>> Вероятнее всего для Вас — важнее детали процесса, или же смысл процесса заключается в деталях. Такие взгляды довольно распространены среди системных программистов.
MSS>Да, про меня это утверждение верно.
Отсюда и спор с большинством на форуме. Для Вас скорее всего в записи:
CFile obFile;
obFile.Open( "Somefile" );
— Будет важнее всего, какими клонкретно системными вызовами был открыт файл, какие дескрипторы безопасности были переданы, сколько вызовов и в какой последовательности было сделано. Поэтому необходимость лезть внутрь обёртки и разбираться со всем этом — вас раздражает. У большинства же интересы диаметрально противоположны. Гораздо интереснее не детали того, как открыватся файл — а сам факт его открытия и дальнейшие действия — причём опять таки их суть, а не детали...
S>Про 1) S>Если это такая уж фича Windows, как вы это представляете (типа святая), то откуда например у CListCtrl функция DrawItem, позволяющая самому инжектить отрисовку?
Неправильный вывод. Она не "святая", она просто есть, об этом надо знать, и чуть по другому менять отрисовку.
DG>> Это стандартная задача, этому посвящено очень много статей и литературы. S>В данном случае, не стоило изобретать велосипед, а стоило хоть один раз прочитать хорошую статью, которая рассказывает, как это делается.
S>Стандартная? Ну дай мне ссылку на "стандартную" статью, где изменяется отрисовка у скролбара.
интересное чтиво, вот только опоздало лет на 10+, даже странно что вокруг него такой флейм развели, по-этому коментировать пост просто не хочется.
Поражает другое, у людей много писавших код с использованием глубокой специфики ОС или железа появляется своеобразное професиональное заболевание которое можно назвать попросту "жлобством", почему то они считают что только проекты из той области где они работают, можно считать "серьезными"
Здравствуйте, Maxim S. Shatskih, Вы писали:
MSS>Про драйвера. Задумался вчера всерьез над темой "Си++ в драйверах", и получилось вот что. Там некое количество внешних структур, с которыми приходится работать, и которые приходят извне. Ну и толку будет оборачивать NDIS_PACKET в класс? Что это даст-то? Взаимодействие с окружающей ОС все равно делается в терминах NDIS_PACKET, и зачем вокруг него врапперы плодить?
Все таки чем ближе к ядру тем там жарче, тем большее количество мелочей становятся важными, тем сложнее их инкапсулировать, и окружающая среда там истончается. Да возможно там другие приемы проектирования и оформления кода нужны.
Но все таки я настаиваю что для прикладного уровня, какая нибудь примитивная задачка удаления файлов в текущей директории должна выглядеть примерно так
foreach(string s in Directory.GetFileSystemEntries(Directory.GetCurrentDirectory(),"*.tmp"))
File.Delete(s);
Вот так она и выглядит yf С#. Просто но со вкусом, как видится так и делается. Делается незначительная мелочевка, она и в программе секунды занимает чтобы понять что там делается, и что там нет никакого скрытого поведения. Какие там будут извращения на С, без OOP чтобы это сделать через WinAPI.
Но я в принципе не настаиваю чтобы самые глубокие внутренности ядра выглядели и оформлялись примерно так:
class OperatingSystemWin2K
{
static void Main()
{
if(Hardware.Processors.Count<1)
throw new WrongProccessorCountException();
if(Hardware.Processors[0].Family.Name!="x86")
{
Console.WriteLine("Wrong proccessor");
Hardware.Processors[0].Reset();
return;
}
if(!Hardware.Processors[0].IsInProtectedMode)
{
try
{
Hardware.Processors[0].IsInProtectedMode=true;
}
catch
{
Console.WriteLine(" Can not switch to protected mode");
Hardware.Processors[0].Reset();
return;
}
//.........
}
}
};
Это было бы конечно круто. Но есть подозрения что возникли бы небольшие проблемы с некоторыми мелочами.
Здравствуйте, Maxim S. Shatskih, Вы писали:
MSS>Так маразм-то — спецификация throw().
А я спорю? Я же назвал это проблемой... Но это фигня по сравнению с граблями которые достались от С. MSS>Кому она нужна-то? излишество, загромождающее код,
Ни кому. MSS>и одна из самых бесящих вещей в Джаве, где она обязательна, в отличие от Си++. .NET и исключения
MSS>Кто-нить реально пользуется этой фичей Си++?
Сомневаюсь MSS>И каким боком из деструктора делается то, что может возбудить ситуацию? Там что, делается то, что может обломиться? Сразу откровенный маразм.
... << RSDN@Home 1.1.3 beta 1 >>
Пусть это будет просто:
просто, как только можно,
но не проще.
(C) А. Эйнштейн
Здравствуйте, Astaroth, Вы писали:
A>Дык не в этом вопрос. Можно и fstream заюзать. A>Вопрос в том, чем этот подход (fopen/fstream) радикально хуже того ужаса, что был процитирован выше — с какими-то хэндлами и прочими вкусностями?
Для тебя ни чем.
Просто при работе на прямую с виндовыми файлами можно спроецировать фаил в память, производить асинхронное чтение/запись...
... << RSDN@Home 1.1.3 beta 1 >>
Пусть это будет просто:
просто, как только можно,
но не проще.
(C) А. Эйнштейн
Здравствуйте, Maxim S. Shatskih, Вы писали:
MSS>Чем он лучше? FILE и fopen просто синтаксически красивее, чем эта бредятина с кучей ::.
Ты хотел сказать привычнее.
... << RSDN@Home 1.1.3 beta 1 >>
Пусть это будет просто:
просто, как только можно,
но не проще.
(C) А. Эйнштейн
S_> Все таки чем ближе к ядру тем там жарче, тем большее количество мелочей становятся важными, тем сложнее их инкапсулировать, и окружающая среда там истончается.
Ну да. Так и есть. Если мне надо проимплементировать функцию, которая зовется извне, и у которой сигнатура:
— то как-то стремно там в ней оборачивать PIRP в класс. Хотя и можно, наверное. К слову, возврат NTSTATUS отсюда — это еще один грубый misdesign Майкрософта, вслед за INVALID_HANDLE_VALUE. Там было бы достаточно BOOLEAN.
S_> Но все таки я настаиваю что для прикладного уровня, какая нибудь примитивная задачка удаления файлов в текущей директории должна выглядеть примерно так S_>[c#] S_>foreach(string s in Directory.GetFileSystemEntries(Directory.GetCurrentDirectory
Для прикладного уровня — конечно. Можно даже проще. Вот так
for $name(`ls`)
{
...
}
Очень, очень многие программы прикладного уровня стоит писать на этом языке удивительно могучий. Надо текущее состояние файрволла? — пожалуйста:
for $rule(`ipfw show`)
{
...
}
Не надо даже знать, что такое IOCTL, не надо писать классовый враппер вокруг IOCTLей для файрволла. Все проще. И файлы там открываются в том же синтаксисе, что редиректы командной строки. У нас будет
open MYFILE, "ls -l |";
вместо Сишного popen(). Очень хороший язык. Для мелочевки особенно. Один недостаток — по читабельности кода худший
S_> Но я в принципе не настаиваю чтобы самые глубокие внутренности ядра выглядели и оформлялись примерно так: S_>[c#] S_>class OperatingSystemWin2K S_>{ S_> static void Main() S_> { S_> if(Hardware.Processors.Count<1) S_> throw new WrongProccessorCountException();
В подавляющем большинстве случаев безразлично, как именно обломалась функция. Это относится и к exceptions, и к кодам ошибки типа NTSTATUS и HRESULT.
Как правило, нужда в знании причины облома возникает уже в UI, чтобы оную причину показать юзеру. В ОО фреймворках все это лежит в объекте exception.
В остальных случаях — ну редко это нужно. Очень редко. Например, при придумывании нового цифирного имени файла — открываешь FILE0000.DAT — получил STATUS_OBJECT_NAME_COLLISION — открываешь FILE0001.DAT и дальше.
Потому на уровне языка энфорсировать, какие именно exceptions имеет право кидать функция — просто затрудняет работу и все.
Джаву я знал в 97ом году, и то как игрушку. Но эта спецификация там успела достать. На деле она ограничивает то, чем можно пользоваться в методе. Нельзя пользоваться теми вещами, которые имеют более широкую спецификацию throw. Вокруг них придется try/catch делать, в котором переделывать одни разновидности exceptions в другие. Изврат редкостный.