Здравствуйте, Roman Odaisky, Вы писали:
RO>2. const справа позволяет избежать непонимания в случае «const T @ @ something», где «@» — «*» или «&». Сам видел «const T* &something». Что хотели написать и что получилось? То ли дело «T const* & something» или «T * const& something».
В чем разница между "const T * &" и "T const * &"?
RO>3. Приклеивать «*» и «&» к имени — глупо. Ясно, что с обоими пунктуаторами нужно поступать одинаково, но, в то время как «X *x» еще имеет смысл («*x имеет тип X»), запись «X &x» его лишена.
Глупо приколупываться к подобным мелочам и уделять им столь повышенное внимание.
RO>Так что «std::string const& in». Оно и читается удобнее, когда самое важное находится по краям строки, но это уже субъективно. Вроде такого: RO>
RO>ns::foo s = getSomeFoo();
RO>ns::bar t;
RO>ns2::quux u;
RO>const ns::foo v = getSomeFoo()
RO>const ns2::bar w = getSomeBar()
RO>ns::quux x = getSomeQuux();
RO>ns2::quuux y;
RO>ns2::quuuux z = getSomeQuuuux();
RO>
Здесь, по-моему, const только отвлекают внимание.
RO>
RO>ns::foo s = getSomeFoo();
RO>ns::bar t;
RO>ns2::quux u;
RO>ns::foo const v = getSomeFoo()
RO>ns2::bar const w = getSomeBar()
RO>ns::quux x = getSomeQuux();
RO>ns2::quuux y;
RO>ns2::quuuux z = getSomeQuuuux();
RO>
А вот так куда лучше.
А по моему все с точностью до наоборот.
SObjectizer: <микро>Агентно-ориентированное программирование на C++.
Здравствуйте, Alxndr, Вы писали:
RO>>>>Я не доверяю гайдам, которые пишут «const string &in». A>[] RO>>Разве ты не видишь в этом ни одной — объективной — ошибки? A>"Объективной" -- ну, я не вижу :???:
Если хорошо подумать, то единственный правильный способ написать это — «std::string const& in».
Потому что:
1. «std::» — надеюсь, понятно.
2. const справа позволяет избежать непонимания в случае «const T @ @ something», где «@» — «*» или «&». Сам видел «const T* &something». Что хотели написать и что получилось? То ли дело «T const* & something» или «T * const& something».
3. Приклеивать «*» и «&» к имени — глупо. Ясно, что с обоими пунктуаторами нужно поступать одинаково, но, в то время как «X *x» еще имеет смысл («*x имеет тип X»), запись «X &x» его лишена. Так что «X* x» и «X& x». Пробелы с обеих сторон, как правильно заметили, придают объявлению вид выражения:
template <class Archive>
void serialize(Archive& archive, unsigned const version)
{
archive & m_something; // это что?
Archive & oops; // а вот это?
}
Пробелы разве что полезны тогда, когда объявление многоуровневое, вроде X * const* * * const* * x. (А typedef еще полезнее. :-)
Так что «std::string const& in». Оно и читается удобнее, когда самое важное находится по краям строки, но это уже субъективно. Вроде такого:
ns::foo s = getSomeFoo();
ns::bar t;
ns2::quux u;
const ns::foo v = getSomeFoo()
const ns2::bar w = getSomeBar()
ns::quux x = getSomeQuux();
ns2::quuux y;
ns2::quuuux z = getSomeQuuuux();
Здесь, по-моему, const только отвлекают внимание.
ns::foo s = getSomeFoo();
ns::bar t;
ns2::quux u;
ns::foo const v = getSomeFoo()
ns2::bar const w = getSomeBar()
ns::quux x = getSomeQuux();
ns2::quuux y;
ns2::quuuux z = getSomeQuuuux();
Главное — не забывать, что этот документ (как и все документы подобного рода) пишется, исходя из конкретной ситуации, в которой находились писавшие, поэтому слепо брать подобные документы в свой проект просто потому, что это Google/MS/whatever, нельзя, потому что в твоем проекте ситуация наверняка будет другая.
эх, у меня когда-то мечта была, в гугл попасть, даже пытался туда устроиться- но на собеседование даже не пригласили..
если бы я знал их кодестайл, мне бы это столько времени бы сыкономило
Они же написали внизу, почему. Они должны поддерживать существующий код, не обеспечивающий exception safety. И в этом они правы: исключения нужно использовать или везде, или нигде.
Здравствуйте, Erop, Вы писали:
E>Здравствуйте, jazzer, Вы писали:
E>>>Интересно, а как они с RAII при этом рабоьают? Неудобно же. J>>А RAII никуда не делась. Просто вместо исключений E>Да ясно, что никуда не делось. Но ведь правда неудобно
неудобно, но все же лучше, чем в какой-нть джаве, где исключения есть, а RAII нет
Здравствуйте, jazzer, Вы писали:
J>неудобно, но все же лучше, чем в какой-нть джаве, где исключения есть, а RAII нет
Уж лучше исключения + GC без RAII чем с кодами возврата жить.
Тем более что есть try/finally а в C# вобще using не сильно хуже RAII получается.
А я сейчас додумываю метод управления жизнью критичных объектов (за не критичными пусть GC смотрит) более гибкий и эффективный чем RAII.
Но это конечно уже не для С++.
... << RSDN@Home 1.2.0 alpha rev. 745>>
Пусть это будет просто:
просто, как только можно,
но не проще.
(C) А. Эйнштейн
Здравствуйте, WolfHound, Вы писали:
WH>Кешь не обновляют. WH>Никогда. WH>Его инвалидируют.
Вот это ты классно! Одним. Словом. Всю статью разбил. Смешно просто. У тебя установка такая, не принимать аргументы собеседников не при каких условиях? "Кэш не обновляют, а другое решение ваще не масштабируется, поэтому нигде ничего откатывать не нужно, и не приводите мне ваших сферосценариев в вакууме!" Тяжелый случай.
Здравствуйте, Roman Odaisky, Вы писали:
RO>Задача. Добавить элемент в два хранилища. Обе операции добавления могут завершиться неудачей. Обеспечить строгую гарантию. RO>Вариант. То же для N хранилищ.
Это не задача.
Это решение.
... << RSDN@Home 1.2.0 alpha rev. 745>>
Пусть это будет просто:
просто, как только можно,
но не проще.
(C) А. Эйнштейн
Здравствуйте, remark, Вы писали:
E>>Феерический бред.
R>Полностью поддерживаю. Это похоже на мнение человека, который 10 лет писал на С, а потом увидел исключения, и попытался их использовать как будто это ещё один способ локальной передачи управления, аналогичный while/if/goto.
Ты собираешься спорить с тем что исключения это ещё один способ передачи управления? Только у while/if и прочих есть скобочки и их видно, а пролетающее мимо исключение ни хрена не видно.
У goto и исключений много общего. Обоих не видно читая код, и оба отнюдь не локальная передача управления, а вполне себе глобальная. Именно из-за этих свойств goto не рекомендуется к использованию. Исключения некоторые рекомендуют, хотя от goto они отличаются только тем шо аккуратнее обходятся с данными на стеке (зовёт деструкторы), и ещё тем шо переход выполняется не на метку а Х3 куда.
Я использую C++ исключения только в "одноразовых" проектах (особенно удобно для работы с COM), но никогда в production-системах.
Да, приходится постоянно писать if(FAILED(hr)), это минус.
Зато уже при написании следующей строчки приходится думать, что же надо в этом случае делать: какие ресурсы освобождать, надо ли извещать пользователя и если надо то как, что писать в лог, или может просто вернуть код ошибки выше и обрабатывать его там, и т.п. И вот решение подобных вопросов очень полезно и для качества кода, для качества продукта.
R>Не говоря уже о том, что в Java/C# такой подход вообще не будет работать, т.к. потенциально практически каждая строчка кода бросает исключения.
В этом форуме речь про C++, большая часть людей использует C++ шоб писать native code. В Java/C# пускай бросают (всё равно приходится ловить и обрабатывать исключения брошенные соответственно JRE/.NET), сам в обоих языках и бросал, и ловил.
Здравствуйте, Roman Odaisky, Вы писали:
RO>>>>>Я не доверяю гайдам, которые пишут «const string &in». A>>[] RO>>>Разве ты не видишь в этом ни одной — объективной — ошибки? A>>"Объективной" -- ну, я не вижу
RO>Если хорошо подумать, то единственный правильный способ написать это — «std::string const& in».
Роман, если хорошо подумать, то все "единственно правильные способы" идут нафиг, оставляя без внимания возможные "доказательства".
Здравствуйте, WolfHound, Вы писали:
WH>Здравствуйте, jazzer, Вы писали:
J>>Это только если все в одном месте. J>>Если нужны промежуточные шаги — все, получится куча вложенных скобок, правильно? WH>У тебя такой код вобще бывает?
Бывает, сплошь и рядом (не с файлами, конечно ).
WH>Вот у меня нет. WH>Один максимум 2 файла за раз открывать приходится.
не, файлы, конечно, ты вряд ли больше чем два в одной функции открывать будешь, но что, у тебя программы только файлами занимаются?
WH>Так что Имею Мнение Хрен Оспоришь что польза от RAII при наличии GC мягко говоря приувеличина.
RAII используется в первую очередь для отката (с конкретными временными рамками, а именно — область видимости) какого-то действия, и захват ресурса — это только одна из разновидностей подобных действий, а уж захват памяти, от которого помогает GC — это еще меньшее подмножество подобных действий.
Так что GC и RAII несколько ортогональны, хотя в области конкретно управления памятью они могут использоваться более-менее взаимозаменяемо (в определенных рамках, естественно, связанных с деструкторами, поскольку, так уж получилось, освобождение памяти и смерть объекта обычно взаимосвязаны).
Здравствуйте, WolfHound, Вы писали:
WH>Здравствуйте, jazzer, Вы писали:
J>>Ну вот у меня в системе летают сообщения, и в программе есть некий state, который обновляется с приходом разнообразных сообщений (т.е. мы добавили элемент в контейнер А, изменили статистику в объекте В, нашли объект в контейнере С и в контейнере, который в нем, удалили какой-то элемент, и так далее, куча действий на разных уровнях). J>>Но сообщения могут быть ошибочными по той или иной причине, и такие сообщения должны игнорироваться. J>>Игнорироваться — это значит, что state после их прихода должен быть таким, как будто ничего не приходило вообще. J>>Причем проверка сообщения — вещь многоуровневая, в одну функцию на входе ее не запихнешь, да и дорого это и неудобно — мы хотим оптимизировать по скорости сценарий, когда сообщение корректное. J>>Т.е. ты начинаешь делать какие-то действия, предполагая, что с сообщением все хорошо, а если где-то дальше по стеку что-то не так — откатываешь свои изменения. WH>Какой то сферосценарий в вакууме. WH>Причем даже по этому описанию видно что данное решение ваще не масштабируется. WH>Те ты даже пользу от SMP получить не сможешь. WH>Про кластер я вобще молчу.
ну тебе, безусловно, по этим пяти строчкам, написанным для демонстрации возможностей RAII, видно, что вся система у меня не масштабируется
И главное, мы так лихо сменили тему разговора...
J>>Другой пример — загрузка иерархического конфига, когда ошибка в конфиге должна привести к "незагрузке" только этой маленькой ветки, а все остальное должно загрузиться — начинаешь парсить и грузить все в память, создавать всякие деревья и прочее, а в какой-то момент, глубоко в стеке, раз — и опаньки, надо ветку, которая вызвала ошибку, не загружать, лишь ругнуться в лог, и продолжить загрузку дальше, как будто ошибочного текста не было вообще. WH>В случае с GC все более чем тривиально. WH>Просто весь этот недогрузившийся мусор подберет GC.
для этого на недогрузившийся мусор должны пропасть все внешние ссылки — они каким образом будут пропадать?
Вот ты свой недогрузившийся мусор (ты просто еще не знаешь, что это мусор, ибо so far so good) положил в контейнер, работаешь дальше, вызываешь разнообразные функции, и тут из недр стека к тебе прилетело исключение — какую-то лажу мы грузим тут — и что, как тебе GC поможет удалить добавленный элемент из контейнера?
J>>короче, транзакционность по отношению к возникновению исключения: если при обработке события возникло исключение, то надо сделать так, будто такого события не было вообще в природе (разве что в логе). WH>Завист от задачи. WH>Очень сильно зависит.
да никак не зависит. Транзакционность функции — очень узкая задача (RAII существует только в контексте функции, даже еще уже — в контексте области видимости). Никакие более высокоуровневые вещи RAII сама по себе решить не может, как их не может решить ни одно локально применимое средство языка.
J>>да не зависит. WH>Правда? J>>транзакция — это действия по изменению + действия по коммиту либо действия по откату. J>>И вот для автоматизации этих действия как раз RAII?и используется. WH>А как насчет распределенных транзакций по нескольким персистентным хранилищам каждое из которых может отрубиться в любой момент?
Ну так это ты мне расскажи, как у тебя и что, желательно с выдержками из кода. А то получаются сферохранилища
Как я могу рассуждать о твоей системе, если я о ней понятия не имею? (Хотя ты вот о моей отлично смог.)
Хотя, если ты мне расскажешь, что такое распределенное исключение, то, может, я и отвечу на твой вопрос.
WH>Как мне поможет RAII если у меня процесс с этим самым RAII сдох посреди транзакции?
Я понятия не имею, как у тебя организован message flow, и как ты узнаешь о том, что процесс сдох, каким образом осуществляются у тебя распределенные транзакции, как у тебя организована обработка некорректных сообщений (если, например, админы сглючили с настройкой роутинга и к тебе в систему попал левый широковещательный трафик, или с консоли телнетом кто-то послал "почти правильное сообщение"), и т.д, и т.п, так что, воспользовавшить любезно предоставленным тобой эпитетом "сферосценарий в вакууме", предположу, что никак, и напомню, что мы говорим о транзакции в пределах, в которых действует RAII, так что твой вопрос эквивалентен вопросу "как мне в этом поможет цикл for/тип double/делегаты C#". Ответ — напрямую никак, слишком низкоуровневое средство.
Более того, даже если RAII не помогает в осуществлении распределенных транзакций (хотя в случае распределенных в вакууме сферотранзакций оно точно помогает ), из этого все равно не следует то, что оно не помогает во всех остальных сферосценариях.
J>>Это я понял, не понял лишь, зачем ты так насильственно сужаешь область применения RAII. WH>За тем что не вижу смысла применять это для чегото другого. WH>Можно попробовать меня переубедить. WH>Только должны быть аргументы. WH>Пока я ничего не вижу.
Не надо брать меня на понт этими рублеными фразами
Это неконструктивно.
Тебе несколько раз уже продемонстрировали, как именно RAII работает в ситуациях, не связанных с управлением критичными ресурсами.
Причем продемонстрировали люди, которые пользуются этим в своей работе, и очень довольны.
Я понимаю, что в управляемых языках полноценного (т.е. автоматического) RAII нету, но есть другие автоматические вещи (GC), так что идиомы программирования там совсем другие (что естественно), но вот в С++ у нас есть полноценный автоматический RAII и мы им пользуемся в полный рост для всего, чего угодно. И если бы вдруг GC взял на себя все вопросы с управлением памятью объектов из кучи, область применения RAII уменьшилась бы совсем ненамного.
P.S. Что бы у тебя там ни было распределенное, все равно все сводится к одиночным процессам и к функциям и данным, которые работают в контексте одного процесса. То, что они, работая сообща, могут реализовать функционал для распределенных транзакций, ни для кого не секрет, но все равно куча кода у тебя работает внутри одного процесса и не имеет дела с распроделенными высями. Зачем при написании этого кода отказываться от возможностей, предоставляемых языком, и искуственно ограничивать область применения до управлением памятью в куче...
Здравствуйте, CTpaHHoe, Вы писали:
CTH>Здравствуйте, night beast
CTH>после беглого прочтения не понял следующего
>>> If you actually need pointer semantics, scoped_ptr is great. You should only use std::tr1::shared_ptr under very specific conditions, such as when objects need to be held by STL containers. You should never use auto_ptr.
>>> Use streams only for logging.
CTH>чем им не угодили потоки и auto_ptr?
Это просто 3.14здец какой-то! shared_ptr under very specific conditions? Тогда как shared_ptr в разы увеличивает надежность кода. А scoped_ptr существенно ограничен по применению. Как они собираются возвращать указатель из функции, например? Единственный разумный ответ в такой ситуации — как голый указатель. А вся мощь smart pointer'ов осталась за бортом.
Поэтому я не могу терпеть большинство coding stadards. Какой-нибудь полоумный architect их напишет, который сам в последний раз что-либо новое про C++ узнал году так в 95-м. Про shared_ptr он услышал от вчерашнего студента (спасибо студенту, а так бы вообще не услышал), и подумал: "не-не-не, Дэвид Блэйн! Only under very specific conditions!"
auto_ptr — действительно в топку, когда у тебя есть shared_ptr.
Лично мне Air Vehicle C++ Coding Standards пока что кажется наиболее вменяемым (из того, что я видел, естественно).
Опять таки, бесполезно листать его, не учитывая предметную область (hard real-time, avionics).
Здравствуйте, Sni4ok, Вы писали:
S>Здравствуйте, night beast, Вы писали:
NB>>Google C++ Style Guide
S>эх, у меня когда-то мечта была, в гугл попасть, даже пытался туда устроиться- но на собеседование даже не пригласили.. S>если бы я знал их кодестайл, мне бы это столько времени бы сыкономило
Думаю, что в Гугл нужны люди, которых заботит не кодинг стайл, а решение проблем. Какая на фиг разница, как писать? Заботиться о кодинг стайле — изощренная форма отлынивания. Писать надо так, как команда пишет. Если команды нет — так, как нравится, но одинаково.
It's kind of fun to do the impossible (Walt Disney)
Здравствуйте, jazzer, Вы писали:
L>>Это опасно. Тут есть народ, который до сих пор при виде шаблонов в обморок падает J>Погоди, похоже, мы о разных книгах говорим. J>Я имею в виду их совместную книгу "Стандарт программирования С++" или как-то так, в общем, они не про шаблоны и прочее, а про самые банальные вещи говорят. J>Очень полезная книжка для командной работы, вот тебе бы она как раз пригодилась в борьбе с твоим занудным соседом.
Да все о том же. Определенными авторами и их произведениями неокрепших программистов можно напугать до смерти. Вот тут как раз такой случай
Здравствуйте, Sergey, Вы писали:
>> А смесь пробелов и табуляции -- это вообще как свидетельство того, что >> человек не владеет инструментами, которыми пользуется (не способен >> настроить свой редактор/IDE).
S>А я вот вполне осознанно пробелы с табуляцией мешаю Не знал, что это S>может кого-то бесить...
Не подскажете, в каких случаях это может пригодиться? Как именно расставляются пробелы и табуляции, систематически?
Дело в том, что если их расставлять как попало, то кому-то другому, который будет смотреть этот код, придётся временно выставить размер табуляции в тот, который использовался при написании кода, что бывает не удобно.
Здравствуйте, WolfHound, Вы писали:
WH>Здравствуйте, jazzer, Вы писали:
J>>неудобно, но все же лучше, чем в какой-нть джаве, где исключения есть, а RAII нет WH>Уж лучше исключения + GC без RAII чем с кодами возврата жить. WH>Тем более что есть try/finally а в C# вобще using не сильно хуже RAII получается.
ну, на мое имхо — сильно хуже, потому что в RAII деструкторы регистрируются по мере добавления, а с finally их наод в одном месте все создавать, флажки всякие заводить, нужно откатывать или не нужно, и все такое. С RAII это все автоматом, пишешь и не думаешь ни о чем, можешь в любой момент в любом порядке все пеетасовать.
Здравствуйте, jazzer, Вы писали:
J>Это только если все в одном месте. J>Если нужны промежуточные шаги — все, получится куча вложенных скобок, правильно?
У тебя такой код вобще бывает?
Вот у меня нет.
Один максимум 2 файла за раз открывать приходится.
Так что Имею Мнение Хрен Оспоришь что польза от RAII при наличии GC мягко говоря приувеличина.
... << RSDN@Home 1.2.0 alpha rev. 745>>
Пусть это будет просто:
просто, как только можно,
но не проще.
(C) А. Эйнштейн
Здравствуйте, jazzer, Вы писали:
J>Бывает, сплошь и рядом (не с файлами, конечно ).
А с чем?
J>не, файлы, конечно, ты вряд ли больше чем два в одной функции открывать будешь, но что, у тебя программы только файлами занимаются?
Не только.
Но критичных ресурсов все так же мало.
Раз два и обчелся.
J>RAII используется в первую очередь для отката (с конкретными временными рамками, а именно — область видимости) какого-то действия, и захват ресурса — это только одна из разновидностей подобных действий,
Пример в студию.
J>а уж захват памяти, от которого помогает GC — это еще меньшее подмножество подобных действий.
Чё? Да это 99% случаев использования RAII если не больше.
... << RSDN@Home 1.2.0 alpha rev. 745>>
Пусть это будет просто:
просто, как только можно,
но не проще.
(C) А. Эйнштейн
Здравствуйте, jazzer, Вы писали:
E>>У желающих возражать есть выбор:
E>>1. Либо сопровождать код вида: E>>
E>>call_function_with_very_long_name( first_argument,
E>> call_another_function_for_second_argument( param1,
E>> call_yet_another_function() ),
E>> some_expression * as / third - argument );
E>>
E>>2. Застрелиться!
J>стреляться не хочу, так что выбираю сопровождать
J>а ты-то что предлагаешь для повышения читабельности?
Ну я давно пользуюсь своей нотацией, которая была выработана за 6 или 7 лет использования других нотаций до этого. Но и она сейчас мне кажется несколько жесткой, кое-чего там можно упростить, да руки не доходят.
Приведенный выше пример я бы переписал с использованием двух простых правил:
— аргументы функции пишутся либо на одной строке все, либо каждый аргумент на своей строке;
— перенесенная часть выражения сдвигается на две табуляции:
call_function_with_very_long_name(
first_argument,
call_another_function_for_second_argument(
param1,
call_yet_another_function() ),
some_expression * as / third - argument );
Чтобы не быть голословным, вот пример из проекта, который я пишу прямо сейчас:
Можешь попробовать отформатировать данный фрагмент в соответствии с рекомендациями Романа и посмотреть, что получится (при этом нужно еще уместиться хотя бы в 80 символов ширины текста).
SObjectizer: <микро>Агентно-ориентированное программирование на C++.
Здравствуйте, WolfHound, Вы писали:
ЮЖ>>Это и есть конкретика — "добавить указатель в контейнер, при невозможности — удалить". Может быть это сфероконь, но мне интересен метод решения именно этой задачи. WH>В системе с ГЦ такой задачи просто нет.
Задача. Добавить элемент в два хранилища. Обе операции добавления могут завершиться неудачей. Обеспечить строгую гарантию.
К>>В целом несомненный зачот, правда несколько пунктов не очень. К>>define guard — это потому шо убогие компиляторы не знают pragma once L>Интересно, если сравнить два компилятора, один тот самый, который про эту прагму знает с младенчества, но доступен по сути только для одной платформы, и другой, который не знает, зато существует для практически любой платформы, какой из них следует называть убогим?
Если "тот самый" это MSDEV то он компилирует под десятки платформ (win32/64, всякие ARMы с WinMobile, Alpha, MIPS, PowerPC, оба Xbox-а, Zune, и т.п.).
А если "другой" это GCC, то ты ж сам написал шо он тоже знает
L>Что не отменяет факта, что какой-то код нужно будет компилировать под нечто, для чего существует ровно один компилятор, который, сюрприз, не в курсе про какие-то там прагмы?
Интересно, сколько процентов разработчиков пишут что-то на C++ под платформы, куда не компилит ни MSDEV ни GCC?
L>Для человека наибольшая комфортная ширина строки текста — примерно 66 символов. Видел когда-нибудь газету, где полосы занимали бы всю ширину листа? Как думаешь, почему?
Думаю потому шо небольшая заметка из пары длинных строк смотрится хреновей, чем такая же "квадратная".
Ещё потому, что газеты печатают на бумаге большого размера, а читают где ни попадя — поэтому горизонтальный скроллинг заключается в нетривиальных манипуляциях с газетой: думаю, постоянно её перескладывать надоест уже строчке на пятой.
BTW в коде который я пишу строки длиннее 80 символов почти исключительно комментарии — полстраницы комментов IMO портят читаемость кода, несмотря на подсветку (особенно если эти полстраницы пишутся не для людей, а для роботов вроде doxygen).
К>>Всё остальное — ППКС! Особенно про исключения и RTTI. L>Каменный век
Про исключения — http://www.joelonsoftware.com/items/2003/10/13.html
RTTI IMHO просто бесполезен, как и например виртуальное наследование, и ещё пара конструкций языка.
A>Это просто 3.14здец какой-то! shared_ptr under very specific conditions? Тогда как shared_ptr в разы увеличивает надежность кода. А scoped_ptr существенно ограничен по применению. Как они собираются возвращать указатель из функции, например? Единственный разумный ответ в такой ситуации — как голый указатель. А вся мощь smart pointer'ов осталась за бортом.
передаёшь scoped_ptr по ссылке, и нет проблем, хотя согласен, что scoped_ptr, что shared_ptr хороши лишь для внутреннего использования в своём коде,
для какого-нить общего апи они ниподходят никак(поскольку навязывают программисту способ использования, а это стиль какой-нить явы, но не плюсов), поскольку не позволяют освобождать указатель от своего владения, а вот auto_ptr в этом случае вполне применим.
A>Поэтому я не могу терпеть большинство coding stadards. Какой-нибудь полоумный architect их напишет, который сам в последний раз что-либо новое про C++ узнал году так в 95-м. Про shared_ptr он услышал от вчерашнего студента (спасибо студенту, а так бы вообще не услышал), и подумал: "не-не-не, Дэвид Блэйн! Only under very specific conditions!"
A>auto_ptr — действительно в топку, когда у тебя есть shared_ptr.
на такой поток сознания даже и отвечать не хочется.
Здравствуйте, eao197, Вы писали:
E>Здравствуйте, Erop, Вы писали:
E>>Интересно, а как они с RAII при этом рабоьают? Неудобно же.
E>Надо полагать, что они практикуют двух-фазную инициализацию объектов. Простой конструктор + все действия в методе Init(), который уже возвращает код ошибки.
Где-то стараются так. Но где-то получается и не совсем так.
Когда разбирался в их libjingle накопилась пачка перлов типа такого:
if (proxy_.type) {
talk::AsyncSocket * proxy_socket = 0;
if (proxy_.type == talk::PROXY_SOCKS5) {
proxy_socket = new talk::AsyncSocksProxySocket(socket, proxy_.address,
proxy_.username, proxy_.password);
} else {
// Note: we are trying unknown proxies as HTTPS currently
proxy_socket = new talk::AsyncHttpsProxySocket(socket,
agent_, proxy_.address,
proxy_.username, proxy_.password);
}
if (!proxy_socket) {//!!! HOW CAN WE GET HERE???delete socket;
return 0;
}
socket = proxy_socket; // for our purposes the proxy is now the socket
}
Может показаться, что это код для старинного компилятора, который из new возвращает 0, но это не так. В частности поддерживается msvc2005.
Судите сами, что за гайд
Здравствуйте, Roman Odaisky, Вы писали:
RO>Здравствуйте, eao197, Вы писали:
E>>
E>>Exceptions
E>>▶ We do not use C++ exceptions.
E>>Сурово.
RO>Они же написали внизу, почему. Они должны поддерживать существующий код, не обеспечивающий exception safety. И в этом они правы: исключения нужно использовать или везде, или нигде.
Names and Order of Includes
▶ Use standard order for readability and to avoid hidden dependencies: C library, C++ library, other libraries' .h, your project's .h.
Забавно. Обычно, для избегания скрытых зависимостей рекомендуют как раз противоположный порядок включения заголовков.
The last good thing written in C was Franz Schubert's Symphony No. 9.
Здравствуйте, Roman Odaisky, Вы писали:
RO>Здравствуйте, eao197, Вы писали:
E>>
E>>Exceptions
E>>▶ We do not use C++ exceptions.
E>>Сурово.
RO>Они же написали внизу, почему. Они должны поддерживать существующий код, не обеспечивающий exception safety. И в этом они правы: исключения нужно использовать или везде, или нигде.
Нифига. Нужно просто суметь определить границу между кодом, использующим исключения и не использующим. Такой границей может быть, например, экспортируемые из DLL наружу функции.
Здравствуйте, jazzer, Вы писали:
J>Здравствуйте, landerhigh, Вы писали:
L>>Не читал. К сожалению, мне ее уже поздно читать J>В смысле, ты уже на плюсах не пишешь?
Нет. Просто что бы я не начинал читать, понимаю, что по всем этим граблям уже ходил-с и с автором категорически согласен
L>>Правда, толку от это очень мало — большинство современных программистов, с кем приходится иметь дело, не то что Александреску не читали, но и о том, кто такой Кнут, имеют очень смутное представление. L>>Могу попробовать сослаться на Александреску, но, боюсь, получу вопрос класса "а кто это?" J>лучше на Саттера — про него можно ответить, что это секретарь комитета по стандартизации С++ и один из главных в команде мелкософтовского компилятора (насчет второго могу ошибаться, правда).
Это опасно. Тут есть народ, который до сих пор при виде шаблонов в обморок падает
Здравствуйте, landerhigh, Вы писали:
L>Здравствуйте, jazzer, Вы писали:
J>>Здравствуйте, landerhigh, Вы писали:
L>>>Не читал. К сожалению, мне ее уже поздно читать J>>В смысле, ты уже на плюсах не пишешь? L>Нет. Просто что бы я не начинал читать, понимаю, что по всем этим граблям уже ходил-с и с автором категорически согласен J>>лучше на Саттера — про него можно ответить, что это секретарь комитета по стандартизации С++ и один из главных в команде мелкософтовского компилятора (насчет второго могу ошибаться, правда). L>Это опасно. Тут есть народ, который до сих пор при виде шаблонов в обморок падает
Погоди, похоже, мы о разных книгах говорим.
Я имею в виду их совместную книгу "Стандарт программирования С++" или как-то так, в общем, они не про шаблоны и прочее, а про самые банальные вещи говорят.
Очень полезная книжка для командной работы, вот тебе бы она как раз пригодилась в борьбе с твоим занудным соседом.
Здравствуйте, Erop, Вы писали:
E>Здравствуйте, landerhigh, Вы писали:
L>>Да все о том же. Определенными авторами и их произведениями неокрепших программистов можно напугать до смерти. Вот тут как раз такой случай E>Самокритично так выразился, респектуха
Подколол таки, чертяга
eao197 пишет:
> А смесь пробелов и табуляции -- это вообще как свидетельство того, что > человек не владеет инструментами, которыми пользуется (не способен > настроить свой редактор/IDE).
А я вот вполне осознанно пробелы с табуляцией мешаю Не знал, что это
может кого-то бесить...
Posted via RSDN NNTP Server 2.1 beta
Одним из 33 полных кавалеров ордена "За заслуги перед Отечеством" является Геннадий Хазанов.
_Jane_ пишет:
>> > А смесь пробелов и табуляции -- это вообще как свидетельство того, что >> > человек не владеет инструментами, которыми пользуется (не способен >> > настроить свой редактор/IDE). > > S>А я вот вполне осознанно пробелы с табуляцией мешаю Не знал, что это > S>может кого-то бесить... > > Не подскажете, в каких случаях это может пригодиться? Как именно > расставляются пробелы и табуляции, систематически?
Везде — табуляции, но при переносе части выражения на следующую иногда
приходится добивать пробелами.
> Дело в том, что если их расставлять как попало, то кому-то другому, > который будет смотреть этот код, придётся временно выставить размер > табуляции в тот, который использовался при написании кода, что бывает не > удобно.
Эта проблема появится не раньше, чем у нас в конторе заведётся человек,
который выставит размер табуляции отличный от 4 и начнёт на это
жаловаться. Пока таких не было.
Posted via RSDN NNTP Server 2.1 beta
Одним из 33 полных кавалеров ордена "За заслуги перед Отечеством" является Геннадий Хазанов.
Здравствуйте, WolfHound, Вы писали:
WH>Здравствуйте, jazzer, Вы писали:
J>>ну, на мое имхо — сильно хуже, потому что в RAII деструкторы регистрируются по мере добавления, а с finally их наод в одном месте все создавать, флажки всякие заводить, нужно откатывать или не нужно, и все такое. С RAII это все автоматом, пишешь и не думаешь ни о чем, можешь в любой момент в любом порядке все пеетасовать. WH>На жебе да не удобно. WH>А вот на C# вполне себе: WH>
Здравствуйте, jazzer, Вы писали:
J>Ну вот у меня в системе летают сообщения, и в программе есть некий state, который обновляется с приходом разнообразных сообщений (т.е. мы добавили элемент в контейнер А, изменили статистику в объекте В, нашли объект в контейнере С и в контейнере, который в нем, удалили какой-то элемент, и так далее, куча действий на разных уровнях). J>Но сообщения могут быть ошибочными по той или иной причине, и такие сообщения должны игнорироваться. J>Игнорироваться — это значит, что state после их прихода должен быть таким, как будто ничего не приходило вообще. J>Причем проверка сообщения — вещь многоуровневая, в одну функцию на входе ее не запихнешь, да и дорого это и неудобно — мы хотим оптимизировать по скорости сценарий, когда сообщение корректное. J>Т.е. ты начинаешь делать какие-то действия, предполагая, что с сообщением все хорошо, а если где-то дальше по стеку что-то не так — откатываешь свои изменения.
Какой то сферосценарий в вакууме.
Причем даже по этому описанию видно что данное решение ваще не масштабируется.
Те ты даже пользу от SMP получить не сможешь.
Про кластер я вобще молчу.
J>Другой пример — загрузка иерархического конфига, когда ошибка в конфиге должна привести к "незагрузке" только этой маленькой ветки, а все остальное должно загрузиться — начинаешь парсить и грузить все в память, создавать всякие деревья и прочее, а в какой-то момент, глубоко в стеке, раз — и опаньки, надо ветку, которая вызвала ошибку, не загружать, лишь ругнуться в лог, и продолжить загрузку дальше, как будто ошибочного текста не было вообще.
В случае с GC все более чем тривиально.
Просто весь этот недогрузившийся мусор подберет GC.
J>короче, транзакционность по отношению к возникновению исключения: если при обработке события возникло исключение, то надо сделать так, будто такого события не было вообще в природе (разве что в логе).
Завист от задачи.
Очень сильно зависит.
J>да не зависит.
Правда? J>транзакция — это действия по изменению + действия по коммиту либо действия по откату. J>И вот для автоматизации этих действия как раз RAII?и используется.
А как насчет распределенных транзакций по нескольким персистентным хранилищам каждое из которых может отрубиться в любой момент?
Как мне поможет RAII если у меня процесс с этим самым RAII сдох посреди транзакции?
J>Это я понял, не понял лишь, зачем ты так насильственно сужаешь область применения RAII.
За тем что не вижу смысла применять это для чегото другого.
Можно попробовать меня переубедить.
Только должны быть аргументы.
Пока я ничего не вижу.
... << RSDN@Home 1.2.0 alpha rev. 745>>
Пусть это будет просто:
просто, как только можно,
но не проще.
(C) А. Эйнштейн
Здравствуйте, jazzer, Вы писали:
J>GC приберется только относительно выделения памяти. J>Элемент из массива удалять кто будет?
Опять сферический массив в вакууме?
... << RSDN@Home 1.2.0 alpha rev. 745>>
Пусть это будет просто:
просто, как только можно,
но не проще.
(C) А. Эйнштейн
Здравствуйте, Sergey, Вы писали:
S>_Jane_ пишет:
>>> > А смесь пробелов и табуляции -- это вообще как свидетельство того, что >>> > человек не владеет инструментами, которыми пользуется (не способен >>> > настроить свой редактор/IDE). >> >> S>А я вот вполне осознанно пробелы с табуляцией мешаю Не знал, что это >> S>может кого-то бесить... >> >> Не подскажете, в каких случаях это может пригодиться? Как именно >> расставляются пробелы и табуляции, систематически?
S>Везде — табуляции, но при переносе части выражения на следующую иногда S>приходится добивать пробелами.
Так и нужно делать.
>> Дело в том, что если их расставлять как попало, то кому-то другому, >> который будет смотреть этот код, придётся временно выставить размер >> табуляции в тот, который использовался при написании кода, что бывает не >> удобно.
S>Эта проблема появится не раньше, чем у нас в конторе заведётся человек, S>который выставит размер табуляции отличный от 4 и начнёт на это S>жаловаться. Пока таких не было.
А это — очень плохой подход. Из той же серии, что и «оставим как есть, пока не придет человек с броузером, отличным от Microsoft Internet Explorer, и не начнет жаловаться».
Здравствуйте, Roman Odaisky, Вы писали:
S>>Везде — табуляции, но при переносе части выражения на следующую иногда S>>приходится добивать пробелами.
RO>
— Ведь очевидно, что если на перекрестке никого нет, то ехать можно при любом свете
— 60 км/час по населенному пункту это очень мало
— Зачем уступать пешеходам, если они вас не догонят?
— Если очень надо, то можно развернуться в любом месте
и т.д.
Никто не спорит, что есть уроды способные нарушать все правила сразу
тут уже где-то писали, что ПДД написаны кровью.
Думаю, что этот guide написан опытом ведения больших проектов
Здравствуйте, CreatorCray, Вы писали:
CC>В таком случае для C++0x auto это как раз то самое применение.
С++0x пока нет. И еще не известно, когда можно будет применять C++0x компиляторы в продакшене (да еще и в кроссплатформенных проектах).
E>>>>А каковы критерии определения крайностей? Почему нужно именно три varN, а четвертая -- это уже крайность? CC>>>Читабельность + разумные рамки вложенностей.
E>>Не сильно объективный критерий. CC>Та каша с дикой вложенностью имеет более объективное обоснование?
Там вообще нет промежуточных объектов. Соответственно, код программы не захламляется переменными, которые будут использоваться всего один раз.
SObjectizer: <микро>Агентно-ориентированное программирование на C++.
Здравствуйте, WolfHound, Вы писали:
J>>Это не я задвинул, это вполне устоявшийся термин. А именно: если у тебя есть объект какого-то класса и ты зовешь какой-то его метод, то метод называется транзакционным (другой термин — дает strong exception safety guarantee), если при в случае вылета из метода по исключению состояние объекта не меняется. Basic exception safety guarantee — это когда состояние объекта может измениться, но при этом оно останется корректным (т.е. все инварианты будут выполнены). J>>Все тут, кроме тебя, говорят исключительно об этой транзакционности и о том, что RAII помогает именно с этой транзакционностью. WH>Реализуй на C#(2 или выше) System.Collections.Generic.List<T> это аналог std::vector. WH>Тогда ты поймешь чего стоит RAII. WH>Скажу по секрету сделать его реализацию так что бы не иметь strong exception safety guarantee нужно ну очень постараться.
index
Type: System.Int32
The zero-based index at which item should be inserted.
Exceptions
Exception
Condition
ArgumentOutOfRangeException
index is less than 0.
-or-
index is greater than Count.
Обрати внимание, как MSDN стыдливо пропускает мимо внимания, что будет, если не хватит памяти, или чем закончится 2147483648-й вызов функции.
Итак, какую гарантию обеспечивает List(T).Insert?
Что должен вывести следующий код при выполнении на машине с 64 ГБ оперативной памяти?
List<int> list;
list.Insert(0, 42);
list.Insert(0, 24);
try
{
for(int i = 0; i < 2147483646; ++i)
{
list.insert(1, 0); // согласно MSDN, исключений не бросает
}
}
catch(Exception)
{
Console.WriteLine("Oops!"); // разве что OOM, но предположим, что 8 ГБ памяти в наличии есть
}
Console.WriteLine("{0} {1} {2} {3} {4}",
list.Count, list.первый_элемент, list.второй_элемент, list.предпоследний_элемент, list.последний_элемент);
Здравствуйте, Юрий Жмеренецкий, Вы писали:
ЮЖ>Т.е. любые примеры отклоняются со словами — "криво, нужно переписать все" ? =)
Не все, а вполне конкретные.
ЮЖ>Переформулирую вопрос — Как при реализации функций в системах с GC(и без него) обеспечивается "strong exception guarantee" ? В С++ один из вариантов — использование RAII.
По разному.
... << RSDN@Home 1.2.0 alpha rev. 745>>
Пусть это будет просто:
просто, как только можно,
но не проще.
(C) А. Эйнштейн
Здравствуйте, WolfHound, Вы писали:
WH>Здравствуйте, Roman Odaisky, Вы писали:
RO>>Итак, какую гарантию обеспечивает List(T).Insert? WH>strong exception safety guarantee те если вылетит исключение то List останется в неизменном состоянии. WH>
Здравствуйте, MShura, Вы писали:
MS>Хотя разрешает создавать дверь, производную, например, от реализованной двери и от базового абстрактного класса для двигателя. MS>В случае множественного наследования рекомендуют создать интерфейс стеклоподьемник и сделать новую дверь производной от реализованной двери и интерфейса стеклоподъемника.
А какой смысл в таких извращениях, если можно просто воспользоваться простым и понятным множественным наследованием?
MS>>>Хотя разрешает создавать дверь, производную, например, от реализованной двери и от базового абстрактного класса для двигателя. MS>>>В случае множественного наследования рекомендуют создать интерфейс стеклоподьемник и сделать новую дверь производной от реализованной двери и интерфейса стеклоподъемника.
J>>А какой смысл в таких извращениях, если можно просто воспользоваться простым и понятным множественным наследованием?
MS>Этот подход напоминает COM. Интерфейсы отдельно, реализации отдельно.
Т.е. если у меня есть два реализованных класса А и В, в каждом по двадцать полей и методов, и есть третий класс С, который _является_ и А и В, то вместо того, чтоб просто написать struct C : A,B {}, я должен буду либо включить эти классы как члены и написать 40 тупых функций-трамплинов?
А если эти методы еще и вертуальные и я их хочу перекрыть...
А если еще я хочу передавать указатели на базовые типы, причем так, чтоб по ним можно было грохнуть объект....
И весь этот геморрой ради того, чтоб напоминало СОМ?
Полностью поддерживаю. Это похоже на мнение человека, который 10 лет писал на С, а потом увидел исключения, и попытался их использовать как будто это ещё один способ локальной передачи управления, аналогичный while/if/goto. Естественно, ничего хорошего при таком подходе не получится.
Не говоря уже о том, что в Java/C# такой подход вообще не будет работать, т.к. потенциально практически каждая строчка кода бросает исключения.
Здравствуйте, Roman Odaisky, Вы писали:
RO> Они должны поддерживать существующий код, не обеспечивающий exception safety. И в этом они правы: исключения нужно использовать или везде, или нигде.
Если исключения не начать использовать, то количество существующего кода, не обеспечивающего exception safety будет расти постоянно.
Ну это так, ответил банальностью на банальность. Сам я жалею, что в нескольких проектах лет шесть-семь назад не начал использовать исключений. Это была большая ошибка.
SObjectizer: <микро>Агентно-ориентированное программирование на C++.
Здравствуйте, night beast, Вы писали:
RO>>Я не доверяю гайдам, которые пишут «const string &in».
NB>ну вот, начинается :) NB>щас кто-нибудь не согласится, и понеслась...
Разве ты не видишь в этом ни одной — объективной — ошибки?
Здравствуйте, Roman Odaisky, Вы писали:
RO>>>Я не доверяю гайдам, которые пишут «const string &in».
NB>>ну вот, начинается NB>>щас кто-нибудь не согласится, и понеслась...
RO>Разве ты не видишь в этом ни одной — объективной — ошибки?
я такой стиль не применяю, но если дать компилятору эту строку, он ее скомпилирует.
значит объективных ошибок нет.
Здравствуйте, night beast, Вы писали:
RO>>>>Я не доверяю гайдам, которые пишут «const string &in». NB>>>ну вот, начинается :) NB>>>щас кто-нибудь не согласится, и понеслась... RO>>Разве ты не видишь в этом ни одной — объективной — ошибки?
NB>я такой стиль не применяю, но если дать компилятору эту строку, он ее скомпилирует. NB>значит объективных ошибок нет.
Здравствуйте, Roman Odaisky, Вы писали:
RO>Здравствуйте, night beast, Вы писали:
RO>>>>>Я не доверяю гайдам, которые пишут «const string &in». NB>>>>ну вот, начинается NB>>>>щас кто-нибудь не согласится, и понеслась... RO>>>Разве ты не видишь в этом ни одной — объективной — ошибки?
RO>Не ошибок компиляции, а стилевых.
Здравствуйте, Roman Odaisky, Вы писали:
RO>>>Разве ты не видишь в этом ни одной — объективной — ошибки?
NB>>я такой стиль не применяю, но если дать компилятору эту строку, он ее скомпилирует. NB>>значит объективных ошибок нет.
RO>Не ошибок компиляции, а стилевых.
Как стилевая ошибка может претендовать на объективность?!
E>Сурово.
+1
Интересно, а как они с RAII при этом рабоьают? Неудобно же.
Все эмоциональные формулировки не соотвествуют действительному положению вещей и приведены мной исключительно "ради красного словца". За корректными формулировками и неискажённым изложением идей, следует обращаться к их автором или воспользоваться поиском
Здравствуйте, Alxndr, Вы писали:
A>Как стилевая ошибка может претендовать на объективность?!
Легко. Если есть несколько стилевых решений, и в среднем (по ситуациям/программистам) одно ведет к большему количеству ошибок читающего/исправляющего код, чем другие, то оно является объективной стилевой ошибкой.
Обычно этот критерий можно свести к количественному такому: "О скольких закоулках синтаксиса должен помнить человек, чтобы без ошибок понимать данный код?" Этот критерий проще, но исключает факторы типа визуального шума и графической похожести, которые могут замазать ошибку/опечатку (например, f(1) всегда должно быть вызовом с аргументом единица, а не с переменной l-маленькое).
Похожий критерий: "сколькими способами можно трактовать данный код?" Тот код, который дает меньший простор воображению, также является стилистически лучшим.
Здравствуйте, Erop, Вы писали:
E>Интересно, а как они с RAII при этом рабоьают? Неудобно же.
Надо полагать, что они практикуют двух-фазную инициализацию объектов. Простой конструктор + все действия в методе Init(), который уже возвращает код ошибки.
SObjectizer: <микро>Агентно-ориентированное программирование на C++.
Здравствуйте, Alxndr, Вы писали:
RO>>>>Разве ты не видишь в этом ни одной — объективной — ошибки? NB>>>я такой стиль не применяю, но если дать компилятору эту строку, он ее скомпилирует. NB>>>значит объективных ошибок нет. RO>>Не ошибок компиляции, а стилевых.
A>Как стилевая ошибка может претендовать на объективность?!
Здравствуйте, eao197, Вы писали:
E>Здравствуйте, Roman Odaisky, Вы писали:
RO>> Они должны поддерживать существующий код, не обеспечивающий exception safety. И в этом они правы: исключения нужно использовать или везде, или нигде.
E>Если исключения не начать использовать, то количество существующего кода, не обеспечивающего exception safety будет расти постоянно.
E>Ну это так, ответил банальностью на банальность. Сам я жалею, что в нескольких проектах лет шесть-семь назад не начал использовать исключений. Это была большая ошибка.
А вариантов, кроме переписывания старого кода и отлова всех исключений на границах, в общем-то, нет никаких.
Здравствуйте, jazzer, Вы писали:
A>>Как стилевая ошибка может претендовать на объективность?!
J>Легко. Если есть несколько стилевых решений, и в среднем (по ситуациям/программистам) одно ведет к большему количеству ошибок читающего/исправляющего код, чем другие, то оно является объективной стилевой ошибкой.
Даже в этом случае стиль, "лучший" с этой точки зрения для одной группы программистов, может привести, к примеру, к меньшей эффективности другой — например, более опытной группы.
Здравствуйте, Alxndr, Вы писали:
A>Здравствуйте, jazzer, Вы писали:
A>>>Как стилевая ошибка может претендовать на объективность?!
J>>Легко. Если есть несколько стилевых решений, и в среднем (по ситуациям/программистам) одно ведет к большему количеству ошибок читающего/исправляющего код, чем другие, то оно является объективной стилевой ошибкой.
A>Даже в этом случае стиль, "лучший" с этой точки зрения для одной группы программистов, может привести, к примеру, к меньшей эффективности другой — например, более опытной группы.
Здравствуйте, jazzer, Вы писали:
J>>>Легко. Если есть несколько стилевых решений, и в среднем (по ситуациям/программистам) одно ведет к большему количеству ошибок читающего/исправляющего код, чем другие, то оно является объективной стилевой ошибкой.
A>>Даже в этом случае стиль, "лучший" с этой точки зрения для одной группы программистов, может привести, к примеру, к меньшей эффективности другой — например, более опытной группы.
J>конь о четырех ногах, сам знаешь
Так и "сдуру" можно такое поломать, что никакие "объективно лучшие" (по вышеописанному критерию) стили не спасут.
Здравствуйте, jazzer, Вы писали:
E>>Интересно, а как они с RAII при этом рабоьают? Неудобно же. J>А RAII никуда не делась. Просто вместо исключений
Да ясно, что никуда не делось. Но ведь правда неудобно
Все эмоциональные формулировки не соотвествуют действительному положению вещей и приведены мной исключительно "ради красного словца". За корректными формулировками и неискажённым изложением идей, следует обращаться к их автором или воспользоваться поиском
Здравствуйте, Roman Odaisky, Вы писали:
RO>Если хорошо подумать, то единственный правильный способ написать это — «std::string const& in».
RO>Потому что: RO>1. «std::» — надеюсь, понятно.
Согласен.
RO>2. const справа позволяет избежать непонимания в случае «const T @ @ something», где «@» — «*» или «&». Сам видел «const T* &something». Что хотели написать и что получилось? То ли дело «T const* & something» или «T * const& something».
Согласен.
RO>3. Приклеивать «*» и «&» к имени — глупо. Ясно, что с обоими пунктуаторами нужно поступать одинаково, но, в то время как «X *x» еще имеет смысл («*x имеет тип X»), запись «X &x» его лишена. Так что «X* x» и «X& x».
Не согласен с выделенным — не глупо, а дело вкуса. Я, к примеру, пишу именно так ("X &x"), поскольку, как гласит буква Стандарта:
8.3.1 Pointers
1 In a declaration T D where D has the form
* cv-qualifier-seqopt D1
and the type of the identifier in the declaration T D1 is “derived-declarator-type-list T,” then the type of the identifier of D is “derived-declarator-type-list cv-qualifier-seq pointer to T.”
Или, другими словами, '*' и '&' являются частью D ("*x"), а не T ("X"), а в Вашей записи выглядит все наоборот Да и вот сразу пример из стандарта (8.3.1/2), где по другому и не напишешь:
const int ci = 10, *pc = &ci, *const cpc = pc, **ppc;
int i, *p, *const cp = &i;
Конечно же, несколько объявлений на одной строке — то еще зло, но все-таки
[]
RO>Ты же не споришь, что приведенный выше вариант — множественно неправильный?
Лично я — не спорю.
У меня просто идиосинкрозия на "объективность" и "единственно правильность".
Надеюсь, в том примере выше ты просто пошутил (и, на всякий случай, — да, я сам сторонник std::string const& in).
Здравствуйте, Roman Odaisky, Вы писали:
RO>Если хорошо подумать, то единственный правильный способ написать это — «std::string const& in».
В общем случае может быть, а в случае аргумента функции const std::string& мне кажется более правильным — это устоявшаяся форма записи, которая, во-первых, широко применяется, а во-вторых, хотя это возможно связано с предыдущим, это легче читать. Обычно люди все-таки читают слева-направо и, взглянув на объявление, особенно с подсвеченным в IDE const, сразу видно, что это in параметр.
Вообще, мне этот гайд понравился. Это как с ПДД, которые, как известно, написаны кровью. Здесь похоже случай близкий — достаточно, например, попытаться портировать проекты с исключениями или rtti на платформы, где их нет или где они работают криво =)
Здравствуйте, eao197, Вы писали:
E>Глупо приколупываться к подобным мелочам и уделять им столь повышенное внимание.
Думаю, что возьму это и включу самым жирнейшим шрифтом в наши coding conventions.
А то есть тут за соседним столом один кадр, который уделяет повышенное внимание отделению знаков == и = пробелами от аргументов. Ни одного не пропустит, но при этом в код постоянно пролезает такой очевидный ужас, что становится страшно.
Здравствуйте, landerhigh, Вы писали:
L>Здравствуйте, eao197, Вы писали:
E>>Глупо приколупываться к подобным мелочам и уделять им столь повышенное внимание.
L>Думаю, что возьму это и включу самым жирнейшим шрифтом в наши coding conventions.
L>А то есть тут за соседним столом один кадр, который уделяет повышенное внимание отделению знаков == и = пробелами от аргументов. Ни одного не пропустит, но при этом в код постоянно пролезает такой очевидный ужас, что становится страшно.
судя по твоим словам, ты еще не читал книжку саттера-александреску по поводу стайл гайдов — рекомендую, там как раз одним их первых пунктов идет "не приколупывайтесь к мелочам!" (ну, может, глагол другой немножко )
Здравствуйте, jazzer, Вы писали:
L>>А то есть тут за соседним столом один кадр, который уделяет повышенное внимание отделению знаков == и = пробелами от аргументов. Ни одного не пропустит, но при этом в код постоянно пролезает такой очевидный ужас, что становится страшно. J>судя по твоим словам, ты еще не читал книжку саттера-александреску по поводу стайл гайдов — рекомендую, там как раз одним их первых пунктов идет "не приколупывайтесь к мелочам!" (ну, может, глагол другой немножко )
Не читал. К сожалению, мне ее уже поздно читать
Правда, толку от это очень мало — большинство современных программистов, с кем приходится иметь дело, не то что Александреску не читали, но и о том, кто такой Кнут, имеют очень смутное представление.
Могу попробовать сослаться на Александреску, но, боюсь, получу вопрос класса "а кто это?"
Здравствуйте, landerhigh, Вы писали:
L>Не читал. К сожалению, мне ее уже поздно читать
В смысле, ты уже на плюсах не пишешь?
L>Правда, толку от это очень мало — большинство современных программистов, с кем приходится иметь дело, не то что Александреску не читали, но и о том, кто такой Кнут, имеют очень смутное представление. L>Могу попробовать сослаться на Александреску, но, боюсь, получу вопрос класса "а кто это?"
лучше на Саттера — про него можно ответить, что это секретарь комитета по стандартизации С++ и один из главных в команде мелкософтовского компилятора (насчет второго могу ошибаться, правда).
Здравствуйте, landerhigh, Вы писали:
L>Да все о том же. Определенными авторами и их произведениями неокрепших программистов можно напугать до смерти. Вот тут как раз такой случай
Самокритично так выразился, респектуха
Все эмоциональные формулировки не соотвествуют действительному положению вещей и приведены мной исключительно "ради красного словца". За корректными формулировками и неискажённым изложением идей, следует обращаться к их автором или воспользоваться поиском
Здравствуйте, landerhigh, Вы писали:
J>>Я имею в виду их совместную книгу "Стандарт программирования С++" или как-то так, в общем, они не про шаблоны и прочее, а про самые банальные вещи говорят. J>>Очень полезная книжка для командной работы, вот тебе бы она как раз пригодилась в борьбе с твоим занудным соседом. L>Да все о том же. Определенными авторами и их произведениями неокрепших программистов можно напугать до смерти. Вот тут как раз такой случай
Что до правил оформления кода, то вот что о них говорится:
Issues that are really just personal taste and don't affect correctness or readability don't belong in a coding standard. Any professional programmer can easily read and write code that is formatted a little differently than they're used to.
Do use consistent formatting within each source file or even each project, because it's jarring to jump around among several styles in the same piece of code. But don't try to enforce consistent formatting across multiple projects or across a company.
Here are several common issues where the important thing is not to set a rule but just to be consistent with the style already in use within the file you're maintaining:
* Don't specify how much to indent, but do indent to show structure: Use any number of spaces you like to indent, but be consistent within at least each file.
* Don't enforce a specific line length, but do keep line lengths readable: Use any length of line you like, but don't be excessive. Studies show that up to ten-word text widths are optimal for eye tracking.
* Don't overlegislate naming, but do use a consistent naming convention: There are only two must-dos: a) never use "underhanded names," ones that begin with an underscore or that contain a double underscore; and b) always use ONLY_UPPERCASE_NAMES for macros and never think about writing a macro that is a common word or abbreviation (including common template parameters, such as T and U; writing #define T anything is extremely disruptive). Otherwise, do use consistent and meaningful names and follow a file's or module's convention. (If you can't decide on your own naming convention, try this one: Name classes, functions, and enums LikeThis; name variables likeThis; name private member variables likeThis_; and name macros LIKE_THIS.)
* Don't prescribe commenting styles (except where tools extract certain styles into documentation), but do write useful comments: Write code instead of comments where possible (e.g., see Item 16). Don't write comments that repeat the code; they get out of sync. Do write illuminating comments that explain approach and rationale.
Finally, don't try to enforce antiquated rules (see Examples 3 and 4) even if they once appeared in older coding standards.
Из всех рекомендаций по оформлению кода, которые мне приходилось видеть эти, пожалуй, самые лояльные.
SObjectizer: <микро>Агентно-ориентированное программирование на C++.
Здравствуйте, eao197, Вы писали:
E>Здравствуйте, landerhigh, Вы писали:
E>Из всех рекомендаций по оформлению кода, которые мне приходилось видеть эти, пожалуй, самые лояльные.
У меня сложилось впечатление, что после определенного числа проектов и связанных с ними развлечений, любой программист приходит к более-менее такому же набору правил.
Как пример — приходит понимание, что размер табуляции на читаемость не влияет никак, зато код с неоднородным выравниванием читать гораздо сложнее, нежели тот, где выравнивание было сделано в одном стиле. Что наличие или отсутствие пробелов до и после операторв вообще никак не влияет, но строки кода, которые по ширине не влезают на 22" монитор, отбивают не только желание читать этот код, но и вообще иметь с ним (и с его автором) дело. То же самое с оформлением комментариев и прочего (главное, чтобы человек и doxygen поняли).
Просто у тех, кому пришлось знатно покопаться в спагетти-коде, возникает ложное, хотя и оправданное мнение, что для наступления полной нирваны необходимо и достаточно заставить всех подряд расставлять пробелы согласно прейскуранту.
Здравствуйте, landerhigh, Вы писали:
L>Просто у тех, кому пришлось знатно покопаться в спагетти-коде, возникает ложное, хотя и оправданное мнение, что для наступления полной нирваны необходимо и достаточно заставить всех подряд расставлять пробелы согласно прейскуранту.
Очень верное замечание.
Однако, есть две вещи, которые лично меня приводят в бешенство:
— написание выражений без пробелов:
— смешение табуляции и пробелов в одном исходном файле.
Уж не знаю почему. Но когда я вижу такое в коде подчиненных, то заставляю переделывать.
А смесь пробелов и табуляции -- это вообще как свидетельство того, что человек не владеет инструментами, которыми пользуется (не способен настроить свой редактор/IDE).
Упс... Чо-то прорвало меня.
SObjectizer: <микро>Агентно-ориентированное программирование на C++.
Здравствуйте, landerhigh, Вы писали:
L>Здравствуйте, eao197, Вы писали:
E>>Здравствуйте, landerhigh, Вы писали:
E>>Из всех рекомендаций по оформлению кода, которые мне приходилось видеть эти, пожалуй, самые лояльные. L>У меня сложилось впечатление, что после определенного числа проектов и связанных с ними развлечений, любой программист приходит к более-менее такому же набору правил.
Это само собой.
Просто когда приходят в проект новички, приходится тратить время, убеждая их, что надо делать так, а не иначе — у них же нет такого опыта.
Вот в этом смысле им очень полезно дать эту книжку почитать.
You will always get what you always got
If you always do what you always did
Re[17]: Google C++ Style Guide
От:
Аноним
Дата:
04.07.08 08:22
Оценка:
Здравствуйте, jazzer, Вы писали:
J>Это само собой. J>Просто когда приходят в проект новички, приходится тратить время, убеждая их, что надо делать так, а не иначе — у них же нет такого опыта. J>Вот в этом смысле им очень полезно дать эту книжку почитать.
Вот прихожу я, новичок, в проект (точнее, в небольшую фирму, занимающуюся небольшими проектами), мне разъясняют, что пробелы и скобки ставить так-то, что тернарный ?: не использовать, что ссылки применять только по требованию синтаксиса (читайте: при переопределении операторов и copy-ctor'а), что исключения -- это зло... Ладно, делаю как сказали.
Прошло полгода, и мне досталось "посопровождать" проект, ведомый этим "старшИм", пока он отдыхает в тёплой стране. Когда мне пришлось вносить изменения, то я увидел сплошной copy-paste (строк по 50), а также абсолютно денормализованную БД.
после беглого прочтения не понял следующего
>> If you actually need pointer semantics, scoped_ptr is great. You should only use std::tr1::shared_ptr under very specific conditions, such as when objects need to be held by STL containers. You should never use auto_ptr.
>> Use streams only for logging.
чем им не угодили потоки и auto_ptr?
... << RSDN@Home 1.2.0 alpha 4 rev. 1089>>
Windows XP 5.1.2600.131072 ... абсолютная тишина
CTpaHHoe пишет:
>> > If you actually need pointer semantics, scoped_ptr is great. You > should only use std::tr1::shared_ptr under very specific conditions, > such as when objects need to be held by STL containers. You should never > use auto_ptr. > >> > Use streams only for logging. > > чем им не угодили потоки и auto_ptr?
Видимо, просто мало кто знает как работает auto_ptr — а работает он
неочевидно. Ну а потоки медленные наверное просто.
Posted via RSDN NNTP Server 2.1 beta
Одним из 33 полных кавалеров ордена "За заслуги перед Отечеством" является Геннадий Хазанов.
Здравствуйте, jazzer, Вы писали:
J>ну, на мое имхо — сильно хуже, потому что в RAII деструкторы регистрируются по мере добавления, а с finally их наод в одном месте все создавать, флажки всякие заводить, нужно откатывать или не нужно, и все такое. С RAII это все автоматом, пишешь и не думаешь ни о чем, можешь в любой момент в любом порядке все пеетасовать.
На жебе да не удобно.
А вот на C# вполне себе:
using (Stream file1 = File.Open(...))
using (Stream file2 = File.Open(...))
using (Stream file3 = File.Open(...))
using (Stream file4 = File.Open(...))
{
}
От RAII не сильно отлячается.
... << RSDN@Home 1.2.0 alpha rev. 745>>
Пусть это будет просто:
просто, как только можно,
но не проще.
(C) А. Эйнштейн
Здравствуйте, Sni4ok, Вы писали:
S>Здравствуйте, night beast, Вы писали:
NB>>Google C++ Style Guide
S>эх, у меня когда-то мечта была, в гугл попасть, даже пытался туда устроиться- но на собеседование даже не пригласили.. S>если бы я знал их кодестайл, мне бы это столько времени бы сыкономило
ты документ внимательно читал?
этот стайлгайд для опенсорсных проектов гугла, а не для их внутренних разработок.
Здравствуйте, alexeiz, Вы писали:
A>Это просто 3.14здец какой-то! shared_ptr under very specific conditions? Тогда как shared_ptr в разы увеличивает надежность кода. А scoped_ptr существенно ограничен по применению. Как они собираются возвращать указатель из функции, например? Единственный разумный ответ в такой ситуации — как голый указатель. А вся мощь smart pointer'ов осталась за бортом.
Действительно, зачем у гугола опыт перенимать? Кто они такие и что могут?
A>Поэтому я не могу терпеть большинство coding stadards. Какой-нибудь полоумный architect их напишет, который сам в последний раз что-либо новое про C++ узнал году так в 95-м. Про shared_ptr он услышал от вчерашнего студента (спасибо студенту, а так бы вообще не услышал), и подумал: "не-не-не, Дэвид Блэйн! Only under very specific conditions!"
Конечно студенты напишут лучше...
Все эмоциональные формулировки не соотвествуют действительному положению вещей и приведены мной исключительно "ради красного словца". За корректными формулировками и неискажённым изложением идей, следует обращаться к их автором или воспользоваться поиском
Здравствуйте, jazzer, Вы писали:
J>ты документ внимательно читал? J>этот стайлгайд для опенсорсных проектов гугла, а не для их внутренних разработок.
люди из конторы в которой я работыю уверяли, что в гугле этот кодестайл и для внутреннего использования, более того ему заставляют следовать, иначе код с ревью на доработку отправляется.
Здравствуйте, Sni4ok, Вы писали:
S>Здравствуйте, jazzer, Вы писали:
J>>ты документ внимательно читал? J>>этот стайлгайд для опенсорсных проектов гугла, а не для их внутренних разработок.
S>люди из конторы в которой я работыю уверяли, что в гугле этот кодестайл и для внутреннего использования, более того ему заставляют следовать, иначе код с ревью на доработку отправляется.
Когда coding guidelines заставляют следовать с точностью до буквы, это конечно жестоко. Неговоря уже о том, что это просто пустая трата времени.
Здравствуйте, WolfHound, Вы писали:
WH>Здравствуйте, jazzer, Вы писали:
J>>Бывает, сплошь и рядом (не с файлами, конечно ). WH>А с чем?
J>>не, файлы, конечно, ты вряд ли больше чем два в одной функции открывать будешь, но что, у тебя программы только файлами занимаются? WH>Не только. WH>Но критичных ресурсов все так же мало. WH>Раз два и обчелся.
J>>RAII используется в первую очередь для отката (с конкретными временными рамками, а именно — область видимости) какого-то действия, и захват ресурса — это только одна из разновидностей подобных действий, WH>Пример в студию.
да любое изменение — изменение значения переменной, вставка объекта в контейнер, удаление объекта из контейнера и т.д.
если ты хочешь обеспечить транзакционность метода в условиях летающих исключений — как ты это без RAII будешь делать?
и тут, как видишь, слово "ресурс" вообще не возникает, а RAII, тем не менее, в полный рост.
J>>а уж захват памяти, от которого помогает GC — это еще меньшее подмножество подобных действий. WH>Чё? Да это 99% случаев использования RAII если не больше.
У кого как
Здравствуйте, jazzer, Вы писали:
J>да любое изменение — изменение значения переменной, вставка объекта в контейнер, удаление объекта из контейнера и т.д.
Что-то ни разу не хотелось сделать что-то подобное.
Можешь показать зачем оно тебе?
J>если ты хочешь обеспечить транзакционность метода в условиях летающих исключений — как ты это без RAII будешь делать?
Очень зависит от того что за метод и что за транзакции.
J>и тут, как видишь, слово "ресурс" вообще не возникает, а RAII, тем не менее, в полный рост.
У кого как.
Лично у меня в коде на С++ RAII только для того чтобы захватить/освободить некий ресурс.
Не важно файл, мьютекс, некий тяжелый объект из пула, кусок памяти...
... << RSDN@Home 1.2.0 alpha rev. 745>>
Пусть это будет просто:
просто, как только можно,
но не проще.
(C) А. Эйнштейн
Здравствуйте, WolfHound, Вы писали:
WH>Здравствуйте, jazzer, Вы писали:
J>>да любое изменение — изменение значения переменной, вставка объекта в контейнер, удаление объекта из контейнера и т.д. WH>Что-то ни разу не хотелось сделать что-то подобное. WH>Можешь показать зачем оно тебе?
Здравствуйте, WolfHound, Вы писали:
WH>Здравствуйте, jazzer, Вы писали:
J>>да любое изменение — изменение значения переменной, вставка объекта в контейнер, удаление объекта из контейнера и т.д. WH>Что-то ни разу не хотелось сделать что-то подобное. WH>Можешь показать зачем оно тебе?
The os stream will retain its new hexadecimal printing mode after the call to hex_my_byte. The stream's printing mode can be saved and restored with manual calls to the stream's state inspecting and mutating member functions. The manual method becomes unwieldy if the main functionality is complex and/or needs to be exception safe. A saver class can implement the better "resource acquisition is initialization" strategy.
J>>если ты хочешь обеспечить транзакционность метода в условиях летающих исключений — как ты это без RAII будешь делать? WH>Очень зависит от того что за метод и что за транзакции.
Как реализуется strong guarantee("все, либо ничего") в присутствии исключений? Вариантов обычно два — клонирование+изменение+swap, либо изменение "in place" с откатами при исключениях. Изменение состояния потока относится к тому случаю, когда клонирование невозможно, поэтому остается только вариант с приведением состояния к первоначальному. Такие вот транзакции...
Здравствуйте, WolfHound, Вы писали:
WH>Здравствуйте, jazzer, Вы писали:
J>>да любое изменение — изменение значения переменной, вставка объекта в контейнер, удаление объекта из контейнера и т.д. WH>Что-то ни разу не хотелось сделать что-то подобное. WH>Можешь показать зачем оно тебе?
Ну вот у меня в системе летают сообщения, и в программе есть некий state, который обновляется с приходом разнообразных сообщений (т.е. мы добавили элемент в контейнер А, изменили статистику в объекте В, нашли объект в контейнере С и в контейнере, который в нем, удалили какой-то элемент, и так далее, куча действий на разных уровнях).
Но сообщения могут быть ошибочными по той или иной причине, и такие сообщения должны игнорироваться.
Игнорироваться — это значит, что state после их прихода должен быть таким, как будто ничего не приходило вообще.
Причем проверка сообщения — вещь многоуровневая, в одну функцию на входе ее не запихнешь, да и дорого это и неудобно — мы хотим оптимизировать по скорости сценарий, когда сообщение корректное.
Т.е. ты начинаешь делать какие-то действия, предполагая, что с сообщением все хорошо, а если где-то дальше по стеку что-то не так — откатываешь свои изменения.
Другой пример — загрузка иерархического конфига, когда ошибка в конфиге должна привести к "незагрузке" только этой маленькой ветки, а все остальное должно загрузиться — начинаешь парсить и грузить все в память, создавать всякие деревья и прочее, а в какой-то момент, глубоко в стеке, раз — и опаньки, надо ветку, которая вызвала ошибку, не загружать, лишь ругнуться в лог, и продолжить загрузку дальше, как будто ошибочного текста не было вообще.
в общем, сложно все упомнить — они реально на каждом шагу.
короче, транзакционность по отношению к возникновению исключения: если при обработке события возникло исключение, то надо сделать так, будто такого события не было вообще в природе (разве что в логе).
J>>если ты хочешь обеспечить транзакционность метода в условиях летающих исключений — как ты это без RAII будешь делать? WH>Очень зависит от того что за метод и что за транзакции.
да не зависит.
транзакция — это действия по изменению + действия по коммиту либо действия по откату.
И вот для автоматизации этих действия как раз RAII и используется.
J>>и тут, как видишь, слово "ресурс" вообще не возникает, а RAII, тем не менее, в полный рост. WH>У кого как. WH>Лично у меня в коде на С++ RAII только для того чтобы захватить/освободить некий ресурс. WH>Не важно файл, мьютекс, некий тяжелый объект из пула, кусок памяти...
Это я понял, не понял лишь, зачем ты так насильственно сужаешь область применения RAII.
Здравствуйте, alexeiz, Вы писали:
A>Почитай здесь.
Let's say you are developing one of those trendy instant messaging servers. Users can log on and off the system and can send messages to each other. You hold a server-side database of users, plus in-memory information for users who are logged on. Each user can have friends. The list of friends is also kept both in the database and in memory.
When a user adds or removes a friend, you need to do two things: update the database and update the in-memory cache that you keep for that user. It's that simple.
Дальше в статье тоже ничего интересного.
Память подчистить или там файлик закрыть. Тоже мне невидаль. Память вобще GC подбирает, а файлик можно и using'ом закрыть.
... << RSDN@Home 1.2.0 alpha rev. 745>>
Пусть это будет просто:
просто, как только можно,
но не проще.
(C) А. Эйнштейн
В системах с GC тут приберется GC.
В системах без GC все будет сделано сильно иначе.
ЮЖ>Другой пример, из буста: "io state savers"
В данном случае сам по себе дизайн стимов нужно очень сильно переделать.
У них вобще много странных особенностей включая эту.
... << RSDN@Home 1.2.0 alpha rev. 745>>
Пусть это будет просто:
просто, как только можно,
но не проще.
(C) А. Эйнштейн
Здравствуйте, WolfHound, Вы писали:
WH>Здравствуйте, jazzer, Вы писали:
J>>GC приберется только относительно выделения памяти. J>>Элемент из массива удалять кто будет? WH>Опять сферический массив в вакууме?
нет, совершенно конкретный массив по имени vec из сообщения Юрия.
WH>В системах с GC тут приберется GC. WH>В системах без GC все будет сделано сильно иначе.
GC тут нет, а сильно иначе(для исправления этой ситуации) не получится. Ну получилось так, legacy и т.п. Вопрос в другом — как это исправить(удаление из вектора нас пока не интересует)?
Варианты:
int* ptr = new int();
try
{
vec.push_back(ptr); // bad_alloc при переаллокации, соответственно ptr утечет
}
catch(std::exception&)
{
delete ptr;
throw;
}
Здесь не просто RAII, здесь ключевой момент — в том что с помощью него можно не только освобождать ресурсы в деструкторах, но и моделировать хоть какую-то транзакционность. Имхо, применение целесообразно в случаях с относительно простым rollback'ом, причем критерии простоты могут быть весьма разными.
ЮЖ>>Другой пример, из буста: "io state savers" WH>В данном случае сам по себе дизайн стимов нужно очень сильно переделать. WH>У них вобще много странных особенностей включая эту.
Стримы это только пример, ключевой момент я там выделил — восстановление состояния при ошибках (+ их обработка вынесена из основного кода и не бросается в глаза, как try/catch выше).
Здравствуйте, Erop, Вы писали:
E>Здравствуйте, alexeiz, Вы писали:
A>>Это просто 3.14здец какой-то! shared_ptr under very specific conditions? Тогда как shared_ptr в разы увеличивает надежность кода. А scoped_ptr существенно ограничен по применению. Как они собираются возвращать указатель из функции, например? Единственный разумный ответ в такой ситуации — как голый указатель. А вся мощь smart pointer'ов осталась за бортом.
E>Действительно, зачем у гугола опыт перенимать? Кто они такие и что могут?
А какие такие C++ проекты от Google общественности известны?
Дайте посмотреть, а? Google не софтверная компания по большому счету. Доходы Google не от
продажи/производства софта. Поэтому говорить что Google авторитет в C++ я бы не стал.
Это мое имхо "взглянутое со стороны".
Здравствуйте, c-smile, Вы писали:
CS>А какие такие C++ проекты от Google общественности известны?
Точно: Google Earth, MapReduce,
Не уверен на 100% : Google Talk, Google Desktop, Picasa
... << RSDN@Home 1.1.4 stable SR1 rev. 568>>
Забанили по IP, значит пора закрыть эту страницу.
Всем пока
Для этого нужен очень продвинутый редактор, каковых я не наблюдаю — у всех реализаций этой фичи всегда была лажа в том или ином месте.
так что пока что пробелы — это самый надежный и переносимый вариант для отступов.
RO>А это — очень плохой подход. Из той же серии, что и «оставим как есть, пока не придет человек с броузером, отличным от Microsoft Internet Explorer, и не начнет жаловаться».
Здравствуйте, CreatorCray, Вы писали:
CC>Здравствуйте, c-smile, Вы писали:
CS>>А какие такие C++ проекты от Google общественности известны? CC>Точно: Google Earth, MapReduce, CC>Не уверен на 100% : Google Talk, Google Desktop, Picasa
(Picasa писана не в google изначально)
Это соизмеримо с лично моим кодом что крутится на end user machines сейчас.
Т.е. я лично не считаю Google авторитетом в С++ (и в GUI строении кстати тоже).
Просто не видел ничего выдающегося.
Почему люди должны Google C++ Style Guide считать неким авторитетным источником?
И потом вот эта каща не впечатляет:
MapReduceSpecification spec;
// Store list of input files into "spec"for (int i = 1; i < argc; i++) {
MapReduceInput* input = spec.add_input();
input->set_format("text");
input->set_filepattern(argv[i]);
input->set_mapper_class("WordCounter");
}
Здравствуйте, Roman Odaisky, Вы писали:
S>>Эта проблема появится не раньше, чем у нас в конторе заведётся человек, S>>который выставит размер табуляции отличный от 4 и начнёт на это S>>жаловаться. Пока таких не было. RO>А это — очень плохой подход. Из той же серии, что и «оставим как есть, пока не придет человек с броузером, отличным от Microsoft Internet Explorer, и не начнет жаловаться».
Отнюдь.
В CodingStandard вносится правило tab == 4 пробела.
И на этом проблема исчерпывается.
Все остальные заморочки решаются настройкой редакторов в единый стиль.
... << RSDN@Home 1.1.4 stable SR1 rev. 568>>
Забанили по IP, значит пора закрыть эту страницу.
Всем пока
Здравствуйте, jazzer, Вы писали:
J>а почему С++03 за бортом? С++98 устарел 5 лет назад
А в C++03 есть автоматический вывод типов переменных? Дайте два!
E>>Настоящий Ъ-вэй так:
J>"Ъ-вэй" — это что? И как произносится?
True-way. Ну типа конкретно единственно правильный путь, чиста для реальных пацанов.
На LOR часто употребляется просто "Ъ", например, "это не-Ъ" или "а настоящий Ъ -- это..."
SObjectizer: <микро>Агентно-ориентированное программирование на C++.
Здравствуйте, eao197, Вы писали:
E>Мы говорим о C++98, C++0x (который в топке, бо ни жывы яще) или D?
Ну я не знаю какой там у тебя тип возвращают эти функции, вот и написал так, чтоб было понятно.
E>Да, и кстати говоря, стиль не выдержан. Настоящий Ъ-вэй так:
Нет, там уже другая крайность.
... << RSDN@Home 1.1.4 stable SR1 rev. 568>>
Забанили по IP, значит пора закрыть эту страницу.
Всем пока
Здравствуйте, CreatorCray, Вы писали:
E>>Мы говорим о C++98, C++0x (который в топке, бо ни жывы яще) или D? CC>Ну я не знаю какой там у тебя тип возвращают эти функции, вот и написал так, чтоб было понятно.
Здравствуйте, alexeiz, Вы писали:
A>Вот это ты классно! Одним. Словом. Всю статью разбил.
Ну что поделать если статью можно разбить одним словом?
Тем более что я показал как нужный результат получают другими методами.
Что нечем крыть чисто декларативный код?
public abstract DepartmentAccessor : DataAccessor<Department, DepartmentAccessor>
{
[Cache(MaxMinutes = 5)]
public abstract List<Department> SelectAll();
[ClearCache("SelectAll")]
public abstract Department Insert([Destination(NoMap = false)]Department d);
}
A>Смешно просто. У тебя установка такая, не принимать аргументы собеседников не при каких условиях?
Нет у меня накиких установок.
A>"Кэш не обновляют, а другое решение ваще не масштабируется, поэтому нигде ничего откатывать не нужно, и не приводите мне ваших сферосценариев в вакууме!"
Ну как всегда... пошла демагогия.
Что аргументов ваще нет?
A>Тяжелый случай.
Ага.
... << RSDN@Home 1.2.0 alpha rev. 745>>
Пусть это будет просто:
просто, как только можно,
но не проще.
(C) А. Эйнштейн
Здравствуйте, Юрий Жмеренецкий, Вы писали:
WH>>В системах с GC тут приберется GC. WH>>В системах без GC все будет сделано сильно иначе. ЮЖ>GC тут нет,
Напомню фразу с которой пошол флейм:
Так что Имею Мнение Хрен Оспоришь что польза от RAII при наличии GC мягко говоря приувеличина.
И еще одну:
J>а уж захват памяти, от которого помогает GC — это еще меньшее подмножество подобных действий.
Чё? Да это 99% случаев использования RAII если не больше.
ЮЖ>а сильно иначе(для исправления этой ситуации) не получится.
Зная конкретику как правило получается.
ЮЖ>Ну получилось так, legacy и т.п.
А рефакторинг не катит?
ЮЖ>Стримы это только пример, ключевой момент я там выделил — восстановление состояния при ошибках (+ их обработка вынесена из основного кода и не бросается в глаза, как try/catch выше).
Лично я всегда обходился другими методами.
... << RSDN@Home 1.2.0 alpha rev. 745>>
Пусть это будет просто:
просто, как только можно,
но не проще.
(C) А. Эйнштейн
Здравствуйте, jazzer, Вы писали:
J>ну тебе, безусловно, по этим пяти строчкам, написанным для демонстрации возможностей RAII, видно, что вся система у меня не масштабируется
Ну да.
Шаренный стейт не масштабируется.
J>для этого на недогрузившийся мусор должны пропасть все внешние ссылки — они каким образом будут пропадать?
Лучше ответь на вопрос: Откуда они возьмутся?
J>Вот ты свой недогрузившийся мусор (ты просто еще не знаешь, что это мусор, ибо so far so good) положил в контейнер, работаешь дальше, вызываешь разнообразные функции, и тут из недр стека к тебе прилетело исключение — какую-то лажу мы грузим тут — и что, как тебе GC поможет удалить добавленный элемент из контейнера?
Даже не знаю как на это реагировать.
Лично я не кладу недосозданные объекты в контейнер.
J>да никак не зависит. Транзакционность функции — очень узкая задача (RAII существует только в контексте функции, даже еще уже — в контексте области видимости). Никакие более высокоуровневые вещи RAII сама по себе решить не может, как их не может решить ни одно локально применимое средство языка.
"Транзакционность функции" мда сильно задвинул.
У меня не бывает задач сделать транзакционную функцию.
У меня бывают задачи провести транзакцию над неким хранилищем.
И вот тут транзакционные функции ну никак не помогают.
WH>>Как мне поможет RAII если у меня процесс с этим самым RAII сдох посреди транзакции? J>Я понятия не имею, как у тебя организован message flow, и как ты узнаешь о том, что процесс сдох, ...
Да не важно это все.
Важно то что если мы что-то меняем в совершенно любом персистентном хранилище то для обеспечения транзакций RAII абсолютно бесполезен.
Просто по тому что RAII живет только пока живет процесс.
А если вдруг процесс умер то вся информация о транзакции умрет вместе с эти процессом.
И как следствие у нас не будет информации чтобы востановить хранилище после сбоя.
Я думал что это совершенно очевидно.
J>Тебе несколько раз уже продемонстрировали, как именно RAII работает в ситуациях, не связанных с управлением критичными ресурсами.
Ну да.
Либо оно решается другими способами сильно проще.
Либо решение на RAII вобще не устойчиво к сбоям.
J>И если бы вдруг GC взял на себя все вопросы с управлением памятью объектов из кучи, область применения RAII уменьшилась бы совсем ненамного.
Практика показывает что оно ограничевается максимум парой using на метр кода.
J>Зачем при написании этого кода отказываться от возможностей, предоставляемых языком, и искуственно ограничивать область применения до управлением памятью в куче...
За тем что эти возможности для других задач бесполезны. А то и вредны.
... << RSDN@Home 1.2.0 alpha rev. 745>>
Пусть это будет просто:
просто, как только можно,
но не проще.
(C) А. Эйнштейн
Здравствуйте, eao197, Вы писали:
E>есть, имхо, очень большая разница.
Откуда ты auto_ptr вынул то?
E>А каковы критерии определения крайностей? Почему нужно именно три varN, а четвертая -- это уже крайность?
Читабельность + разумные рамки вложенностей.
... << RSDN@Home 1.1.4 stable SR1 rev. 568>>
Забанили по IP, значит пора закрыть эту страницу.
Всем пока
Здравствуйте, CreatorCray, Вы писали:
E>>есть, имхо, очень большая разница. CC>Откуда ты auto_ptr вынул то?
Ну мне-то лучше знать, что мои функции возвращают
E>>А каковы критерии определения крайностей? Почему нужно именно три varN, а четвертая -- это уже крайность? CC>Читабельность + разумные рамки вложенностей.
Не сильно объективный критерий.
SObjectizer: <микро>Агентно-ориентированное программирование на C++.
Здравствуйте, WolfHound, Вы писали:
WH>Здравствуйте, jazzer, Вы писали:
J>>ну тебе, безусловно, по этим пяти строчкам, написанным для демонстрации возможностей RAII, видно, что вся система у меня не масштабируется WH>Ну да. WH>Шаренный стейт не масштабируется.
ну, до сих пор прекрасно масштабировался.
Посмотри, например, на FIX Protocol — там тот самый "шаренный стейт".
Подход, вкратце, элементарный — стейт однозначно кодируется последовательностью сообщений, все сообщения в системе упорядочены и все компоненты получают их в одном и том же порядке. Стало быть, расшаренный стейт у всех будет одинаковый.
Ну, либо мы говорим о разных вещах и друг друга не понимаем.
J>>для этого на недогрузившийся мусор должны пропасть все внешние ссылки — они каким образом будут пропадать? WH>Лучше ответь на вопрос: Откуда они возьмутся? WH>Лично я не кладу недосозданные объекты в контейнер.
Видишь ли, проверка корректности может быть слишком дорогой и создавать здоровенную структуру только для проверки корректности сообщения, а потом, когда убедились, что сообщение корректно, повторить всю эту же процедуру еще раз на реальном стейте — это просто трата времени, потому что мы ожидаем, что 99.9999% сообщений у нас в системе корректны.
И гораздо быстрее действовать, как будто сообщение правильное, и в редких случаях некорректного сообщения откатить все изменения, вызванные этим некорректным сообщением.
J>>да никак не зависит. Транзакционность функции — очень узкая задача (RAII существует только в контексте функции, даже еще уже — в контексте области видимости). Никакие более высокоуровневые вещи RAII сама по себе решить не может, как их не может решить ни одно локально применимое средство языка. WH>"Транзакционность функции" мда сильно задвинул.
Это не я задвинул, это вполне устоявшийся термин. А именно: если у тебя есть объект какого-то класса и ты зовешь какой-то его метод, то метод называется транзакционным (другой термин — дает strong exception safety guarantee), если при в случае вылета из метода по исключению состояние объекта не меняется. Basic exception safety guarantee — это когда состояние объекта может измениться, но при этом оно останется корректным (т.е. все инварианты будут выполнены).
Все тут, кроме тебя, говорят исключительно об этой транзакционности и о том, что RAII помогает именно с этой транзакционностью.
WH>У меня не бывает задач сделать транзакционную функцию. WH>У меня бывают задачи провести транзакцию над неким хранилищем. WH>И вот тут транзакционные функции ну никак не помогают.
Ну что ж я могу поделать с тем, что ты транзакционность понимаешь только в таком узком смысле?
Хотя, может, хранилище у тебя не обязательно распределенное, а может быть и простой переменной, в которую ты записал 1, а потом надо это дело откатить и вернуть туда 2, которое там было до того? Или у тебя вообще все распределенное, даже инты? И вообще никаких объектов локальных нет?
WH>>>Как мне поможет RAII если у меня процесс с этим самым RAII сдох посреди транзакции? J>>Я понятия не имею, как у тебя организован message flow, и как ты узнаешь о том, что процесс сдох, ... WH>Да не важно это все. WH>Важно то что если мы что-то меняем в совершенно любом персистентном хранилище то для обеспечения транзакций RAII абсолютно бесполезен. WH>Просто по тому что RAII живет только пока живет процесс. WH>А если вдруг процесс умер то вся информация о транзакции умрет вместе с эти процессом. WH>И как следствие у нас не будет информации чтобы востановить хранилище после сбоя.
WH>Я думал что это совершенно очевидно.
Я тоже думал, что я написал в удаленном тобой моем тексте именно это и ты эти мои слова прочитал.
Теперь не уверен.
WH>Либо решение на RAII вобще не устойчиво к сбоям.
Пример в студию, когда RAII неустойчиво к сбоям.
J>>И если бы вдруг GC взял на себя все вопросы с управлением памятью объектов из кучи, область применения RAII уменьшилась бы совсем ненамного. WH>Практика показывает что оно ограничевается максимум парой using на метр кода.
Ну естественно, это верно в случае твоей практики, когда RAII больше ни для чего не применяется
Было бы странно, если было бы наоборот.
J>>Зачем при написании этого кода отказываться от возможностей, предоставляемых языком, и искуственно ограничивать область применения до управлением памятью в куче... WH>За тем что эти возможности для других задач бесполезны. А то и вредны.
Здравствуйте, Alxndr, Вы писали:
MSL>>а еще "i++", а не ++i. A>Дааа, это важно в данном случае
Вы разбазариваете такты процессора! Подозреваю, что также не бережете и межгаллактический запас скобок )))))) На самом деле режет глаз. Как и когда в сравнениях константы не слева.
Здравствуйте, eao197, Вы писали:
E>>>есть, имхо, очень большая разница. CC>>Откуда ты auto_ptr вынул то? E>Ну мне-то лучше знать, что мои функции возвращают
В таком случае для C++0x auto это как раз то самое применение.
E>>>А каковы критерии определения крайностей? Почему нужно именно три varN, а четвертая -- это уже крайность? CC>>Читабельность + разумные рамки вложенностей.
E>Не сильно объективный критерий.
Та каша с дикой вложенностью имеет более объективное обоснование?
... << RSDN@Home 1.1.4 stable SR1 rev. 568>>
Забанили по IP, значит пора закрыть эту страницу.
Всем пока
Здравствуйте, MaximSL, Вы писали:
MSL>>>а еще "i++", а не ++i. Фубля. A>>Дааа, это важно в данном случае MSL>Вы разбазариваете такты процессора!
Чего?!
MSL>На самом деле режет глаз.
Это личное дело вкуса/привычного стиля.
MSL>Как и когда в сравнениях константы не слева.
Тоже занудство, хотя этот случай хотя бы кому то помогает...
... << RSDN@Home 1.1.4 stable SR1 rev. 568>>
Забанили по IP, значит пора закрыть эту страницу.
Всем пока
Здравствуйте, Alxndr, Вы писали:
MSL>>На самом деле режет глаз. Как и когда в сравнениях константы не слева. A>Т.е. на Ваш взгляд должно быть так?
Нет, он про
if (0 == i)
и подобные извраты.
Впрочем некоторым такой стиль помогает не плодить тупые ошибки.
... << RSDN@Home 1.1.4 stable SR1 rev. 568>>
Забанили по IP, значит пора закрыть эту страницу.
Всем пока
Здравствуйте, CreatorCray, Вы писали:
MSL>>>>а еще "i++", а не ++i. A>>>Дааа, это важно в данном случае MSL>>Вы разбазариваете такты процессора! CC>Чего?!
Для инта пофиг, а если на месте инта окажется классик с перегруженными операторами инкремента, то может быть и не пофиг.
Здравствуйте, Alxndr, Вы писали:
A>Здравствуйте, MaximSL, Вы писали:
MSL>>Не, должно быть так: for (int i = 1; i < argc; ++i)
A>А константа справа от сравнения не режет глаз?
Не, не режет. Я имел в виду такие сравнения: if(a == 7) Вот они режут.
MS>>Думаю, что этот guide написан опытом ведения больших проектов
D>Ты забыл добавить слово "опенсорсных"
Не думаю, что есть разница между inside и опенсорс стилями.
D>А что ты думаешь по поводу запрещения множественного наследования, например? D>И связано ли это с ПДД?
Не запрещают, а разумно ограничивают случаи использования.
В ПДД не разрешают изменять принципиально конструкцию автомобиля.
Как вам понравится улучшенная версия двери, которая будет выполнять роль двери и роль двигателя?
Здравствуйте, MaximSL, Вы писали:
MSL>Для инта пофиг, а если на месте инта окажется классик с перегруженными операторами инкремента, то может быть и не пофиг.
Если бы у бабушки да были бы....
...то это была бы совсем иная песТня
... << RSDN@Home 1.1.4 stable SR1 rev. 568>>
Забанили по IP, значит пора закрыть эту страницу.
Всем пока
Здравствуйте, CreatorCray, Вы писали:
CC>Если бы у бабушки да были бы.... CC>...то это была бы совсем иная песТня
А зачем думать — инт / не инт? Если нет никакой разницы, лучше в одном стиле и не обращая внимания на типы. Тогда везде все будет ОК. Но вообще да, вопросы стиля — глубоко религиозны. Вплоть до появления у бабушек определнных атрибутов )))
Здравствуйте, MShura, Вы писали:
MS>>>Думаю, что этот guide написан опытом ведения больших проектов
MS>Не думаю, что есть разница между inside и опенсорс стилями.
Есть.
D>>А что ты думаешь по поводу запрещения множественного наследования, например? D>>И связано ли это с ПДД?
MS>Не запрещают, а разумно ограничивают случаи использования. MS>В ПДД не разрешают изменять принципиально конструкцию автомобиля. MS>Как вам понравится улучшенная версия двери, которая будет выполнять роль двери и роль двигателя?
Давай возьмем для начала дверь с стеклоподъемником и пепельницей.
На самом деле, некоторые из ограничений
мешают общепринятому применению OOP, например при единичном наследовании
вполне возможны интерфейсы с неразумно большим количеством функций.
И таких примеров можно там еще найти.
MS>>>>Думаю, что этот guide написан опытом ведения больших проектов MS>>Не думаю, что есть разница между inside и опенсорс стилями. D>Есть.
Откуда такие знания?
MS>>Не запрещают, а разумно ограничивают случаи использования. MS>>В ПДД не разрешают изменять принципиально конструкцию автомобиля. MS>>Как вам понравится улучшенная версия двери, которая будет выполнять роль двери и роль двигателя?
D>Давай возьмем для начала дверь с стеклоподъемником и пепельницей.
Такой пример как раз разрешается.
Буквально: запрещается создавать объекты производные от более чем одного класса, имеющего реализацию.
Например есть реализованная простая дверь и есть реализованный двигатель.
Приведенный code style не разрешает создавать дверь, производную одновременно от обоих указанных классов.
Хотя разрешает создавать дверь, производную, например, от реализованной двери и от базового абстрактного класса для двигателя.
Если есть простая реализованная дверь и реализованный стеклоподьемник, то рекомендуют создать объект содержащий объекты реализованной двери и реализованного стеклоподьемника.
В случае множественного наследования рекомендуют создать интерфейс стеклоподьемник и сделать новую дверь производной от реализованной двери и интерфейса стеклоподъемника.
Здравствуйте, MShura, Вы писали:
MS>Откуда такие знания?
Смотрел требования в некоторые конторы, делал выводы.
MS>Такой пример как раз разрешается. MS>Буквально: запрещается создавать объекты производные от более чем одного класса, имеющего реализацию. MS>Например есть реализованная простая дверь и есть реализованный двигатель. MS>Приведенный code style не разрешает создавать дверь, производную одновременно от обоих указанных классов. MS>Хотя разрешает создавать дверь, производную, например, от реализованной двери и от базового абстрактного класса для двигателя. MS>В случае множественного наследования рекомендуют создать интерфейс стеклоподьемник и сделать новую дверь производной от реализованной двери и интерфейса стеклоподъемника.
Не уверен, что их требования позволяют несколько интрефейсов для одного класса, хотя подробно не читал.
MS>Если есть простая реализованная дверь и реализованный стеклоподьемник, то рекомендуют создать объект содержащий объекты реализованной двери и реализованного стеклоподьемника.
Здравствуйте, WolfHound, Вы писали:
WH>Здравствуйте, Юрий Жмеренецкий, Вы писали:
WH>>>В системах с GC тут приберется GC. WH>>>В системах без GC все будет сделано сильно иначе. ЮЖ>>GC тут нет, WH>Напомню фразу с которой пошол флейм: WH>
Так что Имею Мнение Хрен Оспоришь что польза от RAII при наличии GC мягко говоря приувеличина.
Если RAII применять только для управления ресурсами(в привычном понимании) то возможно что и преувеличена.
WH>И еще одну: WH>
J>>а уж захват памяти, от которого помогает GC — это еще меньшее подмножество подобных действий.
WH>Чё? Да это 99% случаев использования RAII если не больше.
Еще раз — если RAII применять только для управления ресурсами...
ЮЖ>>а сильно иначе(для исправления этой ситуации) не получится. WH>Зная конкретику как правило получается.
Это и есть конкретика — "добавить указатель в контейнер, при невозможности — удалить". Может быть это сфероконь, но мне интересен метод решения именно этой задачи.
ЮЖ>>Стримы это только пример, ключевой момент я там выделил — восстановление состояния при ошибках (+ их обработка вынесена из основного кода и не бросается в глаза, как try/catch выше). WH>Лично я всегда обходился другими методами.
Какими ? Интересно посмотреть методы. Хотя бы в случае этого примера:
context это компонент со стороны, так же как и funcX(могут кидаться исключениями). Вместо 'int _a' может быть другой тип, интерфейс(а-ля service_provider), и т.п.
Собственно проблема: На время вызова func2 нужно изменить context::_a и при этом обеспечить strong exception guarantee(или 'транзакционность' о которой говорю я и jazzer).
P.S. В контексте обсуждения этот пример концептуально ничем не отличается от io state saver из буста.
Здравствуйте, jazzer, Вы писали:
J>Видишь ли, проверка корректности может быть слишком дорогой и создавать здоровенную структуру только для проверки корректности сообщения, а потом, когда убедились, что сообщение корректно, повторить всю эту же процедуру еще раз на реальном стейте — это просто трата времени, потому что мы ожидаем, что 99.9999% сообщений у нас в системе корректны. J>И гораздо быстрее действовать, как будто сообщение правильное, и в редких случаях некорректного сообщения откатить все изменения, вызванные этим некорректным сообщением.
Зависит от задачи.
Есть несколько очень циничных методов провернуть такой фокус в системе с ГЦ.
J>Это не я задвинул, это вполне устоявшийся термин. А именно: если у тебя есть объект какого-то класса и ты зовешь какой-то его метод, то метод называется транзакционным (другой термин — дает strong exception safety guarantee), если при в случае вылета из метода по исключению состояние объекта не меняется. Basic exception safety guarantee — это когда состояние объекта может измениться, но при этом оно останется корректным (т.е. все инварианты будут выполнены). J>Все тут, кроме тебя, говорят исключительно об этой транзакционности и о том, что RAII помогает именно с этой транзакционностью.
Реализуй на C#(2 или выше) System.Collections.Generic.List<T> это аналог std::vector.
Тогда ты поймешь чего стоит RAII.
Скажу по секрету сделать его реализацию так что бы не иметь strong exception safety guarantee нужно ну очень постараться.
J>Ну что ж я могу поделать с тем, что ты транзакционность понимаешь только в таком узком смысле? J>Хотя, может, хранилище у тебя не обязательно распределенное, а может быть и простой переменной, в которую ты записал 1, а потом надо это дело откатить и вернуть туда 2, которое там было до того? Или у тебя вообще все распределенное, даже инты? И вообще никаких объектов локальных нет?
А зачем мне такие "транзакции"?
J>Я тоже думал, что я написал в удаленном тобой моем тексте именно это и ты эти мои слова прочитал. J>Теперь не уверен.
Я что-то ничего такого там не вижу.
J>Пример в студию, когда RAII неустойчиво к сбоям.
Решение на RAII. См предыдущее сообщение. Там подробно написано.
J>Ну естественно, это верно в случае твоей практики, когда RAII больше ни для чего не применяется J>Было бы странно, если было бы наоборот.
Так оно больше ни для чего и не нужно.
... << RSDN@Home 1.2.0 alpha rev. 745>>
Пусть это будет просто:
просто, как только можно,
но не проще.
(C) А. Эйнштейн
Здравствуйте, Юрий Жмеренецкий, Вы писали:
ЮЖ>Это и есть конкретика — "добавить указатель в контейнер, при невозможности — удалить". Может быть это сфероконь, но мне интересен метод решения именно этой задачи.
В системе с ГЦ такой задачи просто нет.
В системе без ГЦ нужно подумать. Вероятно можно где то сделать совсем не так. Например взять boost::ptr_vector
ЮЖ>context это компонент со стороны, так же как и funcX(могут кидаться исключениями). Вместо 'int _a' может быть другой тип, интерфейс(а-ля service_provider), и т.п. ЮЖ>Собственно проблема: На время вызова func2 нужно изменить context::_a и при этом обеспечить strong exception guarantee(или 'транзакционность' о которой говорю я и jazzer). ЮЖ>P.S. В контексте обсуждения этот пример концептуально ничем не отличается от io state saver из буста.
Объезд кривых либ это отдельная история.
А пример из серии нужности setjmp/longjmp из-за того что с некоторыми кривыми либами (например libjpeg) иначе работать нельзя.
Так вот если либ с такими особенностями нет или есть альтернатива без этих особенностей то и такие выверты не нужны.
... << RSDN@Home 1.2.0 alpha rev. 745>>
Пусть это будет просто:
просто, как только можно,
но не проще.
(C) А. Эйнштейн
Здравствуйте, eao197, Вы писали:
E>Можешь попробовать отформатировать данный фрагмент в соответствии с рекомендациями Романа и посмотреть, что получится (при этом нужно еще уместиться хотя бы в 80 символов ширины текста).
Меня не поняли...
Я только и хотел сказать, что выравнивание, отличное от отступов, следует делать исключительно пробелами. Пример привел, по-видимому, неудачный.
Здравствуйте, WolfHound, Вы писали:
WH>Здравствуйте, Юрий Жмеренецкий, Вы писали:
ЮЖ>>Это и есть конкретика — "добавить указатель в контейнер, при невозможности — удалить". Может быть это сфероконь, но мне интересен метод решения именно этой задачи. WH>В системе с ГЦ такой задачи просто нет. WH>В системе без ГЦ нужно подумать. Вероятно можно где то сделать совсем не так. Например взять boost::ptr_vector
Это просто перенесет реализацию этой задачи в ptr_vector::push_back.
Собственно, сейчас реализация выглядит так(комментарии родные):
void push_back( value_type x ) // strong
{
this->enforce_null_policy( x, "Null pointer in 'push_back()'" );
auto_type ptr( x ); // notrowthis->base().push_back( x ); // strong, commit
ptr.release(); // nothrow
}
WH>Объезд кривых либ это отдельная история. WH>А пример из серии нужности setjmp/longjmp из-за того что с некоторыми кривыми либами (например libjpeg) иначе работать нельзя. WH>Так вот если либ с такими особенностями нет или есть альтернатива без этих особенностей то и такие выверты не нужны.
Т.е. любые примеры отклоняются со словами — "криво, нужно переписать все" ? =)
Переформулирую вопрос — Как при реализации функций в системах с GC(и без него) обеспечивается "strong exception guarantee" ? В С++ один из вариантов — использование RAII.
Здравствуйте, WolfHound, Вы писали:
WH>Есть несколько очень циничных методов провернуть такой фокус в системе с ГЦ.
Ну так расскажи, не томи.
Я всегда рад узнать что-то новое, и особенно неравнодушен к циничным способам.
J>>Это не я задвинул, это вполне устоявшийся термин. А именно: если у тебя есть объект какого-то класса и ты зовешь какой-то его метод, то метод называется транзакционным (другой термин — дает strong exception safety guarantee), если при в случае вылета из метода по исключению состояние объекта не меняется. Basic exception safety guarantee — это когда состояние объекта может измениться, но при этом оно останется корректным (т.е. все инварианты будут выполнены). J>>Все тут, кроме тебя, говорят исключительно об этой транзакционности и о том, что RAII помогает именно с этой транзакционностью. WH>Реализуй на C#(2 или выше) System.Collections.Generic.List<T> это аналог std::vector. WH>Тогда ты поймешь чего стоит RAII. WH>Скажу по секрету сделать его реализацию так что бы не иметь strong exception safety guarantee нужно ну очень постараться.
Можно расшифровать для не знающих C#? Что там такое?
Ну и о реализации вектора вопрос вообще не стоял, вопрос был об использовании — если ты туда что-то положит и если тебе _потом_ надо это откатить.
J>>Ну что ж я могу поделать с тем, что ты транзакционность понимаешь только в таком узком смысле? J>>Хотя, может, хранилище у тебя не обязательно распределенное, а может быть и простой переменной, в которую ты записал 1, а потом надо это дело откатить и вернуть туда 2, которое там было до того? Или у тебя вообще все распределенное, даже инты? И вообще никаких объектов локальных нет? WH>А зачем мне такие "транзакции"?
потому что исключение может вылететь в процессе изменения состояния объекта, на полпути, после чего объект в общем случае находится в состоянии весьма интересном, если не предприняты специальные меры (либо если тебе этот объект более не интересен).
А если специальные меры предприняты — значит, ты обеспечил эту самую транзакционность.
J>>Я тоже думал, что я написал в удаленном тобой моем тексте именно это и ты эти мои слова прочитал. J>>Теперь не уверен. WH>Я что-то ничего такого там не вижу.
мы говорим о транзакции в пределах, в которых действует RAII, так что твой вопрос <как мне поможет RAII в реализации распределенной транзакции — jazzer> эквивалентен вопросу "как мне в этом поможет цикл for/тип double/делегаты C#". Ответ — напрямую никак, слишком низкоуровневое средство.
J>>Пример в студию, когда RAII неустойчиво к сбоям. WH>Решение на RAII. См предыдущее сообщение. Там подробно написано.
Где там написано, что оно неустойчиво к сбоям? Если RAII живет только в рамках процесса и процесс все равно умирает — какая кому разница, что там у него устойчиво, а что — нет?
А если не умирает — не продемонстрировано.
Здравствуйте, Roman Odaisky, Вы писали:
RO>Итак, какую гарантию обеспечивает List(T).Insert?
strong exception safety guarantee те если вылетит исключение то List останется в неизменном состоянии.
public void Insert(int index, T item)
{
if (index > this._size)
{
ThrowHelper.ThrowArgumentOutOfRangeException(ExceptionArgument.index, ExceptionResource.ArgumentOutOfRange_ListInsert);
}
if (this._size == this._items.Length)
{
this.EnsureCapacity(this._size + 1);
}
if (index < this._size)
{
Array.Copy(this._items, index, this._items, index + 1, this._size - index);
}
this._items[index] = item;
this._size++;
this._version++;
}
private void EnsureCapacity(int min)
{
if (this._items.Length < min)
{
int num = (this._items.Length == 0) ? 4 : (this._items.Length * 2);
if (num < min)
{
num = min;
}
this.Capacity = num;
}
}
public int Capacity
{
get
{
return this._items.Length;
}
set
{
if (value != this._items.Length)
{
if (value < this._size)
{
ThrowHelper.ThrowArgumentOutOfRangeException(ExceptionArgument.value, ExceptionResource.ArgumentOutOfRange_SmallCapacity);
}
if (value > 0)
{
T[] destinationArray = new T[value];
if (this._size > 0)
{
Array.Copy(this._items, 0, destinationArray, 0, this._size);
}
this._items = destinationArray;
}
else
{
this._items = List<T>._emptyArray;
}
}
}
}
(С)Reflector
Все так просто именно из-за отсутствия RAII...
ЗЫ А то что мелкософты не написали про OutOfMemoryException так они просто забыли или считали что и так понятно что оно в любой момент вылететь может.
... << RSDN@Home 1.2.0 alpha rev. 745>>
Пусть это будет просто:
просто, как только можно,
но не проще.
(C) А. Эйнштейн
Здравствуйте, WolfHound, Вы писали:
ЮЖ>>Переформулирую вопрос — Как при реализации функций в системах с GC(и без него) обеспечивается "strong exception guarantee" ? В С++ один из вариантов — использование RAII. WH>По разному.
Можно увидеть хоть один из "разных" вариантов(кроме RAII) в случае когда необходим явный откат ?
Или необхдоимость отката — bad design ? (:
Здравствуйте, Roman Odaisky, Вы писали:
RO>Я только и хотел сказать, что выравнивание, отличное от отступов, следует делать исключительно пробелами. Пример привел, по-видимому, неудачный.
RO>
в идеальном редакторе (которого нету, хотя я видел попытки его создать, эту фичу называют rubber tab), _всё_ выравнивание осуществляется табами, а редактор сам вычисляет, на какую именно позицию надо поместить группу строчек с табами.
И тогда если ты заменишь whatever на whatever_else, у тебя визуально сдвинутся все строчки, но при этом код этих строчек не изменится и в diff будет только whatever_else:
Но так как у нас этого нету, да и другие редакторы это не поймут — лучше от табов отказаться вообще.
Другой подход — хранить в файлах только пробелы, и при загрузке автоматически по разным признакам (первый из которых — наличие больше чем одного пробела подряд и аналогично выровненный текст после этой группы пробелов в соседних строчках) вычислять, где имеются в виду резиновые табы, и дальше реагировать на правки юзера соответственно, но сохранять все равно только пробелы.
Пользователь MaximSL отправлен в бан на два дня за:
1) мат,
2) использование падоначьей лексики,
3) излишнее цитирование (оставляйте в своём ответе только то, что необходимо для понимания вашего ответа. В частности нужно стирать лестницы из "Здравствуйте, ...").
В качестве смягчающего обстоятельства принималась во внимание его недавняя регистрация на форуме.
MS>>Хотя разрешает создавать дверь, производную, например, от реализованной двери и от базового абстрактного класса для двигателя. MS>>В случае множественного наследования рекомендуют создать интерфейс стеклоподьемник и сделать новую дверь производной от реализованной двери и интерфейса стеклоподъемника.
J>А какой смысл в таких извращениях, если можно просто воспользоваться простым и понятным множественным наследованием?
Этот подход напоминает COM. Интерфейсы отдельно, реализации отдельно.
MS>>Этот подход напоминает COM. Интерфейсы отдельно, реализации отдельно.
J>Т.е. если у меня есть два реализованных класса А и В, в каждом по двадцать полей и методов, и есть третий класс С, который _является_ и А и В, то вместо того, чтоб просто написать struct C : A,B {}, я должен буду либо включить эти классы как члены и написать 40 тупых функций-трамплинов?
Странно, почему не 100 методов. 40 это как-то несерьезно.
J>А если эти методы еще и вертуальные и я их хочу перекрыть... J>А если еще я хочу передавать указатели на базовые типы, причем так, чтоб по ним можно было грохнуть объект....
J>И весь этот геморрой ради того, чтоб напоминало СОМ?
Там же черным по белому написано
Only very rarely is multiple implementation inheritance actually useful
Если у Вас 40, 100 или даже 200 методов в классе, то возможно наследование будет как раз тот самый 'rare case'.
Здравствуйте, MShura, Вы писали:
MS>>>Этот подход напоминает COM. Интерфейсы отдельно, реализации отдельно.
Кстати, в СОМ наследования нет вообще, есть только запросы QueryInterface, так что тут сложно говорить, напоминает оно СОМ или нет.
MS>Если у Вас 40, 100 или даже 200 методов в классе, то возможно наследование будет как раз тот самый 'rare case'.
Я пока что не видел нормального аргумента даже для написания пяти функций вместо простого и понятного множественного наследования.
Это все равно что: "умножение эквивалентно сложению, так что просто сложи n раз то, что тебе надо, и получишь умножение. Но если у тебя такой редкий случай, что надо умножить на 200, то так и быть, умножай".
MS>>>>Этот подход напоминает COM. Интерфейсы отдельно, реализации отдельно.
J>Кстати, в СОМ наследования нет вообще, есть только запросы QueryInterface, так что тут сложно говорить, напоминает оно СОМ или нет.
Напоминает тем, что как и в COM интерфейс отдельно и реализация отдельно.
MS>>Если у Вас 40, 100 или даже 200 методов в классе, то возможно наследование будет как раз тот самый 'rare case'.
J>Я пока что не видел нормального аргумента даже для написания пяти функций вместо простого и понятного множественного наследования.
Например в моей практике gcc при компиляции драйверов для Mac OS отказывался компилить, если видел множественное наследование, даже если второй наследуемый класс был простой класс запрещающий копирование.
Google конечно не пишет драйверов для Mac, но возможно на каких-то целевых для них платформах компилятор просто не поддерживает множественное наследование.
Здравствуйте, MShura, Вы писали:
J>>Я пока что не видел нормального аргумента даже для написания пяти функций вместо простого и понятного множественного наследования.
MS>Например в моей практике gcc при компиляции драйверов для Mac OS отказывался компилить, если видел множественное наследование, даже если второй наследуемый класс был простой класс запрещающий копирование.
MS>Google конечно не пишет драйверов для Mac, но возможно на каких-то целевых для них платформах компилятор просто не поддерживает множественное наследование.
А, ну так бы сразу и сказал, что фича просто-напросто не поддерживается компилятором.
А то СОМ, двери...
Здравствуйте, WolfHound, Вы писали:
RO>>Итак, какую гарантию обеспечивает List(T).Insert? WH>strong exception safety guarantee те если вылетит исключение то List останется в неизменном состоянии.
WH> this._size++;
И всё же, что произойдет, если _size = 2³²-1?
WH>Все так просто именно из-за отсутствия RAII...
Тогда уже из-за отсутствия бросающихся конструкторов копий
Здравствуйте, Roman Odaisky, Вы писали:
RO>Здравствуйте, WolfHound, Вы писали:
RO>>>Итак, какую гарантию обеспечивает List(T).Insert? WH>>strong exception safety guarantee те если вылетит исключение то List останется в неизменном состоянии.
WH>> this._size++; RO>И всё же, что произойдет, если _size = 2³²-1?
By default, if an expression produces a value that is outside the range of the destination type, constant expressions cause compile-time errors, and non-constant expressions are evaluated at run-time and raise exceptions. However, the checked keyword can be used to enable checking if it is suppressed globally by compiler options or environment configuration.
WH>>Все так просто именно из-за отсутствия RAII... RO>Тогда уже из-за отсутствия бросающихся конструкторов копий
.NET Framework 2.0 представляет Ограниченные области выполнения (Constrained Execution Regions – CER), которые налагают ограничения как на среду выполнения, так и на разработчика.
...
Чтобы среда выполнения подготовила CER, ей должно быть известно, что код этой CER и схема вызываемых функций поддерживают ограничения, необходимые для выполнения в CER. Для этого .NET Framework предоставляет ReliabilityContractAttribute (атрибут контракта надежности) в пространстве имен System.Runtime.ConstrainedExecution.
...
Для корневых методов схемы вызываемых функций CER допустимыми являются только три комбинации значений Cer и Consistency
[ReliabilityContract(Consistency.MayCorruptInstance, Cer.MayFail)]
[ReliabilityContract(Consistency.WillNotCorruptState, Cer.MayFail)]
[ReliabilityContract(Consistency.WillNotCorruptState, Cer.Success)]
Первая показывает, что в исключительных условиях метод может дать сбой, но в самом худшем случае он повредить лишь конкретный экземпляр; домен приложения и состояние всего процесса останутся нетронутыми. Вторая показывает, что метод может дать сбой, но даже в этом случае все состояние по-прежнему будет действительным. Это соответствует тому, что сообщество C++-разработчиков называет «строгая гарантия исключения», имея ввиду, что действие завершается или дает сбой без негативных побочных эффектов или формирования исключения.
...
(c)Stephen Toub – технический редактор журнала «MSDN Magazine» http://www.vbnet.ru/articles/showarticle.aspx?id=209
Определение строгой гарантии несколько неточно, ну да ладно.
Далее:
So, I wanted to have a look on Array.Copy(), this is how it shows in .NET Refelctor:
[ReliabilityContract(Consistency.MayCorruptInstance, Cer.MayFail)]
public static void Copy(Array sourceArray, int sourceIndex,
Array destinationArray, int destinationIndex, int length)
{
Copy(sourceArray, sourceIndex, destinationArray, destinationIndex, length, false);
}
Добрый вечер, night beast, Вы писали про Google C++ Style Guide.
В целом несомненный зачот, правда несколько пунктов не очень.
define guard — это потому шо убогие компиляторы не знают pragma once
Про аргументы со значениями по умолчанию — не согласен категорически. Не фиг копи-пэйстить то, шо ты не знаешь как работает.
Integer Types — а шо делать если если нужен тип integer 8 bit или больше (например цикл от 0 до 100), но который будет работать максимально быстро и на 32bit и на 64-bit? (т.е. шоб число было 32-bit на win32 и 64-bit на win64).
Line length — щас спецом посмотрел, при традиционно открытом тулбаре "solution explorer" без горизонтального скроллинга на меньшем из 2-х мониторов влезает 170 символов (MSDEV 2005, шрифты и DPI по умолчанию). Это всё-таки побольше чем 80, да и кто в наше время смотрит на 80x25 текстовый режим?
int n; // Bad — meaningless. — если эта n используется только в следующих 5-10 строках кода, то фсё OK.
Всё остальное — ППКС! Особенно про исключения и RTTI.
Добрый вечер, jazzer, Вы писали:
J>Кстати, в СОМ наследования нет вообще, есть только запросы QueryInterface, так что тут сложно говорить, напоминает оно СОМ или нет.
Я понимаю, шо это не имеет отношения к вашей беседе с MShura Тем не менее, хочу заметить, шо в COM есть агрегирование, которое позволяет в некоторых случаях унаследовать не тока интерфейсы, но и реализацию.
Здравствуйте, Константин, Вы писали:
К>Добрый вечер, night beast, Вы писали про Google C++ Style Guide.
К>В целом несомненный зачот, правда несколько пунктов не очень. К>define guard — это потому шо убогие компиляторы не знают pragma once
Интересно, если сравнить два компилятора, один тот самый, который про эту прагму знает с младенчества, но доступен по сути только для одной платформы, и другой, который не знает, зато существует для практически любой платформы, какой из них следует называть убогим? Кстати, этот второй компилятор тоже в курсе про эту прагму с какой-то достаточно древней версии. Что не отменяет факта, что какой-то код нужно будет компилировать под нечто, для чего существует ровно один компилятор, который, сюрприз, не в курсе про какие-то там прагмы? К>Line length — щас спецом посмотрел, при традиционно открытом тулбаре "solution explorer" без горизонтального скроллинга на меньшем из 2-х мониторов влезает 170 символов (MSDEV 2005, шрифты и DPI по умолчанию). Это всё-таки побольше чем 80, да и кто в наше время смотрит на 80x25 текстовый режим?
А Кнута надо бы почитать, что ли. Для человека наибольшая комфортная ширина строки текста — примерно 66 символов. Видел когда-нибудь газету, где полосы занимали бы всю ширину листа? Как думаешь, почему? К>Всё остальное — ППКС! Особенно про исключения и RTTI.
Каменный век
MS>>>>>Этот подход напоминает COM. Интерфейсы отдельно, реализации отдельно.
[snip]
MS>Например в моей практике gcc при компиляции драйверов для Mac OS отказывался компилить, если видел множественное наследование, даже если второй наследуемый класс был простой класс запрещающий копирование.
MS>Google конечно не пишет драйверов для Mac, но возможно на каких-то целевых для них платформах компилятор просто не поддерживает множественное наследование.
это вряд-ли, у них ведь не запрещено множественное наследование само по себе, а только множественное наследование от классов с реализацией.
struct IFoo
{
virtual void foo() = 0;
};
struct IBar
{
virtual void bar() = 0;
};
class Foo : public IFoo
{
public:
virtual void foo() {}
};
class Bar : public IBar
{
public:
virtual void bar() {}
};
class FooBar1 : public IFoo, public IBar // так можно
{
public:
virtual void foo() {}
virtual void bar() {}
};
class FooBar2 : public Foo, public Bar // а так уже нет
{
};
если бы они ориентировались на компиляторы без множественного наследования, то запрещали бы оба варианта, да и возможность исключений из этого правила, тоже говорит, что дело не в компиляторах.
Вообще странно, вроде как они стараются хороших разработчиков набирать, а потом дают им правила рассчитанные на новичков, которые могут учудить что-нибудь с множественным наследованием или еще чем-нибудь.
The last good thing written in C was Franz Schubert's Symphony No. 9.
Re[3]: Google C++ Style Guide
От:
Аноним
Дата:
10.07.08 03:49
Оценка:
Здравствуйте, landerhigh, Вы писали:
L>Здравствуйте, Константин, Вы писали:
К>>Добрый вечер, night beast, Вы писали про Google C++ Style Guide.
К>>В целом несомненный зачот, правда несколько пунктов не очень. К>>define guard — это потому шо убогие компиляторы не знают pragma once L>Интересно, если сравнить два компилятора, один тот самый, который про эту прагму знает с младенчества, но доступен по сути только для одной платформы, и другой, который не знает, зато существует для практически любой платформы, какой из них следует называть убогим? Кстати, этот второй компилятор тоже в курсе про эту прагму с какой-то достаточно древней версии.
А почему ты думаешь, что он этот другой компилятор назвал убогим, если он "в курсе про эту прагму с какой-то достаточно древней версии"?
L> Что не отменяет факта, что какой-то код нужно будет компилировать под нечто, для чего существует ровно один компилятор, который, сюрприз, не в курсе про какие-то там прагмы?
Здравствуйте, Константин, Вы писали:
К>Я использую C++ исключения только в "одноразовых" проектах (особенно удобно для работы с COM), но никогда в production-системах.
А в свободное от работы время пишете фельетоны для joelonsoftware?
SObjectizer: <микро>Агентно-ориентированное программирование на C++.
Здравствуйте, _Jane_, Вы писали:
_J_>Не подскажете, в каких случаях это может пригодиться? Как именно расставляются пробелы и табуляции, систематически? _J_>Дело в том, что если их расставлять как попало, то кому-то другому, который будет смотреть этот код, придётся временно выставить размер табуляции в тот, который использовался при написании кода, что бывает не удобно.
Правило номер 1: Либо табулятор является первым символом (знаком) в строке, либо ему предшествует другой табулятор.
Правило номер 2: Для выравнивания с текстом нужно использовать пробел (сорри, невнятно, см. пример)
Здравствуйте, Константин, Вы писали:
К>Здравствуйте, remark, Вы писали:
E>>>Феерический бред.
R>>Полностью поддерживаю. Это похоже на мнение человека, который 10 лет писал на С, а потом увидел исключения, и попытался их использовать как будто это ещё один способ локальной передачи управления, аналогичный while/if/goto.
К>Ты собираешься спорить с тем что исключения это ещё один способ передачи управления? Только у while/if и прочих есть скобочки и их видно, а пролетающее мимо исключение ни хрена не видно.
С чего ты взял, что кто-то с этим собирается спорить?
К>У goto и исключений много общего. Обоих не видно читая код, и оба отнюдь не локальная передача управления, а вполне себе глобальная. Именно из-за этих свойств goto не рекомендуется к использованию. Исключения некоторые рекомендуют, хотя от goto они отличаются только тем шо аккуратнее обходятся с данными на стеке (зовёт деструкторы), и ещё тем шо переход выполняется не на метку а Х3 куда.
goto передает управление в рамках одной функции, с каких это пор он стал глобальным? Ты, кстати, очень верно подметил важное отличие исключений от goto. Для goto нужно указывать куда происходит переход, а для исключений место... ммм... "перехода" определяется внешним кодом, а не тем который кидает исключение. Т.о. коду, в котором произошла исключительная ситуация не нужно ничего знать о том кто, как и где эту исключительную ситуацию обработает. По сути, это применение принципа сокрытия информации, описанного еще в 70-х годах в работах Парнаса, к обработке ошибок.
К>Я использую C++ исключения только в "одноразовых" проектах (особенно удобно для работы с COM), но никогда в production-системах.
К>Да, приходится постоянно писать if(FAILED(hr)), это минус. К>Зато уже при написании следующей строчки приходится думать, что же надо в этом случае делать: какие ресурсы освобождать, надо ли извещать пользователя и если надо то как, что писать в лог, или может просто вернуть код ошибки выше и обрабатывать его там, и т.п. И вот решение подобных вопросов очень полезно и для качества кода, для качества продукта.
Согласен, решение этих вопросов очень важно для качества продукта, только как их решению способствует отказ от исключений?
R>>Не говоря уже о том, что в Java/C# такой подход вообще не будет работать, т.к. потенциально практически каждая строчка кода бросает исключения. К>В этом форуме речь про C++, большая часть людей использует C++ шоб писать native code. В Java/C# пускай бросают (всё равно приходится ловить и обрабатывать исключения брошенные соответственно JRE/.NET), сам в обоих языках и бросал, и ловил.
А причем тут native или не-native код? Почему в Java и C# кидать исключения нормально, а в С++ это уже плохо??? При чем тут исключения JRE/.NET??? Где во всех твоих предыдущих аргументах против исключений используются особенности C++?
The last good thing written in C was Franz Schubert's Symphony No. 9.
Re[22]: Google C++ Style Guide
От:
Аноним
Дата:
11.07.08 07:46
Оценка:
Здравствуйте, Roman Odaisky, Вы писали:
RO>Задача. Добавить элемент в два хранилища. Обе операции добавления могут завершиться неудачей. Обеспечить строгую гарантию.
RO>Вариант. То же для N хранилищ.