Pull to refresh

Comments 354

Земля – крестьянам!
Заводы – рабочим!
Планету — хакерам!!!
Сишникам — НСР
(Народная Сишная Республика)
уже давно. не про программистов, но всё же: у нас в новостройке есть СС ИГ — совет собственников инициативная группа :)
В Новосибирске есть ИГиЛ СО РАН, с отделом взрывных процессов https://ru.wikipedia.org/wiki/%D0%98%D0%BD%D1%81%D1%82%D0%B8%D1%82%D1%83%D1%82_%D0%B3%D0%B8%D0%B4%D1%80%D0%BE%D0%B4%D0%B8%D0%BD%D0%B0%D0%BC%D0%B8%D0%BA%D0%B8_%D0%B8%D0%BC%D0%B5%D0%BD%D0%B8_%D0%9C._%D0%90._%D0%9B%D0%B0%D0%B2%D1%80%D0%B5%D0%BD%D1%82%D1%8C%D0%B5%D0%B2%D0%B0_%D0%A1%D0%9E_%D0%A0%D0%90%D0%9D
Может, тогда Сишная Народная Республика? СНР даже удобнее произносить. Ну и фаны Marvell поймут :)
People's Republic of C
Autonomous Republic of C++
Линуса — в президенты!
Столмана — в прокуроры!
Балмера — в жириновские!

Боже упаси. Он тупо бизнесмен. Где бабло, там и он.

Для полноты надо рекламу на Brainfuck рядом разместить
*Нужна работа и есть умения – иди в Stork.
Ваш Кэп.
Не соглашусь, там это не написано. То что вы что-то придумали, ничего не меняет.
если (нужна_работа И есть_навыки) {
    иди_в _1С
}
Если НужнаРабота И ЕстьНавыки Тогда
ИдиВ1С;
КонецЕсли
РАПИРА же!

https://ru.wikipedia.org/wiki/%D0%A0%D0%B0%D0%BF%D0%B8%D1%80%D0%B0_%28%D1%8F%D0%B7%D1%8B%D0%BA_%D0%BF%D1%80%D0%BE%D0%B3%D1%80%D0%B0%D0%BC%D0%BC%D0%B8%D1%80%D0%BE%D0%B2%D0%B0%D0%BD%D0%B8%D1%8F%29
Для этого нужен дипломированный переводчик с Си на русский. Вы такого знаете?
Увы, нет.
Зато знаю множество толковых переводчиков с русского на Си
В антивирусных компаниях таких можно найти.
В данном контексте неизвестно что означают переменные и каковы их текущие значения и как они связаны с входными данными. Поэтому судить о том, что обозначает данная СИ-фраза не представляется возможным вообще.
Очевидно, что данные переменные определяют, есть ли у кого-то скилл, и нужна ли ему работа. А от текущих значений зависит, пойдет ли этот кто-то на Stock.
Мне почему-то все предельно ясно. Что я делаю не так?
Вы слишком доверяете названиям переменных.

int need_job = 14;
struct war* have_skill = (struct war*) malloc(16);
Stork: need_job += 'a';
if (need_job && have_skill) {
goto Stork;
}

Как-то так, например
Все дело в том, что это лишь имена переменных, обозвать их можно как угодно.
Вот ФАС и требует обозвать их на русском.
Хотя, если рассуждать логически, сравнивать человеческую речь и яык программирования — некорректно. Это же набор инструций и все. Это даже близно непохоже на язык. «Языком» они были обозваны в стародавние времена, чтоб обозначить тот факт, что программист может общаться с машиной. Только это нифига не общение. Ведь общение подразумевает двустороннюю комуникацию. Но с компьютерами двусторонняя комуникация невозможна, так как все «ответы» уже заранее подготовленны программистом.
Если хозяин отдает команду рабам на человеческом языке, а те просто молча выполняют — это не общение?
Некудышный пример. Компьютер не обладает самоосознанием. А рабы каждый раз делают выбор, подчиниться или схватить наказание.
Нет, они же ему не отвечают, не возражают, хозяин от рабов вообще ответа не ждет, откровений тоже. Сплошной императив.
А разве в C допустимы unicode имена?
Человек выше сказал «обозвать их можно как угодно».
А как вы поняли, что это С, а не С++?
В С++ допустимы unicode имена, если компилятор позволит. Компилятор от MS позволяет…
UFO just landed and posted this here
Компилятор из Visual Studio умеет юникод.
Угу

#define esli if
#define poshel_v goto

esli (nuzhna_rabota && est_znaniy) {
poshel_v Stork;
}
Это лишь предположение.
Быть уверенным в том, что записано в переменную и записано ли в нее что-либо мы знать не можем.
А каков данный контекст? И с чего вы вообще взяли, что это «СИ-фраза»? Потому что похоже?

Точно так же похоже, что словами «need_job» и «have_skill» авторы хотели обозначить «требуется работа» и «имеется навык».

И эти размышления не определяют, как реклама должна была бы выглядеть по закону. Это всего лишь ответ на ваш вопрос «Каким мог бы быть перевод?».
Если верно, что «требуется работа» и «имеется навык», то перейти к Сторк
Если (НужнаРабота И ЕстьНавыки) тогда
Перейти ~Stork;
КонецЕсли;
Наличие кириллицы не делает этот текст написанным на русском языке. В противном случаем на КонецЕсли может возбудится уже не ФАС, а Роскомнадзор. И придётся запрещать 1С по всей стране и возвращаться к книгам бухучёта.
В 1С нет аналога команды перехода goto.
В 1C команда Перейти ~Метка это и есть goto
Упс! Действительно есть, век живи — век учись.
«Перейти» это не та вещь которую стоит знать в 1с.
Пример у них убойный с бесконечным циклом, из которого не факт, что есть выход:

Пока Истина Цикл
Для Каждого Элемент Из МассивЭлементов Цикл
Если ВыполнениеУсловия(Элемент) Тогда
Перейти ~ВыходИзДвойногоЦикла;
КонецЕсли;

КонецЦикла;
КонецЦикла;
~ВыходИзДвойногоЦикла:
// продолжение вычислений

Оторвать руки и «Перейти ~ВыходИзДвойногоЦикла;» заменить на «Прервать».
Ага, только вот, Прервать из двух вложенных циклов не выведет. )

Ну я думаю, что они оператор безусловного перехода на метку сделали для «полноты» языка. Так то они его не используют вообще.
Обфускаторы зато его широко используют, между прочим :)
1С вообще, это не та вещь, которую стоит знать :)
Судя по размерам предлагаемых на HH зарплат — не могу так утверждать. :)
Кому? Почему?
К чему такие категоричные утверждения?
Не, нормальная платформа для реализации бизнес логики.
Не согласен. Как то мне попалась работа «всего на 5 минут», где нужно было добавить условие по которому из 5-ой циклической вложенности требовалось попасть на уровень второго циклы. При этом кода было на 2-3 листа — анализировать и рефакторить можно было бы целый день. Но зачем, если за это платить никто не будет, а ты видишь этот говнокод в первый и последний раз в жизни? Вот тут знание про переход по меткам очень помогло.
скорее «Перейти ~куда_угодно_только_не_в_сторк»
Тоже была такая мысль. Ну а вообще вариантов то много: РАПИРА, Кумир… Если поискать, то еще можно чего-нибудь найти.
В конце-концов, что мешало им сделать просто блок-схему! :)
Разве одного языка достаточно для того что бы считать себя единым народом?
Разве главное не происхождение?
«Этничность можно представить как форму общественной организации культурных различий, состоящей из тех характеристик, которые сами члены этнической общности считают для себя значимыми и которые лежат в основе их самосознания. К этим характеристикам относится также обладание одним или несколькими общими названиями, общие элементы культуры, представление об общем происхождении и, как следствие, наличие общей исторической памяти.…

Определение этничности строится также на основе культурной самоидентификации этнической общности по отношению к другим общностям (этническим, общественным, политическим), с которыми она находится в фундаментальных связях.» https://ru.wikipedia.org/wiki/Этнос

«Этнос — исторически сложившаяся этническая общность — племя, народность, нация.

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

Общей исторической памятью, надо полагать, является git log ядра linux?

Это будет религиозной литературой.
Ветхий завет. Бытиё. Наши дни.
А всех программистов на c-like языках будем считать сектантами :)
Общей исторической памятью являются Кен Томпсон и Деннис Ритчи, за консолью PDP-11.

image
Признаю: все эти определения можно пусть и с оговорками примерить на си разработчиков. Но ведь скажем если я выучу татарский язык — я ведь не стану татарином?=)
Вы можете быть татарином и не зная татарского языка.

Вообще, в современном мире национальность определяется самоидентификацией. Вы сами должны определиться (если хотите), кто вы больше — русский или сишник.

