Re[16]: Google C++ Style Guide
От: WolfHound  
Дата: 06.07.08 13:54
Оценка: -1
Здравствуйте, 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) А. Эйнштейн
Re[16]: Google C++ Style Guide
От: WolfHound  
Дата: 06.07.08 13:54
Оценка:
Здравствуйте, 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.

Кешь не обновляют.
Никогда.
Его инвалидируют.

Причем правильные пацаны делают это так:
ClearCacheAspect
Автор: ili
Дата: 19.05.08


Дальше в статье тоже ничего интересного.
Память подчистить или там файлик закрыть. Тоже мне невидаль. Память вобще GC подбирает, а файлик можно и using'ом закрыть.
... << RSDN@Home 1.2.0 alpha rev. 745>>
Пусть это будет просто:
просто, как только можно,
но не проще.
(C) А. Эйнштейн
Re[16]: Google C++ Style Guide
От: WolfHound  
Дата: 06.07.08 13:54
Оценка:
Здравствуйте, Юрий Жмеренецкий, Вы писали:

ЮЖ>Например для исправления этой ситуации:

ЮЖ>
ЮЖ>std::vector<int*> vec;
ЮЖ>vec.push_back(new int); 
ЮЖ>

В системах с GC тут приберется GC.
В системах без GC все будет сделано сильно иначе.

ЮЖ>Другой пример, из буста: "io state savers"

В данном случае сам по себе дизайн стимов нужно очень сильно переделать.
У них вобще много странных особенностей включая эту.
... << RSDN@Home 1.2.0 alpha rev. 745>>
Пусть это будет просто:
просто, как только можно,
но не проще.
(C) А. Эйнштейн
Re[17]: Google C++ Style Guide
От: jazzer Россия Skype: enerjazzer
Дата: 06.07.08 14:30
Оценка:
Здравствуйте, WolfHound, Вы писали:

WH>Здравствуйте, Юрий Жмеренецкий, Вы писали:


ЮЖ>>Например для исправления этой ситуации:

ЮЖ>>
ЮЖ>>std::vector<int*> vec;
ЮЖ>>vec.push_back(new int); 
ЮЖ>>

WH>В системах с GC тут приберется GC.
WH>В системах без GC все будет сделано сильно иначе.

GC приберется только относительно выделения памяти.
Элемент из массива удалять кто будет?
jazzer (Skype: enerjazzer) Ночная тема для RSDN
Автор: jazzer
Дата: 26.11.09

You will always get what you always got
  If you always do  what you always did
Re[18]: Google C++ Style Guide
От: WolfHound  
Дата: 06.07.08 14:38
Оценка: -1
Здравствуйте, jazzer, Вы писали:

J>GC приберется только относительно выделения памяти.

J>Элемент из массива удалять кто будет?
Опять сферический массив в вакууме?
... << RSDN@Home 1.2.0 alpha rev. 745>>
Пусть это будет просто:
просто, как только можно,
но не проще.
(C) А. Эйнштейн
Re[17]: Google C++ Style Guide
От: jazzer Россия Skype: enerjazzer
Дата: 06.07.08 15:15
Оценка: 1 (1) +2
Здравствуйте, 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. Что бы у тебя там ни было распределенное, все равно все сводится к одиночным процессам и к функциям и данным, которые работают в контексте одного процесса. То, что они, работая сообща, могут реализовать функционал для распределенных транзакций, ни для кого не секрет, но все равно куча кода у тебя работает внутри одного процесса и не имеет дела с распроделенными высями. Зачем при написании этого кода отказываться от возможностей, предоставляемых языком, и искуственно ограничивать область применения до управлением памятью в куче...
jazzer (Skype: enerjazzer) Ночная тема для RSDN
Автор: jazzer
Дата: 26.11.09

You will always get what you always got
  If you always do  what you always did
Re[19]: Google C++ Style Guide
От: jazzer Россия Skype: enerjazzer
Дата: 06.07.08 15:17
Оценка:
Здравствуйте, WolfHound, Вы писали:

WH>Здравствуйте, jazzer, Вы писали:


J>>GC приберется только относительно выделения памяти.

J>>Элемент из массива удалять кто будет?
WH>Опять сферический массив в вакууме?
нет, совершенно конкретный массив по имени vec из сообщения Юрия.
jazzer (Skype: enerjazzer) Ночная тема для RSDN
Автор: jazzer
Дата: 26.11.09

You will always get what you always got
  If you always do  what you always did
