Я чуть ниже начал нитку "Наследование и рефакторинг". Там максимально по делу изложена главная (ИМХО) претензия к ОО. Если есть желание — почитай.
Пока что мне там ответили а) что "ООП еще так молодо" — это за 20-то лет! б) что нельзя наследоваться от конечных классов, а этот запрет нарушался во всех знаменитых (и хороших) ОО фреймворках от ТурбоВижна до наших дней в) что качественный ОО дизайн требует фич, которые толком не поддержаны ни в одном ОО языке, и поддержаны разве что в виде макросов в ATL.
Насчет драйверов. Проекты маленькие по объему (мегабайт густо комментированного исходника — это в этой области большой проект) — но как бы очень насыщенные по логике. В этом области "терять сцепление колес с дорогой" и витать в облаках абстракций вряд ли оправдано. И требования к надежности очень высоки. Потому ИМХО оправдано не прятать детали реализации, а выставлять наружу как есть.
Абстракции там получаются очень крупноблочные, скорее как в COMе, а не как в классических ОО языках типа Дельфей, Джавы и Шарпа.
Здравствуйте, VladD2, Вы писали:
WH>>а если бы был компаил-тайм рефлекшен... то вобще бы сразу сгенерил бы код для сериализации в нужном не формате. VD>Пойми если рефлекшен есть, то он есть. Сделай превую компиляцию, получи мета-информацию, прочти ее и сгенери код сериализации.
Это я могу и сейчас... читаем дебугинфо и... сам не пробовал но кто-то на форуме говорил что у него это работает.
Но это не переносимо
Кроме мейнстрейма для которого .НЕТ и ему подобные пожалуй лучший выбор есть и будут области программирования где нужен zero overhead language те что не использую за то не плачу.
Вот тут то и нужен компаил тайм рефлекшен. Чтобы то что нужно я мог сгенерить прямо во время компиляции и именно так как мне надо. А если мне понадобится метаинформация в рантайме то я мог бы ее вытащить причем только для тех классов для которых она мне нужна и ровно столько сколько мне нужно.
Единственный адекватный способ создать такой язык это проектирование его с нуля и при этом забив на обратную совместимость с С/С++.
К стати. У тебя есть конкретные идеи по выделеной части?
8. Отсуствие системы автоматического контроля памяти, или механизма позволяющего гладко интегрировать такой механизм на уровне библиотеки.
... << RSDN@Home 1.1.3 beta 1 >>
Пусть это будет просто:
просто, как только можно,
но не проще.
(C) А. Эйнштейн
Здравствуйте, Voblin, Вы писали:
V>Здравствуйте, Maxim S. Shatskih
V>На 100% согласен с тем, что сказано про запутанность кодов и монструозность библиотек.
V>Когда читал про оптимизацию компиляторов, вспомнился один пример немножко из другой области, но весьма жизненный.
V>Есть две среды разработки специфических приложений — 1С и MBS Navision. Обе занимаются не компиляцией, а интерпретацией своих скриптовых языков. 1С написан, видимо, на С++ с широким использованием COM, в результате чего производительность встроенного языка при исполнении на P4 примерно равна производительности ROM-бэйсика на IBM XT. Navision пошустрее будет. Раз в 10. Тоже, конечно, безобразие, но но разница в 10 раз — это, согласитесь, аргумент.
Скажем так: опыт программирования на 1С у меня не большой, а точнее сказать ваще не большой, вчера когда читал этот треп скачал и установил, и начал писать на нем ). Но..
Не знаю про Навизион, но:
1С, в чем то очень ограниченый язык, согласен что он расширяемый вроде бы, не в курсе, и не буду спорить по этому поводу... опять таки но:
чем больше и гибче возможности по программированию задачи тем на мой взгляд лучше.
Т.е. на том же Си++ описать можно все... а в 1С только в пределах того что она позволяет..
Хотя конечно хотелось бы взглянуть на реализацию расширения 1С кто ссылкой кинется буду очень признателен.
Здравствуйте, VladD2, Вы писали:
VD>Здравствуйте, WolfHound, Вы писали:
WH>>А теперь посмотри на амереканцев... жрут в МакДональдсе и выглядят как... ну вы поняли... Короче я считаю что МакДональдс гораздо опаснее чем БенЛаден и компания... В отличии от террористов МакДональдс убивает милионами причем с особой жестокостью и цинизмом.
VD>Не, а мне нравится макдонадльдс. Я им не злоупотребляю. А когда нужно в попыхах перекусить, то это лучше бем пирожок неизвестного качества или наши забегаловки.
В Америке и в Москве МакДональдс — это небо и земля.
Здравствуйте, vstrogov, Вы писали:
V>Здравствуйте, VladD2, Вы писали:
VD>>Сдается мне, что сей труд написан на днях.
V>Нет, не на днях. Максим уже публиковал этот текст в английском переводе пару лет где-то назад на редмондовском V>форуме разработчиков драйверов (в частности в нем участвуют многие ключевые разработчики NT).
Здравствуйте, Дарней, Вы писали:
Д>Это оказалась очень хорошая иллюстрация к тому, что я хотел сказать Д>и это не первая ошибка в MSDN, на которую я натыкаюсь Д>и не первая ошибка, которую помог бы избежать C++ (при его грамотном применении, конечно)
Во-во...
Так лучше будет(я понятия не имею что этот код делает. просто тупо перебил его на враперы.)
#include <windows.h>
#include <winbase.h>
#include <initguid.h>
#include <ole2.h>
#include <mstask.h>
#include <msterr.h>
#include <wchar.h>
#include <util/co_smart_ptr.h>
//содержимое co_smart_ptr.h
//#pragma once
//#include "smart_ptr.h"
//inline void p_add_ref(IUnknown* ptr_)
//{
// ptr_->AddRef();
//}
//inline void p_release(IUnknown* ptr_)
//{
// ptr_->Release();
//}
//те у меня одни и теже смартпоинтеры на все классы с внутренним подсчетом ссылок...#include <boost/noncopyable.hpp>
struct com_initialize
:boost::noncopyable
{
com_initialize(LPVOID pvReserved=NULL)
{
hr=CoInitialize(pvReserved);
}
~com_initialize()
{
if(SUCCEEDED(hr))
CoUninitialize();
}
operator HRESULT()
{
return hr;
}
private:
HRESULT hr;
};
int main(int argc, char **argv)
{
com_initialize com_init;
if(FAILED(com_init))
return 1;
HRESULT hr=S_OK;
///////////////////////////////////////////////////////////////////
// Call CoInitialize to initialize the COM library and then
// CoCreateInstance to get the Task Scheduler object.
///////////////////////////////////////////////////////////////////
ref_t<ITaskScheduler> pITS;
hr=CoCreateInstance
(CLSID_CTaskScheduler
,NULL
,CLSCTX_INPROC_SERVER
,IID_ITaskScheduler
,(void **)ref_accept(pITS)
);
if (FAILED(hr))
return 1;
///////////////////////////////////////////////////////////////////
// Call ITaskScheduler::Activate to get the Task object.
///////////////////////////////////////////////////////////////////
ref_t<ITask> pITask;
LPCWSTR lpcwszTaskName=L"Test Task";
hr=pITS->Activate
(lpcwszTaskName
,IID_ITask
,(IUnknown**)ref_accept(pITask)
);
if (FAILED(hr))
{
wprintf(L"Failed calling ITaskScheduler::Activate: ");
wprintf(L"error = 0x%x\n",hr);
return 1;
}
///////////////////////////////////////////////////////////////////
// Call ITask::CreateTrigger to create new trigger.
///////////////////////////////////////////////////////////////////
ref_t<ITaskTrigger> pITaskTrigger;
WORD piNewTrigger;
hr = pITask->CreateTrigger
(&piNewTrigger
,ref_accept(pITaskTrigger)
);
if (FAILED(hr))
{
wprintf(L"Failed calling ITask::CreatTrigger: ");
wprintf(L"error = 0x%x\n",hr);
return 1;
}
//////////////////////////////////////////////////////
// Define TASK_TRIGGER structure. Note that wBeginDay,
// wBeginMonth, and wBeginYear must be set to a valid
// day, month, and year respectively.
//////////////////////////////////////////////////////
TASK_TRIGGER pTrigger;
ZeroMemory(&pTrigger, sizeof (TASK_TRIGGER));
// Add code to set trigger structure?
pTrigger.wBeginDay =1; // Required
pTrigger.wBeginMonth =1; // Required
pTrigger.wBeginYear =1999; // Required
pTrigger.cbTriggerSize = sizeof (TASK_TRIGGER);
pTrigger.wStartHour = 13;
pTrigger.TriggerType = TASK_TIME_TRIGGER_DAILY;
pTrigger.Type.Daily.DaysInterval = 1;
///////////////////////////////////////////////////////////////////
// Call ITaskTrigger::SetTrigger to set trigger criteria.
///////////////////////////////////////////////////////////////////
hr = pITaskTrigger->SetTrigger (&pTrigger);
if (FAILED(hr))
{
wprintf(L"Failed calling ITaskTrigger::SetTrigger: ");
wprintf(L"error = 0x%x\n",hr);
return 1;
}
///////////////////////////////////////////////////////////////////
// Call IPersistFile::Save to save trigger to disk.
///////////////////////////////////////////////////////////////////
ref_t<IPersistFile> pIPersistFile;
hr = pITask->QueryInterface
(IID_IPersistFile
,(void **)ref_accept(pIPersistFile)
);
hr = pIPersistFile->Save
(NULL
,TRUE
);
wprintf(L"The trigger was created and IPersistFile::Save was \n");
wprintf(L"called to save the new trigger to disk.\n");
return 0;
}
... << RSDN@Home 1.1.3 beta 1 >>
Пусть это будет просто:
просто, как только можно,
но не проще.
(C) А. Эйнштейн
Здравствуйте, WolfHound, Вы писали:
WH>Так лучше будет(я понятия не имею что этот код делает. просто тупо перебил его на враперы.)
вот и я когда с этим безобразием (TaskScheduler API) столкнулся, первым делом врапперы понаделал
потому что использовать эти функции как есть — это проще повеситься будет
Здравствуйте, alexkro, Вы писали:
A>Здравствуйте, vstrogov, Вы писали:
V>>Здравствуйте, VladD2, Вы писали:
VD>>>Сдается мне, что сей труд написан на днях.
V>>Нет, не на днях. Максим уже публиковал этот текст в английском переводе пару лет где-то назад на редмондовском V>>форуме разработчиков драйверов (в частности в нем участвуют многие ключевые разработчики NT).
A>Ссылочку пожалуйте.
Когда-то давно эти форумы поддерживались Rational как разработчиком одной из серьезнейших файловых систем для NT для ClearCase, с 2000 поддерживаются Open Systems Resources. Де факто мониторят и принимают участие многие ключевые разработчики режима ядра MS.
Здравствуйте, VladD2, Вы писали:
VD>Здравствуйте, Shhady, Вы писали:
S>>Я конечно не использую dynamic_cast, темплейтов и эксепшенов, и очень доволен, и использовать не хочеться.
VD>И очень зря. Чертовски полезные вещи. Хотя исключения сделаны (особенно в компиляторах МС) не очень толково. Но уж шаблоны не использовать работая с КОМ-ом — это верх мазохизма. Все же ATL непропьеш.
Ошибся, я использую темплейты только в виде смарт поинтов внутри реализации ATL не использую, стараюсь писать всё самому, чтоб держать всё под контролем ( я просто собаку сЪел, офигивая, почему моя программа глючила, оказалось что глючил mfc со своими недокументированными фичами и ограничениями ( перепишите отрисовку в производном классе от CButton ( или от чего-то там, не помню ), офигенное поведение обеспечено ). Исключения то же юзаю, но по маленькому и чтоб они не вырывались за пределы класса. Но я это всё использую по минимуму и не фигачу метапрограммирование.
"Man feed machine
Machine feed man"
Peter Gabriel — OVO — The Tower That Ate People
Здравствуйте, VladD2, Вы писали:
VD>Ты будешь смеяться, но в 2001 Шарпа тоже небыло. Он появился в 2002. _>>смешно.. _>>я лично программировал в начале 2001 на C# (Beta 2) VD>Значит должен знать, что такое DNA и какие ограничения на треп оно распростроняет. VD>Я программировал еще на пре бете и на бэте 1. И именно по этому могу скзать, что вероятность появления этих слов в 2001 стремится к нулю.
я не понял что ты имеешь в виду — человек писал, что в 2001 C# не было, а я писал, что был.
_>>более того, я использовал С# код, созданный другим разработчиком в 2000
VD>Ну, прям прозводсво каое-то. Хорошо что ты не программировал на супер продукте под названием COM+: VD>http://www.microsoft.com/msj/1197/complus.aspx VD>http://www.microsoft.com/msj/1297/complus2/complus2.aspx VD>
Здравствуйте, Maxim S. Shatskih, Вы писали:
MSS>Похоже, что сначала придумали ОО и Си++ — то есть "как сделать то же самое, но через зад, с кучей лишнего и в шизанутом синтаксисе" — а тут же возникла нужда в рефакторинге. Энтропии в ОО языках больше, чем в Си.
Я так понял это наезды вобще на высокоуровневые технологии и ООП.
Хорошо. Может обсудим надежность во такой вот функции, которая торчала из одной библиотеки.
int MtGetLastMail( const int handle, char * path, int *lenofpath );
Получения имени файла, в который было записано пришедшее с сервера письмо.
handle – ....
path – строка символов для приёма имени файла;
lenofpath – адрес переменной типа int, в которой записана длина приёмной строки.
Если имя файла (включая завершающий ноль) больше, чем приёмная строка,
то в приёмную строку записывается строка нулевой длины, а в переменную
по адресу lenofpath записывается длина строки, необходимая для приёма имени файла.
Возвращает код возврата.
И ее высокоуровневый аналог [b]со скрытым поведением
string GetLastMal() — Все! больше ничего не надо. Ошибки через иключения плевать. А handle инкапсулирован в классе.[/b]
Так какая конструкция подходит для серьезных проектов?
По поводу документации: описание этой функции очень неполное, как минимум раз в 5 его побольше надо было сделать там где описан процесс возврата строки. Можно конечно сказать что у прграммистов руки были кривые ктороые это писали, но к чему эти разговоры если тогда у 90% разработчиков руки кривые.
В вызове этой фукции как минимум десяток потенциальных багов может случиться. С длинами буферов итд.
Хотя тут скрытого поведения нету. Вот поэтому крупный софт и глючный на основе низкоуровневых технологий (без скрытого поведения), и лезут через инет на комп всякие черви через всякие щели.
Здравствуйте, Maxim S. Shatskih, Вы писали:
SS>Прятать мелочи — глупо. Баги будут именно в них. The devil is in the details. Потому имеет смысл выставить эти детали бесстыдно наружу, чтобы быстрее баг увидеть, если он там есть.
Ага. Чтобы чаще об них спотыкаться. Лучше один раз сделать чтобы бага не было и спрятать от греха подальше.
Здравствуйте, WolfHound, Вы писали:
WH>Вот тут то и нужен компаил тайм рефлекшен. Чтобы то что нужно я мог сгенерить прямо во время компиляции и именно так как мне надо. А если мне понадобится метаинформация в рантайме то я мог бы ее вытащить причем только для тех классов для которых она мне нужна и ровно столько сколько мне нужно. WH>Единственный адекватный способ создать такой язык это проектирование его с нуля и при этом забив на обратную совместимость с С/С++.
Ну как бы R# уже сейчас показывает что это не обязательно.
Здравствуйте, Maxim S. Shatskih, Вы писали:
MSS>Абстракции там получаются очень крупноблочные, скорее как в COMе, а не как в классических ОО языках типа Дельфей, Джавы и Шарпа.
Компонентная модель дотнета в разы более абстрактна нежели СОМ
Здравствуйте, alexkro, Вы писали:
VD>>Не, а мне нравится макдонадльдс. Я им не злоупотребляю. А когда нужно в попыхах перекусить, то это лучше бем пирожок неизвестного качества или наши забегаловки.
A>В Америке и в Москве МакДональдс — это небо и земля.
Кстате, смотрю вы пропагандирует C#, а как насчет производительности? Мы ж вроде в России, и дофига компов с максимум 800 мегагерцовыми пнями ( и это в офисах многих фирм ).
"Man feed machine
Machine feed man"
Peter Gabriel — OVO — The Tower That Ate People