При переписи населения вас просто попросят указать, кто вы по национальности, не вдаваясь в подробности национальностей бабушек или дедушек, а если вы не захотите говорить переписчику свою национальность, настаивать не имеют права.
Там всё слегонца сложнее.
http://blogovodoved.livejournal.com/4059.html
Если про образование народа по языкопрограмистскому признаку не писали в фантастическом произведении, то это маловероятно.
Напишите, если знаете такие произведения.
Если арбитражный суд откажет в иске, то надо подать групповую аппеляцию в международный суд по правам человека. Даже до ООН дойдём!
Это уже за разжигание, пойдет… и не по гражданскому кодексу.
Расслабься и открой исходники ядра линукса.
вот из за таких как вы из повершела убрали GOTO. и для того чтобы выскочить из одного цикла в другой приходится мудрить переменные и проверки.
UFO just landed and posted this here
Вот это поворот
вот из за таких как вы из повершела убрали GOTO
убрали ещё на этапе разработки
Я не знаком с данным продуктом, но по факту получается, что GOTO нет в первоначальном релизе… т.е. по задумке авторов изначально оператор безусловного перехода не предусмотрен. Вам не кажется, что «такие как я» тут как бы не причем, т.к. GOTO не было в релизе от слова совсем. А то я уже стал сыпать голову пеплом… а оказалось вон оно как.
так ведь разработчики и относятся к ненавистникам goto
в замен дали break :label
Но както через жо
В Windows PowerShell иметь метки могут только ключевые слова цикла, такие как Foreach, For, While.

в результате из цикла можно выскочить только в начало другого цикла или в конец этого.
Экспресс в середину цикла? да кому оно надо подумали они.
так ведь разработчики и относятся к ненавистникам goto
Вы напрасно ярлыки развешали. Я не ненавистник, я его просто не использую в си, а студентам просто не говорю, что так можно. При этом в проектах на асме goto jmp — это наше все.
Приведите пример безусловного перехода в середину цикла на си… а то у меня мозг ломается от такой задачи
не фанат С но вроде компилируется в билдере
просьба сильно не пинать мне ассемблер роднее чем С
#include <stdio.h>
int main(void)
{
  int P;
  int PP;
  int count=0;
  int H=50000000;
  int N=61000000;

  if (H%2==0) {H++;}
  while (H<=N)
  {
   P=1;
   PP=round(sqrt(H));
   do
   {
	P=P+2;
	if (H%P==0) {goto E;}
   }
	while (P<=PP);
   count++;
E: H=H+2;
  }

	 printf( "%d\n", count );
	 getchar();
	return 0;
}

Я думал, что в си через goto обрабатывают ошибки.
Как вы их обрабатываете без goto?
В С++ есть try-catch блоки, из того что встречал. Не знаю, имеется ли такой механизм в C.
По факту ошибки выполняется throw(чё произошло) и ловится в catch. Дальше уже пляшем.
Возможно, есть что-то ещё.
По форме (а не по содержанию) ничем не отличается от goto: прыгнуть туда-то.
Т.е. longjmp ближе к goto, чем к генерации исключения.
Благодаря этому коментарию, вспомнил что в php есть такая вот штука (http://php.net/manual/ru/control-structures.break.php). В сам break можно передать параметр, который укажет, через сколько уровней цикла можно перепрыгнуть. Добавляет приятный сахарок в синтаксис и отменяет необходимость в «флажках».
Появление необходимости в флажках сигнализирует о том, что тут что-то не так.
break с упоминанием какой именно цикл прервать??? И как такое читать потом?
Ничего страшного в GOTO нет, тем более в Си. Очень часто его использование очень оправдано.
Нам, излишне наверное категоричный, преподаватель запретил использовать goto. Поначалу было не комфортно, но потом мозг перестроился и с тех пор уже 20 лет как отсуствие goto в программёрской практике совершенно не напрягает. Я уже про него и забыл.
Могу осторожно согласиться, что я просто не встречался с задачами, где без goto никак.
Вот вам такая выскочить из середины одно цикла в середину другого. Обойтись можно но надо мудрить кучу if else.
Смутно представляю, когда может появиться такая необходимость. Уверен, что в таких случаях код можно переписать более красиво.
Я, честно говоря, плохо понял что имел ввиду Foolleren, но типовой случай использования goto в C/С++ это выход из двойного цикла (например если мы гуляем по дву-/трехмерной таблице и дошли до точки).
Википедия
for implementing multi-level break and continue if not directly supported in the language; this is a common idiom in C. Ссылка на википедию с ссылкой на источник


Второй способ описан ниже и применим только для C, но не для C++.
bool go_out = false;
for(int x = -1024; (x <= 1024) && (!go_out); x++){
    for(int y = -1024; (y <= 1024) && (!go_out); y++){
        // any operations
        ...
        // block end
        if(m[x][y] == 'X'){
            go_out = true;
        }
    }
}

Чем не решение? Случай синтетический, лично не доводилось использовать такие конструкции.
break'ами мне кажется быстрее будет, чем на каждой итерации проверять состояние переменной.
На ум приходит сразу 4 решения:

1. Обернуть код в функцию (предпочтительно).
2. Написать двумерный итератор (тоже хороший вариант).
3. После go_out поставить break, и проверять условие только во внешнем цикле.
4. Заменить go_out на x = 1025, y = 1025 (крайне нежелательно).
UFO just landed and posted this here
Тем что это медленнее.
Goto — это нативная команда ассемблера, JMP и куча нативных Jxx, из этого состоит весь компилированный код.
Вместо этого в твоём примере тратим память на абсолютно ненужную переменную, на доступ к памяти, на чтение памяти каждый раз в этой миллионной интерации, вместо того чтобы сделать один goto и съэкономить миллиадры циклов процессора. Даже если go_out будет лежать в регистре, это всё равно не бесплатная операция проверки.

А потом удивляемся, почему у нас всё везде тормозит на 8 ядрах и 4х гигагерцах, потому что каждый уровень разработчиков абстракции побоялся где-то чуть оптимизировать код и побоялся «богомерзкого» нативного goto, якобы «кто-то сказал что так нельзя». Эти же люди бояться писать без «ооп», делают фабрики фабрик даже там где это не нужно и совсем не думают о производительности.
Если у вас " тормозит на 8 ядрах и 4х гигагерцах" и производительность упирается в проверки флагов и серьезно улучшается от внедрения повсеместно goto, тут что-то у вас не так.
Не согласен. Из-за частого обращения будева переменная будет висеть в кэше и время доступа будет крайне малО.
и я не согласен, закидывание переменных в регистры в зависимости от процессора даёт в худшем случае 1% буста в лучшем 20+%. профилирование кодека divx выявило, что вытаскивание переменных из стека занимает большую часть времени функции.
А подскажите почему тут нельзя использовать while?
Как вариант можно использовать try-catch. С++ плоховато знаю, но принцип понятен.
говнокод на C#
int i, j, k;

try
{
    for (i = 0; i < 100; i++)
    {
        for (j = 0; j < 100; j++)
        {
            for (k = 0; k < 100; k++)
            {
                if (k == 50)
                {
                    throw new IndexOutOfRangeException();
                }
            }
        }
    }
}
catch (IndexOutOfRangeException) {}

а ничего, что механизм исключений очень дорогой и является наихудшайшим вариантом из всех возможных?
Ну, это понятное дело. Но, если совсем вообще никак, то как вариант. =)
а ничего, что иногда выйти из вложенных циклов нужно всего один раз. В таком случае дороговизна генерации исключения и его отлова роли не играет.
При этом затраты на обработку исключения могут быть на порядок больше, чем собственно выполнение цикла.
А если таких узких мест будет несколько?
А чем исключение лучше goto? В ситуации, когда надо выйти из вложенного цикла, и то, и то — костыль. Но goto костыль дешевый и логичный. А генерация исключения — дорогой и нелогичный.
Исключения лучше чем goto потому что корректно уничтожают автоматические переменные.
А goto просто прёт напролом.
Насколько я понимаю.
Нет, goto тоже их все корректно уничтожит.
On exit from a scope (however accomplished), destructors (12.4) are called for all constructed objects with automatic storage duration (3.7.2) (named objects or temporaries) that are declared in that scope, in the reverse order of their declaration.
А там куда прыгнули — так же всё создастся в порядке появления в коде, как я понимаю?
Тогда это не просто jmp куда-то на метку, получается, а сложная конструкция.
It is possible to transfer into a block, but not in a way that bypasses declarations with initialization. A program that jumps from a point where a local variable with automatic storage duration is not in scope to a point where it is in scope is ill-formed unless the variable has POD type and is declared without an initializer.
В общем, не всё так просто с этими goto.
Мутная тема. По крайней мере в С++, где не только POD.
В С++ вообще нету простых тем :-Р

Но по крайней мере, компилятор вам не даст «запрыгнуть» внутрь блока в обход инициализации переменных. Или переменные инициализируются по умолчанию (некоторые компиляторы, включая MSVC++, в «нестрогом» режиме это разрешают), или будет ошибка компиляции.
Когда я полез за тем что бы узнать чем вообще заменить GOTO в повершеле, наткнулся на такой кейс
раскрашивание логов в html, мне он нужен был для совершенно не нормального применения — сравнить скорость работы алгоритма в разных ЯП ну и бонусом в повершеле.
также призывается comargo
Волосы дыбом встают от такого алгоритма :)
Угу, без комментариев понять, что происходит совсем не просто, за это собственно GOTO и не любят, но местами с ним всё же проще чем без него.
Вы так или иначе условие выхода из цикла будете проверять через if или case. И если вы прервёте выполнение цикла по break или продолжить очередной цикл по continue не проходя до конца весь цикл, вы получите такой же функционал, который прекрасно работает без goto и значительно облегчает понимание алгоритма и его отладку.
Да выход в таком случае будет всё равно через if, но когда надо прыгнуть в середину другого цикла, без goto получается проблема.
Такой же if но уже в другом цикле. Разве нет? Ведь цикл у всё равно нужны условия начала, окончания цикла. Не всё ли равно начинать в начале цикла проверку какую часть выполнять или в середине?
Надеюсь, я правильно понял семантику требования «прыгнуть в середину другого цикла».
private void doFirstCycle() {
  int j;
  for (j=0; j<100; j++) {
    doYourJob();
    if (this.haveToBreak) {
      doSecondCycle(3, 200);
      break;
    }
  }
return;
}