Re[17]: Google C++ Style Guide
От: Юрий Жмеренецкий ICQ 380412032
Дата: 06.07.08 15:48
Оценка:
Здравствуйте, WolfHound, Вы писали:

ЮЖ>>Например для исправления этой ситуации:

ЮЖ>>
ЮЖ>>std::vector<int*> vec;
ЮЖ>>vec.push_back(new int); 
ЮЖ>>

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;
}

и
{
  std::auto_ptr<int> ptr(new int());
  vec.push_back(ptr.get());                    
  ptr.release();                     // commit
  // ~auto_ptr rollback
}

Здесь не просто RAII, здесь ключевой момент — в том что с помощью него можно не только освобождать ресурсы в деструкторах, но и моделировать хоть какую-то транзакционность. Имхо, применение целесообразно в случаях с относительно простым rollback'ом, причем критерии простоты могут быть весьма разными.

ЮЖ>>Другой пример, из буста: "io state savers"

WH>В данном случае сам по себе дизайн стимов нужно очень сильно переделать.
WH>У них вобще много странных особенностей включая эту.
Стримы это только пример, ключевой момент я там выделил — восстановление состояния при ошибках (+ их обработка вынесена из основного кода и не бросается в глаза, как try/catch выше).
Re: Google C++ Style Guide
От: dandy  
Дата: 06.07.08 16:09
Оценка: :)
Здравствуйте, night beast, Вы писали:

NB>Google C++ Style Guide


Процентов 30 наивно.
Re[4]: Google C++ Style Guide
От: c-smile Канада http://terrainformatica.com
Дата: 06.07.08 17:22
Оценка:
Здравствуйте, 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++ я бы не стал.
Это мое имхо "взглянутое со стороны".
Re[17]: Google C++ Style Guide
От: alexeiz  
Дата: 06.07.08 19:48
Оценка: +2 -1 :)
Здравствуйте, WolfHound, Вы писали:

WH>Кешь не обновляют.

WH>Никогда.
WH>Его инвалидируют.

Вот это ты классно! Одним. Словом. Всю статью разбил. Смешно просто. У тебя установка такая, не принимать аргументы собеседников не при каких условиях? "Кэш не обновляют, а другое решение ваще не масштабируется, поэтому нигде ничего откатывать не нужно, и не приводите мне ваших сферосценариев в вакууме!" Тяжелый случай.
Re[5]: Google C++ Style Guide
От: CreatorCray  
Дата: 06.07.08 20:39
Оценка:
Здравствуйте, c-smile, Вы писали:

CS>А какие такие C++ проекты от Google общественности известны?

Точно: Google Earth, MapReduce,
Не уверен на 100% : Google Talk, Google Desktop, Picasa
... << RSDN@Home 1.1.4 stable SR1 rev. 568>>
Re[3]: Google C++ Style Guide
От: CreatorCray  
Дата: 07.07.08 06:30
Оценка:
Здравствуйте, Erop, Вы писали:

E>Интересно, а как они с RAII при этом рабоьают? Неудобно же.

Нормально работают.
... << RSDN@Home 1.1.4 stable SR1 rev. 568>>
Re[20]: Google C++ Style Guide
От: Roman Odaisky Украина  
Дата: 07.07.08 06:54
Оценка: :)
Здравствуйте, Sergey, Вы писали:

S>_Jane_ пишет:


>>> > А смесь пробелов и табуляции -- это вообще как свидетельство того, что

>>> > человек не владеет инструментами, которыми пользуется (не способен
>>> > настроить свой редактор/IDE).
>>
>> S>А я вот вполне осознанно пробелы с табуляцией мешаю Не знал, что это
>> S>может кого-то бесить...
>>
>> Не подскажете, в каких случаях это может пригодиться? Как именно
>> расставляются пробелы и табуляции, систематически?

S>Везде — табуляции, но при переносе части выражения на следующую иногда

S>приходится добивать пробелами.

if(cond)
→   {
→   →   someFunction(param1, param2, param3,
→   →   ·············param4, param5);
→   }

так?

Так и нужно делать.

>> Дело в том, что если их расставлять как попало, то кому-то другому,

>> который будет смотреть этот код, придётся временно выставить размер
>> табуляции в тот, который использовался при написании кода, что бывает не
>> удобно.

S>Эта проблема появится не раньше, чем у нас в конторе заведётся человек,

S>который выставит размер табуляции отличный от 4 и начнёт на это
S>жаловаться. Пока таких не было.

А это — очень плохой подход. Из той же серии, что и «оставим как есть, пока не придет человек с броузером, отличным от Microsoft Internet Explorer, и не начнет жаловаться».
До последнего не верил в пирамиду Лебедева.
Re[21]: Google C++ Style Guide
От: eao197 Беларусь http://eao197.blogspot.com
Дата: 07.07.08 07:00
Оценка: +1
Здравствуйте, Roman Odaisky, Вы писали:

S>>Везде — табуляции, но при переносе части выражения на следующую иногда

S>>приходится добивать пробелами.

RO>
RO>→   if(cond)
RO>→   {
RO>→   →   someFunction(param1, param2, param3,
RO>→   →   ·············param4, param5);
RO>→   }
RO>

RO>так?

RO>Так и нужно делать.


За выравнивание под определенную границу пробелами -- расстрел!
За выравнивание параметров под открывающую скобку -- расстрел!

У желающих возражать есть выбор:

1. Либо сопровождать код вида:
call_function_with_very_long_name( first_argument,
                                   call_another_function_for_second_argument( param1,
                                                                              call_yet_another_function() ),
                                   some_expression * as / third - argument );


2. Застрелиться!


SObjectizer: <микро>Агентно-ориентированное программирование на C++.
Re[22]: Google C++ Style Guide
От: jazzer Россия Skype: enerjazzer
Дата: 07.07.08 07:11
Оценка:
Здравствуйте, eao197, Вы писали:

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. Застрелиться!


стреляться не хочу, так что выбираю сопровождать

а ты-то что предлагаешь для повышения читабельности?
jazzer (Skype: enerjazzer) Ночная тема для RSDN
Автор: jazzer
Дата: 26.11.09

You will always get what you always got
  If you always do  what you always did
Re[21]: Google C++ Style Guide
От: jazzer Россия Skype: enerjazzer
Дата: 07.07.08 07:14
Оценка:
Здравствуйте, Roman Odaisky, Вы писали:

RO>
RO>→   if(cond)
RO>→   {
RO>→   →   someFunction(param1, param2, param3,
RO>→   →   ·············param4, param5);
RO>→   }
RO>

RO>так?

RO>Так и нужно делать.


Для этого нужен очень продвинутый редактор, каковых я не наблюдаю — у всех реализаций этой фичи всегда была лажа в том или ином месте.

так что пока что пробелы — это самый надежный и переносимый вариант для отступов.

RO>А это — очень плохой подход. Из той же серии, что и «оставим как есть, пока не придет человек с броузером, отличным от Microsoft Internet Explorer, и не начнет жаловаться».


+1
jazzer (Skype: enerjazzer) Ночная тема для RSDN
Автор: jazzer
Дата: 26.11.09

You will always get what you always got
  If you always do  what you always did
Re[23]: Google C++ Style Guide
От: eao197 Беларусь http://eao197.blogspot.com
Дата: 07.07.08 07:24
Оценка: +2
Здравствуйте, 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 );


Чтобы не быть голословным, вот пример из проекта, который я пишу прямо сейчас:
so_add_destroyable_traits(
        new so_msg_templ_postman_t< msg_send_finish >(
                so_query_name(),
                "msg_send_finish",
                and_analyzer(
                        dest_equality_analyzer( 
                                mbox_dest_t( cfg.m_listening_mbox ) ),
                        not_rerouted_by_analyzer( so_query_name() ) ),
                cfg.m_interception_priority,
                intercept_msg ) );

Можешь попробовать отформатировать данный фрагмент в соответствии с рекомендациями Романа и посмотреть, что получится (при этом нужно еще уместиться хотя бы в 80 символов ширины текста).


SObjectizer: <микро>Агентно-ориентированное программирование на C++.
Re[6]: Google C++ Style Guide
От: c-smile Канада http://terrainformatica.com
Дата: 07.07.08 07:30
Оценка:
Здравствуйте, 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");
}


взято отсюда: http://labs.google.com/papers/mapreduce.html
Re[2]: Google C++ Style Guide
От: MShura  
Дата: 07.07.08 07:50
Оценка: +1
NB>>Google C++ Style Guide

D>Процентов 30 наивно.


Если так рассуждать, то в ПДД вообще все наивно.

— Ведь очевидно, что если на перекрестке никого нет, то ехать можно при любом свете
— 60 км/час по населенному пункту это очень мало
— Зачем уступать пешеходам, если они вас не догонят?
— Если очень надо, то можно развернуться в любом месте
и т.д.
Никто не спорит, что есть уроды способные нарушать все правила сразу


тут уже где-то писали, что ПДД написаны кровью.
Думаю, что этот guide написан опытом ведения больших проектов
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.