private void doSecondCycle(from, to) {
  int i;
  for (i=from; i<to; i++) {
  doAnotherJob();
  return;
}


В нужном месте той огромной нечитаемой функции, из одного из циклов которой нужно прыгать в середину другого, вместо цикла вставляете вызов функции. Заодно и читаемость повысится.
когда я говорил про середину, то имел в виду совсем середину — не кратную
— надо начать с doAnotherJob_2();
private void doSecondCycle(from, to) {

  int i;

  for (i=from; i<to; i++) {

  doAnotherJob_1();
  doAnotherJob_2();

  return;
}
Можно задать выполнение нужных частей кода битовой маской или значением enum'а. Предполагаем, что в следующей итерации цикла мы выполним тело целиком (а с goto так и выйдет); в этом месте мой мозг начинает понемногу плавиться.
private enum dirtyCycleJumper { 
fromFirst, 
fromSecond
}

private void doSecondCycle(int from, int to, dirtyCycleJumper startFrom) {

  int i;

  for (i=from; i<to; i++) {
  switch (startFrom) {
case fromFirst:  doAnotherJob_1(); 
case fromSecond:  doAnotherJob_2();
}
startFrom = dirtyCycleJumber.fromFirst;
}
return;
}



Вызываем doSecondCycle(3, 200, dirtyCycleJumper.fromSecond).
С такими требованиями, действительно, goto будет удобнее. Но случай какой-то уж больно маргинальный.
случай действительно очень редкий, и очень хорошо подходит чтобы запутать предсказатель ветвлений старого процессора, например разница между феном 1100 и вишерой 9590@ оказалась 8 раз при выполнении в 1 поток при выходе/входе через goto, интеловских свежаков для сравнения к сожалению нет,
когда руки дойдут сравню различные способы обойти goto где он действительно просится( запрыгнуть в середину цикла), но беглый взгляд подсказывает что goto должен отработать быстрее вызова функции.
Надеюсь, я правильно понял семантику требования «прыгнуть в середину другого цикла».

private void doFirstCycle() {
int j;
for (j=0; j
Написанный в прошлом такой свой код (с кучей IF и прыжками из одной части в другую в гигантском цикле) сейчас считаю примером того как не надо было писать.
И живет он теперь почти как ИИ, хрен знаешь что выкинет в следующий раз.
Лучше переписать так чтобы в принципе не нужно было из середины цикла кудато прыгать
ну вот смотрите у нас есть условия которые проверяются для какого то массива, если проходит, то проверяем другие условия во втором цикле, и вот тут если не проходит надо сделать первое и второе если не проходит то только второе.
можно сделать goto на второе
или сделать ещё одну переменную и break`ом оборвать первый цикл, а потом пройтись по куче if, когда количество итераций плавно так уходит за 6 лямов, каждый if в цикле делает вас печальнее.
А чем Вас return не устроит, с нужным разбиением на функции, как раз вывалитесь где надо?
в си функции по умолчанию передают параметры через стек, работа со стеком не на всех процессорах происходит без потерь для производительности.
Я думаю, любой нетривиальный компилятор С сделает одиноко вызываемую функцию inline'овой, а все return'ы из нее заменит на jmp'ы, которые, по сути, те же goto.
Способ передачи параметров в Си все же лучше рассматривать с точки зрения платформы, а не языка. В X64 первые 4 или 5 аргументов без вариантов уйдут через регистры.
Т.е. там va_args не такой, как на x86?
В Джаве нет goto, а для выхода из нескольких циклов есть типа такого:
a: while(true) {
 while(true) {
  if (Math.random() < 0.5) {
   break a;
  }
 }
}
Ну, goto было когда-то, но потом его выкинули. До сих пор goto — зарезервированное ключевое слово. Да и из байткода его не выкинешь :)
Основной паттерн использования goto в современном си — досрочный выход из функций с корректным освобождением ресурсов. Возможно у вас предмет называется c++, в котором использовать goto действительно не желательно. В си — это абсолютно нормальное явления — возьмите любой крупный сишный проект.
Учили-то мы C, хотя последние лет 15 программирую в основном на C++.
Но первые лет 5 и после тогда отвлекался на С. Модуль ядра линукс даже помнится писал.
Но нигде алгоритм не упирался в goto. Так, что прям без него вот ну никак.
И даже на c++ не всегда RAII использую. Но обхожусь без goto и, повторю, ни разу не вспоминал про него в духе: эх, тут goto просится.
Есть прекрасный паттерн использования goto — выход из функции по ошибке с очисткой ресурсов. Например:
int do_or_fail(void)
{
    FILE *f1, *f2, *f3;
    int retval = 0;
    if(!(f1=fopen("aaa.txt","r")))
        return 0;
    if(!(f2=fopen("bbb.txt","r")))
        goto cleanup_f1;
    if(!(f3=fopen("ccc.txt","r")))
        goto cleanup_f2;
    /* ... do something with the files .... */
    retval = 1;
cleanup_f3:
    fclose(f3);
cleanup_f2:
    fclose(f2);
cleanup_f1:
    fclose(f1);
    return retval;
}

Без него при каждом открытии файла был бы иф с кучей команд освобождения ресурсов и возвратом по ошибке. При этом код освобождения ресурсов дублируется, что загромождает программу. А еще в таком коде легко допустить ошибку.
Как только люди не извращаются, лишь бы на нормальном C++ с RAII не писать.
И как Вы на «нормальном C++ с RAII» напишете модуль ядра линукса?
А это уже вопрос религии линуксоидов, а не технологии. Как-то вот в Windows и MacOs это можно сделать, а красноглазым чисто Эго не позволяет до С++ опуститься.
Ядро Windows тоже на «голом» C написано. И большая часть драйверов, работающих в режиме ядра — тоже. Боюсь, что, даже если где-то в ядро можно влезть с C++ — то там будут ограничения по используемым возможностям, например — отсутствие полной поддержки исключений.
Есть нюансы, кто же спорит. Но уж такую мелочь как RAII всё-же потянет.
RAII без исключений невозможно, а исключения — один из «тяжелых» механизмов C++, который в контексте ядра ОС может не поддерживаться или поддерживаться ограниченно. Например, для обычного кода использование исключений может быть возможно, а для всяких ISR и DPC — нет.

Также не стоит забывать, что обстановка в ядре ОС сильно отличается от обстановки в user-space. В user-space у вас обычно есть потоки, и каждый из них выполняет какой-то длинный код, захватывая ресурсы и освобождая их. Здесь RAII работает хорошо. А в ядре у вас в основном callbacks (в числе которых ISR и DPC), короткие функции, которые должны быстро отработать и выйти. Захваченные ресурсы зачастую удерживаются между вызовами этих функций, а вызваны они могут быть в контексте разных потоков и процессов. Так что RAII в чистом виде здесь имеет ограниченное применение, как, впрочем, и вышеприведенный паттерн с goto.
А почему RAII невозможно без исключений? o_O
А как вы будете сообщать об ошибке из конструктора? Сообщать об ошибках инициализации членов класса или базовых классов? Уничтожать уже созданные члены?

Какие-то костыли, конечно, можно придумать, но от этого вся красота и удобство RAII сходят на нет.
Суть RAII заключается не в том, чтобы бросить исключение в конструкторе.

А по вашему вообще ООП без исключений невозможно получается?
Суть RAII заключается не в том, чтобы бросить исключение в конструкторе.

Я не говорил, что «бросить исключение в конструкторе — это суть RAII».

Но возможность бросить исключение в конструкторе является критической для реализации RAII так, чтобы код получался красивым и корректным. Поясните пожалуйста, как можно реализовать RAII без исключений в конструкторе?
А по вашему вообще ООП без исключений невозможно получается?

Этого я тоже не говорил.
В общем случае, ошибки при захвате ресурса может и не быть.
Так что вовсе не обязательно конструктор должен бросать исключение.

Ну и если могут быть ошибки, можно оставить проверку ошибок для отдельных функций, а не кидать исключения.
Конструктор открыл файл.
Внешний код вызвал функцию проверки всё-ли в порядке.
Файловые потоки stl c++ так и работают.
В общем случае, ошибки при захвате ресурса может и не быть.

Это скорее исключение, чем правило. В подавляющем большинстве случаев функции захвата ресурсов могут вернуть отказ. На то они и ресурсы, чтобы исчерпываться.
Ну и если могут быть ошибки, можно оставить проверку ошибок для отдельных функций, а не кидать исключения.

И тогда RAII превращается в адъ.

Мы в данной ветке обсуждаем паттерн goto для досрочного возврата из функции с очисткой ресурсов. Выше была приведена реализация на C для случая открытия трех файлов. Те, кто говорил здесь о RAII, имели в виду, что с помощью RAII эта задача решается проще. С этим можно согласиться. Вот пример реализации с помощью RAII:
class RaiiFile
{
public:
    RaiiFile(const char* filename): f(fopen(filename,"r")) {if(!f) throw std::runtime_error("File open failed");}
    ~RaiiFile() { fclose(f); }
private:
    FILE* f;
}

void do_or_fail(void) // Throws an exception on failure
{
    RaiiFile f1("aaa.txt");
    RaiiFile f2("bbb.txt");
    RaiiFile f3("ccc.txt");
    /* ... do something with the files .... */

    // The files will be correctly closed on return or exception anywhere in this function
}

Попробуйте сделать то же самое без исключений в конструкторах. Потом сравните с вариантом на C с goto.
Вы не путайте выделение ресурса с его захватом.
И память может быть уже выделена и уже после отдаётся для управления RAII-объекту.
И мьютекс уже заранее создан и отдается на блокирование RAII-объекту.
Вы не путайте

Уважаемый, пожалуйста не используйте в разговоре со мной такой поучительный тон. Еще неизвестно, кто из нас что путает.
И мьютекс уже заранее создан и отдается на блокирование RAII-объекту.

То, что он заранее создан, не гарантирует, что функция блокировки по мьютексу завершится успешно. В винде, например, есть такой код возврата WAIT_ABANDONED. Можете погуглить, если интересно.

Ну и даже если вы найдете примеры, когда ошибка в конструкторе возникнуть не может — все же это не опровергает, что при захвате, выделении, или каких угодно операций в отношении ресурсов чаще встречается ситуация, когда может возникнуть ошибка, чем наоборот. И пример с goto, с которого началось обсуждение, как раз возник из задачи обработки ошибок. К чему вы вообще сюда приплетаете участки кода, где ошибок возникать не может?

Вам выше был задан вопрос, можете ли вы реализовать обработку ошибок на базе RAII, но без исключений. И привести пример для сравнения. Вопрос остался без ответа. Не можете?
Если Вы пишете:

«В подавляющем большинстве случаев функции захвата ресурсов могут вернуть отказ. На то они и ресурсы, чтобы исчерпываться.»

и не делаете разницы между выделением ресурса и его захватом, то мне ничего не остаётся как указать на этот недочёт, уважаемый :)

Теперь что касается RAII без исключений: RAII это всего лишь ООП-техника управления ресурсами. Вы отказались от «своих» слов, предложенных мною:

«А по вашему вообще ООП без исключений невозможно получается?

Этого я тоже не говорил.»

Стало быть согласны ООП и исключения — не две стороны одной медали. И одно без другого вполне может существовать.
Стало быть и RAII можно сделать без исключений.
И ошибочки после конструктора проверить незазорно (я привёл пример работы с файловыми потоками).
Или, например, какая может возникнуть ошибка в конструкторе какого-нибудь авто указателя, которому сдают на управление память? Что он не сможет в свою внутреннюю переменную-указатель положить переданное в параметре значение?

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

По сути дела, с точки зрения RAII, это одно и то же. В обоих случаях ресурс надо вернуть (очистить, освободить), и в обоих случаях может возникнуть отказ.
то мне ничего не остаётся как указать на этот недочёт, уважаемый :)

Вы так старательно заостряете внимание на мелочах — вам явно хочется увести обсуждение в сторону от исходной темы.
Стало быть согласны ООП и исключения — не две стороны одной медали. И одно без другого вполне может существовать.
Стало быть и RAII можно сделать без исключений.

Из одного не следует другое. Я вам дважды предлагал привести пример реализации RAII без исключений для открытия файлов и обработки ошибок их открытия. В ответ — тишина. Если можно сделать — сделайте. Думаю, что на написание ваших сообщений с придирками к мелочам ушло больше вашего времени, чем на написание предлагаемого примера.
И ошибочки после конструктора проверить незазорно (я привёл пример работы с файловыми потоками).

«Проверяние ошибочек после конструктора» — это по сути не RAII, так как при использовании RAII ресурс выделен (захвачен), пока существует объект, им управляющий, и наоборот.

Вы привели в пример весьма неудачное решение из стандартной библиотеки. Создается, к примеру, объект ofstream, но существование этого объекта не означает возможность записи в поток. Эта архитектура появилась до изобретения RAII в C++ (а возможно — и до введения в этот язык механизма исключений) и сохраняется лишь как наследство с целью совместимости.

Для сравнения возьмите приведенный выше класс RaiiFile. Здесь у объекта имеется инвариант: пока он существует, файл открыт, как только удаляется — файл закрыт. С такой архитектурой работать значительно проще.
Вы написали, что без исключений нельзя построить RAII. Для того, чтобы опровергнуть это утверждение — достаточно привести хотя бы один пример.Указанной парочки хватит?

Ваши примеры мое утверждение не опровергают. Случай отсутствия возможности ошибок в конструкторе не охватывает все области применения RAII, поэтому он не может рассматриваться как общее решение задачи. Что же касается ofstream — аргументы приведены выше. Это неполноценное RAII, так как не соблюдается инвариант.
Ещё раз:
Вы утверждаете, что RAII без исключений невозможно.
Я привёл 2 опровергающих примера. С точки зрения формальной логики достаточно и одного.
Вы акцентировали внимание на удобном Вам примере с файловыми потоками, не считая их по сути RAII. По вашему — RAII это однозначность: если объект есть — ресурс захвачен.
По мне так более важная работа происходит в деструкторе. Он «автоматически», самостоятельно, незаметно для программиста подчищает ресурсы. Конструктор же работает «под управлением» программиста и так или иначе — всё-равно проверка его работы осуществляется. Или вызвать функцию или ловить исключение. Всё-равно писать код. Или сразу после создания объекта или «где-то внизу». Это уже не принципиально и не является сутью RAII.
Суть его — в деструкторе.
И в этом смысле файловые потоки stl — самое обычное RAII.

А с какой «архитектурой» работать проще: с исключениями или с «ручной» проверкой ошибок — по большей части вопрос вкуса.
У исключений есть, на мой взгляд, только 2 существенных плюса:
1. Исключение не пропустишь. Вручную ошибку можно забыть проверить или, если какая-то стороняя библиотека, то в новой версии в ней могут появиться новые исключения.
Но, опять таки, что лучше — упавшая на непойманном исключении программа или программа не проверившая ошибку и ковыляющая дальше — зависит от ситуации.

2. Иерархия классов исключений, которая позволяет ловить их не по одиночке, а группами.
Я привёл 2 опровергающих примера. С точки зрения формальной логики достаточно и одного.

Вы не привели ни одного опровергающего примера.

Здесь ситуация такая же, как если бы я утверждал, что корни полинома 8й степени в общем случае нельзя найти аналитически, а вы «опровергали» бы это, приводя в пример уравнение вида x^8=64, которое таким образом решить можно.

Наличие легких частных случаев не означает, что общая задача решается так же легко, как эти частные ее случаи.
Вы акцентировали внимание на удобном Вам примере с файловыми потоками, не считая их по сути RAII.

Удобный мне пример? Ни в коем случае. Это был удобный вам пример, который вы настойчиво проталкиваете к обсуждению. Я вынужден был его разобрать, раз вы так настаивали.
По вашему — RAII это однозначность: если объект есть — ресурс захвачен.

Ну а как иначе? Прочитайте, что ли, определение RAII. «Resource acquisition IS initialization». В случае с ofstream, объект после отработки конструктора инициализирован? Инициализирован. Ресурс захвачен? Не захвачен. Какое здесь может быть RAII?
По мне так более важная работа происходит в деструкторе.

Деструкторы — это необходимый механизм реализации RAII в C++. Но недостаточный. Другим необходимым механизмом являются исключения.
Конструктор же работает «под управлением» программиста и так или иначе — всё-равно проверка его работы осуществляется. Или вызвать функцию или ловить исключение.

Полагаю, под фразой «вызвать функцию» вы имели в виду «выполнить проверку»?

Вот вы написали выше про деструктор: «Он «автоматически», самостоятельно, незаметно для программиста подчищает ресурсы».
Это очень важное преимущество. За счет автоматизации подчистки ресурсов исключаются ситуации, когда программист «забыл» это сделать вручную. Также код очистки ресурсов не загромождает программу, облегчая понимание ее основной логики.

Но не деструкторами едиными жив RAII. Есть еще вторая проблема — проверка ошибок при захвате ресурсов и досрочный выход из функции в случае ошибки. Этим в C++ занимается механизм исключений в конструкторах. Благодаря ему, вашими же словами: «автоматически», самостоятельно, незаметно для программиста проверяются ошибки при захвате ресурсов.

Не находите сходство? В обоих случаях идет автоматизация одного из важных аспектов работы с ресурсами.

Отсутствие исключений в конструкторах делает невозможной автоматизацию проверки ошибок при захвате ресурсов. От этого попытка реализации RAII в C++ теряет, грубо говоря, половину своих преимуществ.
А с какой «архитектурой» работать проще: с исключениями или с «ручной» проверкой ошибок — по большей части вопрос вкуса.

Если распространить вашу логику на деструкторы — то получится, что RAII можно сделать и без деструкторов, вручную очищая ресурсы, и это лишь вопрос вкуса.
Что-то у меня кнопки форматирования текста пропали, приходится отвечать просто текстом, без цитат.

1. У Вас прямым текстом было написано:
«RAII без исключений невозможно».
Никаких общих или не общих случаев. Просто написано: невозможно.

Я привёл примеры — ну хорошо, не нравятся Вам файловые потолки, но Вы уже второй раз игнорируете второй пример с автоуказателем.
У которого в конструкторе не может быть ошибок.

2. Ваши слова:
«В случае с ofstream, объект после отработки конструктора инициализирован? Инициализирован.»
С чего Вы взяли? Он — создан, а вот инициализирован он до конца (в его, объекта семантике) — это нужно у него узнать.
Да, спросить:
if (!myFileStream) return;
Или, как Вы настаиваете, ловить исключение:
try
{

}
catch (Exception& e)
{
return;
};

Оба варианта годятся.
Мне вариант с исключениями не нравится громоздкостью. Плюс Вы же сами упомянули, что исключения — «тяжелый» механизм.
Но не вижу причин делать тот или иной механизм обработки ошибок неотъемлемым признаком RAII.

3. «Вот вы написали выше про деструктор: «Он «автоматически», самостоятельно, незаметно для программиста подчищает ресурсы».
Это очень важное преимущество.»
Преимущество… Я настаиваю, что именно это и есть суть RAII. А не принцип проверки ошибок инициализации.

4.«Но не деструкторами едиными жив RAII. Есть еще вторая проблема — проверка ошибок при захвате ресурсов и досрочный выход из функции в случае ошибки. Этим в C++ занимается механизм исключений в конструкторах. Благодаря ему, вашими же словами: «автоматически», самостоятельно, незаметно для программиста проверяются ошибки при захвате ресурсов.»

Во-первых, Вы сами упоминали, что исключения — это не единственный способ сообщить об ошибке.
Во-вторых, никакой «автоматической проверки ошибок» исключениями — нет. Программист всё-равно должен написать код проверки.
Но по Вашему — не в месте возникновения ошибки, а в блоке catch. Ну, как я уже писал, это дело вкуса и к RAII не имеет отношения.
Единственное что однозначно характеризует RAII — это работа деструктора.
И именно поэтому не катит ваше утверждение:
«Если распространить вашу логику на деструкторы — то получится, что RAII можно сделать и без деструкторов, вручную очищая ресурсы, и это лишь вопрос вкуса.»
1. У Вас прямым текстом было написано:
«RAII без исключений невозможно».
Никаких общих или не общих случаев. Просто написано: невозможно.

Хорошо, уточню: RAII невозможно без исключений в общем случае. Если вы считаете это важным уточнением — то надеюсь, что этим ваше стремление к точности в мелочах удовлетворено?

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

Вы уводите обсуждение в сторону, придираетесь к мелочам, игнорируете предложение реализовать обработку ошибок при захвате ресурсов с помощью RAII без исключений. Мне трудно представить, чтобы при этом вами двигало стремление к поиску истины.
Вы уже второй раз игнорируете второй пример с автоуказателем. У которого в конструкторе не может быть ошибок.

Что это меняет? Вернемся снова к аналогии с полиномами 8й степени. Вы можете привести бесконечное множество таких полиномов, корни которых можно найти аналитически. Но это не отменит тот факт, что в общем случае корни таких полиномов найти аналитически невозможно.

Вы можете приводить сколько угодно примеров таких ресурсов, при захвате которых не может возникнуть отказ. Но это не отменяет того, что существуют ресурсы, при захвате которых отказ возникнуть может.
С чего Вы взяли? Он — создан, а вот инициализирован он до конца (в его, объекта семантике) — это нужно у него узнать.

В языке C++ объект считается инициализированным после того, как завершил работу его конструктор. Разумеется, программист может обойти этот принцип, но концепция RAII подразумевает его строгое соблюдение.
Или, как Вы настаиваете, ловить исключение:… Мне вариант с исключениями не нравится громоздкостью.

Вы лукавите насчет громоздкости. Возможно, это свидетельствует об отсутствии у вас понимания эффективных способов использования исключений в C++. Прочитайте еще раз пример реализации RaiiFile с исключениями, который я привел выше, и укажите, где там находится громоздкий код.
Плюс Вы же сами упомянули, что исключения — «тяжелый» механизм.

Что поделаешь, это плата за удобство RAII. Не нравится «тяжесть» — вы всегда вольны отказаться от RAII.
Но не вижу причин делать тот или иной механизм обработки ошибок неотъемлемым признаком RAII.

В языке C++ это неотъемлемый признак RAII так же, как и деструкторы. Вы с тем же успехом могли бы доказывать, что деструкторы C++ не являются неотъемлемым признаком RAII.
Я настаиваю, что именно это и есть суть RAII. А не принцип проверки ошибок инициализации.

Оба принципа являются необходимыми для RAII в C++. Отказ от одного из них — это как лететь с одним крылом.
Вы сами упоминали, что исключения — это не единственный способ сообщить об ошибке.

Укажите пожалуйста иной способ сообщить об ошибке в конструкторе в C++ так, чтобы компилятор понял, что это именно сообщение об ошибке, и предоставил соответствующую поддержку. Аналогично, деструктор — это не единственное место, где можно разместить код освобождения ресурсов. Что тогда — не считать освобождение ресурсов в деструкторе неотъемлемой частью RAII?
Во-вторых, никакой «автоматической проверки ошибок» исключениями — нет. Программист всё-равно должен написать код проверки.

А какое же тогда есть автоматическое, как вы сказали, освобождение ресурсов с помощью деструкторов? Программист все равно должен писать код освобождения (в деструкторе).
Но по Вашему — не в месте возникновения ошибки, а в блоке catch.

В блоке catch пишется не код проверки, а код обработки ошибок. И то не весь. Часть его пишется в деструкторах. Код проверки же пишется в конструкторе. Посмотрите еще раз приведенный выше пример с RaiiFile.
Ну, как я уже писал, это дело вкуса и к RAII не имеет отношения.

Я уже аргументировал сообщением выше, почему это ваше мнение ошибочно.
Единственное что однозначно характеризует RAII — это работа деструктора.

Вы указали только один из важных механизмов RAII, но упорно отрицаете второй. Полагаю, в этом ваше заблуждение. Без исключений на C++ невозможно полноценно реализовать парадигму RAII так же, как и без деструкторов.
«Как говорится, переубедить мне Вас не удастся, поэтому сразу перейду к оскорблениям»
:)

Мы досконально, как я вижу, выяснили позиции друг друга.
Каждый остался при своём мнении, которое однако не мешает никому из нас использовать принцип RAII по своему. Благо он это позволяет.
Ну хорошо, можно остановиться и на этом. «Agree to disagree», как говорят американцы.
Гораздо более пикантная ситуация — это ошибка в деструкторе.
Ошибка в деструкторе, да… Как ее обрабатывать — непонятно совершенно. Красивых решений на данный момент я не нашел. Разве что логировать. Прерывать исполнение деструктора, как правило, недопустимо даже при ошибках.
разве так не проще?

int do_or_fail(void)
{
FILE *f1, *f2, *f3;
int retval = 0;
if(f1=fopen(«aaa.txt»,«r»)) {
if(f2=fopen(«bbb.txt»,«r»)) {
if(f3=fopen(«ccc.txt»,«r»)) {
/*… do something with the files… */
retval = 1;
fclose(f3);
}
fclose(f2);
}
fclose(f1);
}
return retval;
}

Что тут дублируется?
Ничего не дублируется. Но если файлов открывать не три, а десять (или просто много), то нормальные отступы будут выглядеть гораздо хуже, чем в ситуации с goto.
Меня код даже с тремя 3 файлами в одной функции смутил, а уж 10…
А каким образом вы будете писать код, если надо одновременно открыть 3 файла? В разных функциях будете открывать? А ошибки где проверять и закрывать уже открытые файлы, если часть из них открылось, а часть — нет?

Причем это не обязательно должны быть файлы, это могут быть любые другие ресурсы, у которых подобная модель захвата с возможностью отказа. Память, например.
Код можно структурировать и даже в принципе алгоритм реализовать — разными способами.
Но универсального ответа на ваш вопрос «как» — я дать не могу.
Это нужно разбираться в каждом конкретном проекте.
Ну и, повторю, наверное есть алгоритмы, где без goto или некуда или замена будет гораздо корявее, чем вариант с goto.
Но я с такими за 20 лет — не встречался.
Названия файлов в константу, дескрипторы в массив, если у вас сишников так все не просто, можно и флаги «файл 3 открыт» в массив записать. И никакого goto, и хоть 20 файлов открывай, кода больше не станет.
Я с таким за 3 года работы часто сталкивался, что в элементарных случаях пишут вот такую портянку, и говорят что «иначе не сделаешь», а в реальности надо было только немного подумать. Простите если кого-то сейчас обидел. Я всего лишь молодой и глупый питонист.
В итоге какая глубина вложенности будет? И какой сдвиг форматирования вправо?
vector<FILE*> files;
vector<string> names;
vector<bool> success;
// ресайз, заполнение имён файлов
...
bool group_success = true;
for(int i = 0; i < N; i++){
    success[i] = (file[i] = fopen(names[i].c_str(), "r")) == NULL;
    if(!success[i]){
        group_success = false;
    }
}
if(group_success){
    // any actions with files
}
for(int i = 0; i < N; i++){
    if(success[i]){
        fclose(files[i]);
    }
}
Только сейчас заметил, что там с NULL по "!=" сравнивать надо было. Опечатался.
А что, если требуется захватывать разнородные ресурсы?
В enum перечислите типы ресурсов, по if или case применяйте открытие и закрытие, в массив вместо file* сделайте void*
Разнородные ресурсы — это значит, что они захватываются, в общем случае, разными функциями, имеющими разный интерфейс. Вызывать их в цикле по массиву указателей невозможно из-за различий в интерфейсе.

Можно и эту проблему решить, конечно. Создать, к примеру, функции-адаптеры. Для большого числа ресурсов это, наверно, хорошее решение. Но для среднего числа (3-10) — это стрельба из пушки по воробьям. Логика одной функции оказывается размазана на несколько функций, появляются циклы и дополнительные переменные. Для восприятия программы все это, на мой взгляд, тяжелее, чем конструкция с goto.
Подытоживая, для малого числа аргументов имеет смысл расписать каждый вручную, для большого — построить комбайн с унифицированным доступом к разным типам ресурсов.
Такие конструкции прекрасно реализуются через
FILE *f1 = NULL, *f2 = NULL, *f3 = NULL;
int retval = 0;
do
{
if(!(f1=fopen(«aaa.txt»,«r»)))
break;
if(!(f2=fopen(«bbb.txt»,«r»)))
break;
if(!(f3=fopen(«ccc.txt»,«r»)))
break;
/*… do something with the files… */
retval = 1;
} while(FALSE);

if(!retval)
{
if (f1) fclose(f1);
if (f2) fclose(f2);
if (f3) fclose(f3);
}

Причем блок отката обычно выносится в отдельную функцию, которая позже вызывается как деструктор (например, если действия с файлами происходят не только в контексте вызова функции).
Операторы return, break и continue — это по сути замаскированные goto, они нарушают структурность программы (по Дейкстре). Так что, если у вас в свое время воспитали устойчивое отвращение к goto — то забыли это сделать в отношении остальных вышеупомянутых команд.

Ну и приведенная вами программа имеет следующие недостатки: цикл-который-не-цикл, лишние проверки («if(f1) fclose(f1);»). Не всякий ресурс допускает такую простую проверку на предмет существования. Для тех ресурсов, которые нельзя так проверить, придется заводить отдельные логические переменные.

В общем, goto в данном случае красивее и эффективнее. И приведенный мной паттерн — это не мое изобретение (хотя я его в свое время независимо изобрел), а классический пример-исключение, показывающий, что есть случаи, где применение goto оправдано.
При обучении озвучивался аргумент, что функции с goto выпадают из поля зрения оптимизатора. Потому и привился такой стиль программирования. Насколько я знаю, современные компиляторы не имеют такого недостатка. Кстати, приведенный мной пример не моя идея, это распространенный паттерн инициализации в драйверах Windows (функции создания объектов, StartDevice и прочие). Более адекватно код выглядит, если учесть, что описатели нужно закрывать не только здесь на откате при проблемах, но и при очистке объекта.
А в целом вы правы, это попытка не использовать goto там где он подходит лучше.
Спасибо, понятно.
Более адекватно код выглядит, если учесть, что описатели нужно закрывать не только здесь на откате при проблемах, но и при очистке объекта.

По-моему это неоптимальное решение. Если мы снова взглянем на RAII в C++ — то он выглядит примерно так:
class ResourceSet
{
private:
    Resource a;
    Resource b;
    Resource c;
public:
    ResourceSet(): a(), b(), c() {}    
}

При создании объекта типа ResourceSet его конструктор поочередно захватывает ресурсы a, b и c. Если какой-либо из этих ресурсов недоступен — то соответствующий конструктор бросает исключение, и тогда создание объекта ResourceSet прерывается преждевременно. Исключение летит дальше вверх. А поскольку объект ResourceSet не был создан до конца (он считается созданным до конца после того, как будут созданы все объекты-члены и завершено исполнение тела конструктора) — то его деструктор не вызывается. Вызываются только деструкторы тех членов, которые уже были созданы на момент генерации исключения.

Соответственно, при уничтожении объекта ResourceSet() деструкторы членов вызываются безусловно, так как гарантированно известно, что все члены класса были успешно созданы.

Чтобы реализовать это на C, нужно иметь функцию, реализующую конструктор. Эта функция будет завершаться либо успешно — и тогда известно, что все ресурсы, которые она должна была захватить, захвачены; либо неуспешно — и тогда известно, что никаких ресурсов не захвачено, и вызывать «деструктор» не нужно. В таком случае в функции, реализующей концепцию деструктора, можно не проверять каждый ресурс, был ли он на самом деле захвачен.
Эти операторы работают чётко в рамках конструкций: циклов, switch'ей и функций, и имеют вполне предсказуемые последствия.
В каком же состоянии окажутся ресурсы программы в результате goto — предсказать трудно.
Если я не ошибаюсь, существование тьюринг-полного P" языка (в котором отсутствует goto оператор), уже говорит о том, что всегда можно обойтись без goto.
В самой машине Тьюринга нет ни goto, ни каких других операторов. Значит, без любых операторов можно обойтись. И что?
Вы точно читали комментарий, на который я отвечал?
Цитирую:
Могу осторожно согласиться, что я просто не встречался с задачами, где без goto никак.

А теперь вам вопрос, при чем тут другие операторы?
Это смотря как использовать. Некогда, учась классе в 6-8, я не знал о существовании процедур и функций(правда это был паскаль, а не СИ) и вот тогда я с помощью goto выстраивал некие блоки, которые по сути своей были функциями. Да, дикий говнокод, но я умудрялся с таким подходом занимать призовые места :)
Это полный аналог русского мата — в каких-то коллективах это категорически не привествуется — настолько, что могут сразу попросить на выход, где-то наоборот — им не ругаются, а на нём разговаривают…
Т.о. goto, точнее его положение в языке поднимает Си на уровень именно что Настоящего Языка, который как известно делает население — народом.
<пыыхххх....>
Кстати о мате — если суд не только признает C иностранным языком, но еще и признает оператор goto нецензурным матерным словом на этом языке — то авторам рекламы будет совсем печально.
Судя по минусам, пока лидируют сторонники мата goto.
Это сотрудники Интела минусуют, они ярые фанаты goto, даже в процессор её встроили!
Таки обработка ошибок на goto крайне приятна.
Налицо дискриминация людей по языковому признаку!
http://s670.photobucket.com/user/DeathLoveCrymo/media/see-computers-are-racist.jpg.html
В рекламе явная борьба с русским языком.
На кол!
— Вы знаете эсперанто?
— Ещё бы — я там три года прожил!
Должна быть Wikipedia на С, Google Translate тоже с C, а также республика C вдобавок.
И чтобы Google Translate мог переводить C на Java / C++ / PHP / JS и прочие диалекты малых народностей.
И переиздать Конституцию, все кодексы и федеральные законы. Так даже лучше — баги будет искать легче.
Я так понимаю, переизданные документы должны корректно компилироваться при отсутствии ошибок?

Вот только не факт, что все юнит-тесты будут зелеными)

После этого мы наконец-то выясним, что любое действие, включая бездействие, по нашему законодательству является правонарушением)

Да как бы в этих документов не появилось еще больше способов выстрелить себе в ногу...

ну, locale C уже есть, дело за малым… 8-)
Скоро стране потребуются переводчики с Си на русский!
С переводом Си на русский неплохо справится и автомат. Ведь Си — формальный язык. Вот с обратным переводом — уже сложнее. Пока что в основном это прерогатива человека. Но такие переводчики уже есть. Называются в простонародье «программистами».
Рискну высказать даже более сильное утверждение. С С, как, впрочем, и с любого другого формального языка, возможен абсолютно точный и 100% автоматический перевод на любой другой формальный или неформальный язык обладающий соответствующим свойством полноты. Достаточно лишь правила вывода задать.
Сегодня, 26 апреля 2016 г., арбитражный суд Орловской области должен был решить вопрос, является ли язык программирования C иностранным языком.

Эхо Чернобыля?
если язык иноСТРАННЫЙ, — то где та страна в которой на нем разговаривают?
А где связь, простите? Языков как минимум на порядок больше, чем стран.
В одной стране может быть языков больше чем один, так же как и наоборот — один язык больше чем в одной стране.
Тогда надо найти страну, в которой С признан государственным языком наравне с, к примеру, Суахили.
В первую очередь это именно английский. Тот факт, что фраза «разбавлена» Сишным синтаксисом, никак не влияет на семантику. Если я напишу какое-нибудь оскорбление, а потом между словами вместо пробелов буду ставить различные символы, это не перестанет быть оскорблением.
Правда?
А если я сконструирую некий искусственный язык, в котором обыденные слова или некоторые внешне бессмысленные наборы символов будут иметь оскорбительное значение, а потом опубликую рекламное объявление на таком языке?
В какой момент объявление станет запрещенным? Сразу — или после того, как я опубликую словарь такого языка?
Скорее всего, с момента опубликования словаря. Но это надо у лингвистов и юристов интересоваться.

Не понимаю, как можно приравнять язык программирования к языку на котором разговаривают?
Вы видели людей, которые разговаривают на языке С?

собственно любой язык на котором разговаривают люди это C
разница в том что после #define
На самом деле… Это роботы потихоньку захватывают власть.
только тсссс…
А много людей разговаривает на латыни?
UFO just landed and posted this here
UFO just landed and posted this here
Мда, на вполне внятном языке доходчиво читается. Хотя немного многословно.
Только момент не понял: через двое суток после собеседования сценарий падает?
Заметьте что нет строки Assert.IsTrue(devExpress.Salary.IsNice)
для того года это было наверняка nice :)
Ошибка в строке
Assert.IsTrue((DateTime.Now - visitTime) < new DateTime(0,0,0,2,0,0));

вычитание DateTime-ов даёт TimeSpan, который не сравнивается с DateTime.
need job, have skill, go to — это, конечно, ни разу не иностранный язык? :-)
Английскую фразу обернули в Си-подобную конструкцию, теперь троллят несчастных провинциальных судей :-)
Безграмотность и неквалифицированность не дает права развязывать руки и всячески ограничивать граждан в своих свободах. Суд в РФ уже давно не мерило справедливости и непредвзятости, а просто инструмент подавления со стороны государства и его чиновников.
И кого тут подавили? Кого свободы лишили?
Реклама на иностранном языке, с чем спорим? :-)
Я вот понять не могу: где вы рекламу углядели? Я вижу на картинке объявление для ищущих работу.
UFO just landed and posted this here
Не приведете цитату из закона, подтверждающую ваши слова?
Неправда ваша.
Из ФЗ: «объект рекламирования — товар, средства индивидуализации юридического лица и (или) товара, изготовитель или продавец товара, результаты интеллектуальной деятельности либо мероприятие (в том числе спортивное соревнование, концерт, конкурс, фестиваль, основанные на риске игры, пари), на привлечение внимания к которым направлена реклама».
Таким образом, закон не содержит отсылки к вакансиям. Практика, как правило, такие объявления рекламой не считает, но есть ряд оговорок, к примеру, продукты/услуги компании упоминать в вакансии не стоит. Или если идет объявление о вакансии от трудового агенства — тогда это реклама.
Иностранный язык — язык иной страны. Язык C — язык какой страны? Если судьи настолько бестолковы, что не могут распознать, что такое «иностранный язык», то им место полы мыть, а не кресло судьи занимать.
В русском языке могут использоваться слова из других языков, но от этого фраза на русском языке не перестает оставаться таковой. Аналогично, выражение на языке C может использовать идентификаторы из любого языка с латинским алфавитом, но от этого оно все равно не перестанет оставаться на языке C
Дружище! В одной только России 37 официальных языков (слыхали про республики?), из которых 15 — официально признаны государственными. О каких странах речь идёт? Слыхали про Северный Кавказ? Там больше десятка языков, относящихся к стране России.
Никакого более важного занятия ФАС Орловской области не нашла?
UFO just landed and posted this here
А я, наивный, думал, что органы безопасности и прочие ЗП должны получать за отсутствие проблем на участке, а не за выполнение нормы по заведённым делам.
Деда Мороза, тоже не существует, только тссс…

А вообще, палочная система не отечественное изобретение, и пользуются ей везде. Причём она всем не нравится, но заменить её нечем:)
А если проблем нет, то её нужно создать и решать.
Человек далёкий от программирования будет уверен в том, что это иностранный язык. Мало ли какие скобки и знаки пунктуации там применяются. При мало-мальском знании английского смысл становится ясен. Так что для обычного человека это будет именно иностранный язык. Иначе внизу была бы ремарка:«Читать и понимать только программистам и тем, кто в теме».
А если признают, можно указывать владение иностранным языком))
Все-таки тут в названии переменных явно видно, что использован английский язык. Даже не смотря на то, что это общепринятая практика, в суде могу придраться к этому. Тогда русская модификация должна выглядеть как-то так:
if (nuzhna_rabota && est_umenie) {
А также быть признан экстремистской организацией
Иностранным агентом, если быть точным. Все эти ваши C99, C11 явно пишутся под иностранную дудку. Мало ли чего там понапишут! Да еще и не на русском. Запретить, как бы чего не вышло. Просто запретить. Запретить!
ГОСТ-ты не помогут?) Или для создания новых ГОСТ-тов нужно иметь большое влияния?
Возможно не в тему
Си разрабатывался как проект ЦРУ, так и развивается.
При чем тут вообще язык программирования? Он здесь не более чем для стилизации.
ну если я китайский выучу то я же не стану китайцем
хотя…
если твойдед писал на С, отец писал на С и ты пишешь на С, то что-то в этом есть
Мне уже просто интересно, все чиновники реально так тупы как выглядят или прикидываются? Один не знает чем отличается свекла, другой никогда не видел сишного синтаксиса. Пи*дец какой-то, а мы ведемся. И интересно то, что ВСЕ меры, депутаты и прочие выходцы нецифрового века, все они — пережиток СССР. Ни одного молодого и образованного человека. Видать потому что разумные люди не так рвутся к этой дурацкой официальной власти и взаимному подрачиванию законопроектов друг друга. Особенно когда вокруг столько простора для самых разнообразных действий.
Печалька. Вот бы всех расстрелять и заменить программой. Главное Сивиллой не называть и может все получится.
Я считаю что нельзя останавливаться в собственном развитии только потому что нашел кормушку и нажрал пузо. Хотя это дело личное.
Ну а в 2016 году не то что не знать, а и просто не видеть ни разу синтаксиса языков программирования это уже даже не смешно. Зато, могу поспорить, 9 из 10 чинуш заходят во вконтактики и вообще хоть чуть-чуть пользуются компьютерами.

Раньше считалось что учить детей в школах делать киянки и ложки это достаточно. Тогда не было компьютеров. Но вот в 2016 почему-то даже учителя информатики в школах не знают как работает компьютер и учат как ходить на яндекс.

Короче говоря, с прогрессом в этих странах сейчас совсем чуть-чуть малость адовая жопа. От начала (обучение детей) и до конца (любой начальник любой государственной конторы).
Ну а в 2016 году не то что не знать, а и просто не видеть ни разу синтаксиса языков программирования это уже даже не смешно.
Ну почему бы тогда не требовать с поваров знания ядерной физики? Принцип тот же. Как ниже подсказали, для подобных случаев существуют эксперты и экспертизы.

P. S. Компьютерная грамотность != знание синтаксиса каких-то там языков программирования.
Потому что вы предлагаете знание, это крайность как и незнание. Но спросите у повара что такое ядерная физика, с очень высокой вероятностью он вам ответит что-нибудь про раздел физики такой, нужен для бомб и электричества. Это не крайность, это не знание и не незнание.
Никто не требует грамотности или знания синтаксиса. Это было бы крайностью.
В общем риторика от крайностей считается грязной и к использованию не рекомендуется вот уже почти 2000 лет.
Никто не требует глубокого знания программирования. Но если тому же повару показать формулы по математике, физике и химии, он же отличит, какая из них к какой области относится? Почему тогда он не должен знать, что четвертая «формула» — это некий язык программирования?
Вы серьезно?

image

image

image
Ну и с какого перепугу повар должен все это различать?
И как можно отличать формулы из физики и из математики, если физика использует математический аппарат как инструмент?

Про то, что повар должен еще и языки программирования распознавать — вообще молчу.
для этого по идее есть эксперты
Ну да, в таком судебном деле напрашивается комиссионная экспертиза с участием экспертов-лингвистов и программистов.
Ни одного молодого и образованного человека

Жизненного опыта мало. Чтобы руководить сложной системой, нужен опыт, который приобретается с годами. Иногда молодые (до 30) люди попадают во власть; если поискать, можно найти такие случаи. Но много ли вы знаете таких случаев, чтобы такой молодой властитель мудро руководил тем, что ему дали в управление?
все они — пережиток СССР

Вам не нравится СССР? Но ничего другого не было на территории современной РФ до 1992г. Все, кто родился на территории современной РФ до этой даты, не могут быть ничем иным, как «пережитком СССР». Вы предлагаете всех расстрелять:
Вот бы всех расстрелять

Но не за это ли ругают СССР, что, дескать, репрессии? Сами того не замечая, вы предлагаете совершать то, в чем обвиняете «совков».
Видать потому что разумные люди не так рвутся к этой дурацкой официальной власти

Погодите немного. Произойдет очередная смена поколений, и среди ваших сверстников начнется грызня не на жизнь, а на смерть, за участие в «дурацкой официальной власти».
«Иногда молодые (до 30) люди попадают во власть; если поискать, можно найти такие случаи.»
____
Далеко ходить не надо:
Никифоров Николай Анатольевич, Министр связи и массовых коммуникаций Российской Федерации, родился: 24 июня 1982 (сейчас 33 года), 21 мая 2012 года указом Президента России Н. А. Никифоров был назначен министром — то есть 30 ему еще не было, а уже министр.

И да, руководитель из него еще тот…
А название компании, по этому закону, тоже нужно переводить? Вот, к примеру, большой плакат с надписью Microsoft Windows 10. И всё, другого текста нет. То нужно дублировать в виде Микромягкие Окна 10?
Микромягкие Окна 10

Мелкомягкие же!
Маломягкие же, https://ru.wiktionary.org/wiki/%D0%BC%D0%B0%D0%BB%D0%BE
Неубедительно. Ни разу не встречал перевода «micro» как «мало». Вот «мелко», например, ещё у Н.Лескова в «Левше» встречается («мелкоскоп»).
Вы бы свою ссылку посмотрели. Оттуда перевод «мало»: little, a little bit, (a) few. Ни единого micro.
Это канонiчный перевод. А как переведут ФАС — можно только догадываться.
Очевидно же, «Майкрософт Виндоус 10».
А реклама будет выглядеть так:
иф (нид_джоб && хэв_скилл) {
  гоуту Сторк
}

Это они ещё AppleScript не видели:


tell application "Finder" to get POSIX path of (target of front Finder window as text)

Вообще-то знание иностранного языка не делает человека представителем другого этноса. Полиглотам в обратном случае будет вообще весело жить.
Дело не только в знании другого языка. Суть в том, что у носителей этого языка нет своей территории и государства. И потому они могут требовать право на самоопределение.
И почему ни кто не обратил внимания, что сама по себе конструкция, по меньшей мере, не полная. Допустим мне нужна работа и есть навыки, однако навыки у меня из другой ветки и работа, скорей всего, нужна не та, что может подразумеваться.

В общем я хотел бы видеть объявление, которое покрывает все случаи без ложных срататываний. Собственно потому goto и является лишним и неправильным, вот для этого и нужна правильная конструкция с условиями. Ну или хотя бы правильно объявить переменные, раз уж так им хочется goto использовать.
1) не ходите на это собеседование
2) если пойдёте, собеседование уточнит одинаковое ли у вас понимание
Так что, теперь все опенсорсные идентификаторы должны быть на русском языке?
Немного потроллю ФАС:
Если вам кажется что вы понимаете смысл этой фразы то вам это просто кажется.
Немножко потроллю Вас:
Если вам кажется, что вы не деаниномизированы, то вам это просто кажется.
Интересно, а почтовый адрес тоже надо переводить?
работа на сторк.ру?
Мне вот интересно — им там в ФАС реально что ли заняться нечем???
Когда коту делать нечего…
ФАС возбуждалось даже из-за безобидной надписи «Free WiFi» по той же причине.
Что у них случится в головах, если увидят например «Wi-Fi macht frei»?
Опять Орел опозорился… Стыдоба головушка…
А почему именно C? Этот код и на PHP прекрасно запустится.
Это же очень хорошо! :)

«Гражданский процессуальный кодекс Российской Федерации» от 14.11.2002 N 138-ФЗ (ред. от 30.12.2015) (с изм. и доп., вступ. в силу с 01.01.2016)
Статья 9. Язык гражданского судопроизводства

2. Лицам, участвующим в деле и не владеющим языком, на котором ведется гражданское судопроизводство, разъясняется и обеспечивается право давать объяснения, заключения, выступать, заявлять ходатайства, подавать жалобы на родном языке или на любом свободно избранном языке общения, а также пользоваться услугами переводчика.
ПлАчу из-под стола. Какая прелесть. Пора уже гимн, герб и флаг нового государства придумывать. =)
ФАРС — Федеральная антимонопольная российская служба
Чтобы определить на каком языке написано это объявление, на английском или на C, можно провести простой мысленный эксперимент:
есть два человека: один знает английский, но не знает С и других языков программирования; другой знает С, но даже поверхностно не знаком с английским, вот вообще ни одного слова не знает. Кто из них поймет значение этого объявления?

Каким образом человек может знать си, но не знать английского? Тем более ни одного слова, если там все операторы представляют собой чистейший английский. Со стандартами именования переменных и прочего. И практически все конструкции написанные логичным англофоном можно прочитать как слегка кастрированный, но всё равно английский? Что-то выше anykey в современном мире для программиста начинается с английского, потому что там содержится основная прорва информации, в том числе новой, пока ещё актуальной. Именно там можно найти пути карьерного роста и более высокая вероятность встретить людей-гуру, при чём без разницы, на какой ступени развития сейчас находится соискатель.

Каким образом человек может знать си, но не знать английского?

Жил в пещере, и была у него одна книжка «С для чайников» на русском.
Я самолично (на курсах английского) видел несколько программистов, которые пользовались англоязычными терминами, названиями операторов, даже не задумываясь о «нормальном» значении слов, они их запоминали как имена.
Но это все не важно. Это мысленный эксперимент, в этом его суть.
Подтверждаю. Я выучил бейсик раньше, чем начал учить английский; и с большим интересом обнаруживал, что у всех этих заклинаний, оказывается, есть и «непрограммистский» смысл.
То есть «знать си» равнозначно прочтению одной книжки «С для чайников» на русском языке. Нафиг хотя бы лет семь работы над крупным проектом в тиме, нафиг общение с себе подобными, никакие новые веяния, версии и стандарты не нужны; покупайте наших слонов…
Предположим, он прочёл более 9000 книжек про си, все на русском языке, и работал над крупным проектом в русскоязычном коллективе. Если остальные участники проекта и знали английский сами, нет никакой причины, чтобы они стали насильно учить английскому своего коллегу.
Я самолично (на курсах английского) видел несколько программистов, которые пользовались англоязычными терминами, названиями операторов, даже не задумываясь о «нормальном» значении слов, они их запоминали как имена.


Оно запоминается не именами, а как раз «образом» из ЯП. Как то развлекался анализом своих фраз по работе: англицизмов невероятно много и все они служат для подчеркивания рабочих моментов. В итоге получается, что Дата и Данные — это разные слова с точки зрения смысловой нагрузки, а в английском оно вообще может иметь смысл только применительно к конкретному случаю. Практикуюсь в английском и приходится вычищать свою речь от Delete вместо Remove, Data вместо Information и т.п. Друг дико ржет над тем, как я порой фразы строю, а оно уже в подкорку забито.
UFO just landed and posted this here

Тем забавнее выглядит сей махрово-чиновничий непробиваемый формализм.

Есть предположение, что корректнее этот текст должен было выглядеть примерно так:


if ( you( need_job && have_skills ) ) {
    goto Stork;
}

Не говоря уже о том, что этот код валиден на целом семействе языков с похожим синтаксисом (goto не выпиливается почти нигде, оператор ветвления, переменные, условный оператор AND и блоки кода — стандарт для высокоуровневых языков). А необходимость понимать это без перевода напрямую содержится в переменной have_skills...

нет, в C #define-константы принято писать полностью заглавными:

if ( you( NEED_JOB && HAVE_SKILLS ) ) {
goto Stork;
}
Желание работать и наличие навыков — это переменные.
Тогда все равно слегка по-другому:

if ( you( need_job ) && you( have_skills ) ) {
goto Stork;
}
То, что код не соответствует некоторым стандартам, не означает, что он невалиден. Этот код прекрасно скомпилируется, при чём много где, для большого парка компиляторов и зоопарка языков, под разные системы. Не говоря уже о том, что need_job, как и have_skills, попросту не могут быть константами.
Русскими символами можно пользоваться при программировании на Свифт, да что там: смайликами можно программировать!
Что они тогда скажут про рожицы и какашки? Что это язык?
Надо защиту в суде проводить на языке С. Как и писать прочие официальные бумаги.

Ритчи, Томпсон и Керниган — наши пророки. Страуструп — вероотступник, лживый мессия. Bell Labs — наша Мекка. И сейчас — 44-й год от основания мира. )
Да глупость очередная.
Русский язык — это естественный язык, а Си — язык формальный, но нифига не иностранный. Если ФАС не понимает разницы между этими двумя понятиями, то это их проблема, а проблема суда – разобраться, для этого достаточно пригласить нормального лингвиста который разжуёт судье разницу между этими двумя понятиями.
Я думаю, что смогу сейчас найти штук 5 реклам с математическими формулами/кванторами, к которым ФАС не имеет никаких претензий по поводу необходимости перевода формул с математического языка на русский.
Во, кажется хоть один комментарий по теме топика. Думаю они скажут, что язык программирования C использует слова из английского языка, а значит является подмножеством английского языка. А как же наличие особой формальной логики? Выше приводили большое количество примеров перевода на русский операторов и выражений языка, а также использование языка 1C, т.е. наличие такой логики не является неотделимой прерогативой C. Значит, компания нарушила закон о рекламе.

Интересно, а какие аргументы можно привести в защиту компании? Что-то я ни одного не могу придумать.
«Реклама — информация, распространенная любым способом, в любой форме и с использованием любых средств, адресованная неопределенному кругу лиц и направленная на привлечение внимания к объекту рекламирования, формирование или поддержание интереса к нему и его продвижение на рынке;»
(Из закона о рекламе)

В данном случае это информация адресованная определённому кругу лиц: программистам.
Написали бы не goto Stork(); а функцию какую-нибудь с передачей туда себя Stork(me);
Кстати, написал ещё раз Stork и подумалось — а этот чудной процесс точно не часть рекламной кампании?
Спасибо.
А вот это мне понравилось:
Специалист Ершов М.Н. суду пояснил размещенное на рекламном щите изображение
не является текстом на каком-либо иностранном языке, а копирует часть авторского
программного продукта, написанного на языке программирования «С++».

Это был всего лишь кусок кода на C++ из некой программы (по мнению специалиста Ершова)
Я бы еще добавил, что это вообще картина неизвестного художника.
image

Или использованные на картине иностранные слова тоже надо переводить?
catch(interviewException ex) {ex.printTrace()}
finnally {TakieDela();}
А координаты в WGS 84 тоже нужно дублировать в ПЗ-90?
По сообщению Михаила Паулкина суд первой инстанции они выиграли. ФАС сказала что пойдет выше. Продолжаем запасаться попкорном.
Было бы интересно почитать коментарии о судебном заседании. Ведь наверняка там были какие-нибудь перлы как с одной так и с другой стороны.

Ну что же, сегодня 27.05.2016 состоялось финальное заседание арбитражного суда Орловской области, на котором судья не согласилась с претензиями ФАС относительно нашего плаката с объявлением на языке программирования ))

Таким образом суд первой инстанции мы выиграли, но еще вчера представитель ФАС, открыто заявила, что будут обжаловать решение, и готовы идти до Высшего арбитражного суда.

Я так понимаю, у них (ФАС) денег куры не клюют, и они могут позволить себе такие расходы? Тогда мы тоже готовы продолжать ликбез и далее, если этого потребует ситуация
Мне всегда было интересно почему редакторы набросят на вентилятор, а чем всё закончилось предлагают отслеживать пользователям.
С чего вы взяли, что я (автор этой заметки) — редактор Хабра? Я такой же пользователь, как и вы. И в заметке приведены все необходимые ссылки для того, чтобы можно было узнать продолжение непосредственно у первоисточника, если это интересно.
Простите если это выглядит как камень в ваш огород, этим обычно страдают редакторы.

Articles