Столь необычным вопросом суд озаботился из-за Федеральной антимонопольной службы (ФАС), которая возбудилась вот на это объявление, размещённое напротив местного политеха:
ФАС посчитала это объявление рекламой, а по закону реклама на иностранном языке должна быть дублирована на русском. Руководитель компании Stork.ru Михаил Паулкин с выводами ФАС не согласился, и дело дошло до рассмотрения арбитражным судом Орловской области. Суд должен был вынести решение сегодня, но отложил заседание на 25 мая.
Нужно заметить, что признание судом языка программирования C иностранным языком позволит программистам на C бороться за официальное признание себя в качестве малого этноса. Малый этнос — это уже не обычное профессиональное сообщество, а народ. Народ же, не имеющий своего государства, может воспользоваться правом на самоопределение, записанным во Всеобщей декларации прав человека ООН.
Комментарии (345)
begemot_sun
26.04.2016 18:10+1А какие варианты то перевода?
mediakotm
26.04.2016 18:19+7*Нужна работа и есть умения – иди в Stork.
Ваш Кэп.begemot_sun
26.04.2016 19:46+6Не соглашусь, там это не написано. То что вы что-то придумали, ничего не меняет.
bolk
27.04.2016 07:17+52если (нужна_работа И есть_навыки) { иди_в _1С }
asmodeusta
27.04.2016 14:56+3Если НужнаРабота И ЗначениеЗаполнено(Навыки) Тогда
Перейти ~1С;
КонецЕсли;
mlurker
26.04.2016 18:31+20На 1С
retrograde
26.04.2016 19:29+3РАПИРА же!
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
Ohar
26.04.2016 21:45+5Для этого нужен дипломированный переводчик с Си на русский. Вы такого знаете?
begemot_sun
26.04.2016 22:44+3В данном контексте неизвестно что означают переменные и каковы их текущие значения и как они связаны с входными данными. Поэтому судить о том, что обозначает данная СИ-фраза не представляется возможным вообще.
SCareAngel
27.04.2016 00:28+2Очевидно, что данные переменные определяют, есть ли у кого-то скилл, и нужна ли ему работа. А от текущих значений зависит, пойдет ли этот кто-то на Stock.
Мне почему-то все предельно ясно. Что я делаю не так?Nimtar
27.04.2016 00:59+6Вы слишком доверяете названиям переменных.
int need_job = 14;
struct war* have_skill = (struct war*) malloc(16);
Stork: need_job += 'a';
if (need_job && have_skill) {
goto Stork;
}
Как-то так, например
profesor08
27.04.2016 01:51Все дело в том, что это лишь имена переменных, обозвать их можно как угодно.
bolk
27.04.2016 07:19Вот ФАС и требует обозвать их на русском.
profesor08
27.04.2016 08:14Хотя, если рассуждать логически, сравнивать человеческую речь и яык программирования — некорректно. Это же набор инструций и все. Это даже близно непохоже на язык. «Языком» они были обозваны в стародавние времена, чтоб обозначить тот факт, что программист может общаться с машиной. Только это нифига не общение. Ведь общение подразумевает двустороннюю комуникацию. Но с компьютерами двусторонняя комуникация невозможна, так как все «ответы» уже заранее подготовленны программистом.
Dioxin
27.04.2016 08:28Если хозяин отдает команду рабам на человеческом языке, а те просто молча выполняют — это не общение?
profesor08
27.04.2016 08:56Некудышный пример. Компьютер не обладает самоосознанием. А рабы каждый раз делают выбор, подчиниться или схватить наказание.
gearbox
27.04.2016 10:03Нет, они же ему не отвечают, не возражают, хозяин от рабов вообще ответа не ждет, откровений тоже. Сплошной императив.
DeadKnight
27.04.2016 13:24+4Угу
#define esli if
#define poshel_v goto
esli (nuzhna_rabota && est_znaniy) {
poshel_v Stork;
}
UrbanRider
27.04.2016 13:57+1Это лишь предположение.
Быть уверенным в том, что записано в переменную и записано ли в нее что-либо мы знать не можем.
edd_k
27.04.2016 03:59+1А каков данный контекст? И с чего вы вообще взяли, что это «СИ-фраза»? Потому что похоже?
Точно так же похоже, что словами «need_job» и «have_skill» авторы хотели обозначить «требуется работа» и «имеется навык».
И эти размышления не определяют, как реклама должна была бы выглядеть по закону. Это всего лишь ответ на ваш вопрос «Каким мог бы быть перевод?».
Diaver
26.04.2016 18:12+7Надо было продублировать на 1С.
meliko
26.04.2016 18:49+2Если (НужнаРабота И ЕстьНавыки) тогда
Перейти ~Stork;
КонецЕсли;dkv
26.04.2016 21:20+12Наличие кириллицы не делает этот текст написанным на русском языке. В противном случаем на КонецЕсли может возбудится уже не ФАС, а Роскомнадзор. И придётся запрещать 1С по всей стране и возвращаться к книгам бухучёта.
MrKit
27.04.2016 00:29-1В 1С нет аналога команды перехода goto.
meliko
27.04.2016 01:03+2В 1C команда Перейти ~Метка это и есть goto
MrKit
27.04.2016 02:00Упс! Действительно есть, век живи — век учись.
SuhoffGV
27.04.2016 14:04«Перейти» это не та вещь которую стоит знать в 1с.
MrKit
27.04.2016 14:29Пример у них убойный с бесконечным циклом, из которого не факт, что есть выход:
Пока Истина Цикл
Для Каждого Элемент Из МассивЭлементов Цикл
Если ВыполнениеУсловия(Элемент) Тогда
Перейти ~ВыходИзДвойногоЦикла;
КонецЕсли;
…
КонецЦикла;
КонецЦикла;
~ВыходИзДвойногоЦикла:
// продолжение вычислений
Dementor
29.04.2016 11:24+1Не согласен. Как то мне попалась работа «всего на 5 минут», где нужно было добавить условие по которому из 5-ой циклической вложенности требовалось попасть на уровень второго циклы. При этом кода было на 2-3 листа — анализировать и рефакторить можно было бы целый день. Но зачем, если за это платить никто не будет, а ты видишь этот говнокод в первый и последний раз в жизни? Вот тут знание про переход по меткам очень помогло.
Apatic
28.04.2016 10:03Тоже была такая мысль. Ну а вообще вариантов то много: РАПИРА, Кумир… Если поискать, то еще можно чего-нибудь найти.
В конце-концов, что мешало им сделать просто блок-схему! :)
nubko
26.04.2016 18:20-1Разве одного языка достаточно для того что бы считать себя единым народом?
Разве главное не происхождение?art_of_press
26.04.2016 18:23+6«Этничность можно представить как форму общественной организации культурных различий, состоящей из тех характеристик, которые сами члены этнической общности считают для себя значимыми и которые лежат в основе их самосознания. К этим характеристикам относится также обладание одним или несколькими общими названиями, общие элементы культуры, представление об общем происхождении и, как следствие, наличие общей исторической памяти.…
Определение этничности строится также на основе культурной самоидентификации этнической общности по отношению к другим общностям (этническим, общественным, политическим), с которыми она находится в фундаментальных связях.» https://ru.wikipedia.org/wiki/Этнос
«Этнос — исторически сложившаяся этническая общность — племя, народность, нация.
Нация — исторически сложившаяся устойчивая общность людей, образующихся в процессе формирования общности их территории, экономических связей, литературного языка, особенностей культуры и духовного облика.» С. И. Ожеговaklis
27.04.2016 16:51+1Признаю: все эти определения можно пусть и с оговорками примерить на си разработчиков. Но ведь скажем если я выучу татарский язык — я ведь не стану татарином?=)
art_of_press
27.04.2016 17:16+3Вы можете быть татарином и не зная татарского языка.
Вообще, в современном мире национальность определяется самоидентификацией. Вы сами должны определиться (если хотите), кто вы больше — русский или сишник.
При переписи населения вас просто попросят указать, кто вы по национальности, не вдаваясь в подробности национальностей бабушек или дедушек, а если вы не захотите говорить переписчику свою национальность, настаивать не имеют права.
akaChewy
27.04.2016 14:56Если про образование народа по языкопрограмистскому признаку не писали в фантастическом произведении, то это маловероятно.
Напишите, если знаете такие произведения.
fireptyca
26.04.2016 18:20+2Если арбитражный суд откажет в иске, то надо подать групповую аппеляцию в международный суд по правам человека. Даже до ООН дойдём!
MaxAlekseev
26.04.2016 18:37-24GOTO!!! Си!!! Карл!!!
Foolleren
26.04.2016 18:56+11вот из за таких как вы из повершела убрали GOTO. и для того чтобы выскочить из одного цикла в другой приходится мудрить переменные и проверки.
zedalert
26.04.2016 21:54А когда это он там был?
Foolleren
26.04.2016 22:03убрали ещё на этапе разработки.
MaxAlekseev
26.04.2016 22:23-1Вот это поворот
вот из за таких как вы из повершела убрали GOTO
убрали ещё на этапе разработки
Я не знаком с данным продуктом, но по факту получается, что GOTO нет в первоначальном релизе… т.е. по задумке авторов изначально оператор безусловного перехода не предусмотрен. Вам не кажется, что «такие как я» тут как бы не причем, т.к. GOTO не было в релизе от слова совсем.А то я уже стал сыпать голову пеплом… а оказалось вон оно как.Foolleren
26.04.2016 22:35так ведь разработчики и относятся к ненавистникам goto
в замен дали break :label
Но както через жо
В Windows PowerShell иметь метки могут только ключевые слова цикла, такие как Foreach, For, While.
в результате из цикла можно выскочить только в начало другого цикла или в конец этого.
Экспресс в середину цикла? да кому оно надо подумали они.MaxAlekseev
26.04.2016 22:43так ведь разработчики и относятся к ненавистникам goto
Вы напрасно ярлыки развешали. Я не ненавистник, я его просто не использую в си, а студентам просто не говорю, что так можно. При этом в проектах на асмеgotojmp — это наше все.
Приведите пример безусловного перехода в середину цикла на си…а то у меня мозг ломается от такой задачиFoolleren
26.04.2016 22:57не фанат С но вроде компилируется в билдере
просьба сильно не пинать мне ассемблер роднее чем С#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; }
murzilka
27.04.2016 21:20Я думал, что в си через goto обрабатывают ошибки.
Как вы их обрабатываете без goto?DrSavinkov
27.04.2016 21:21В С++ есть try-catch блоки, из того что встречал. Не знаю, имеется ли такой механизм в C.
По факту ошибки выполняется throw(чё произошло) и ловится в catch. Дальше уже пляшем.
Возможно, есть что-то ещё.murzilka
27.04.2016 21:25+1В Си нет try, catch и исключений.
Abstraction
28.04.2016 15:16+1… но есть setjmp() и longjmp().
murzilka
28.04.2016 15:26+1По форме (а не по содержанию) ничем не отличается от goto: прыгнуть туда-то.
Т.е. longjmp ближе к goto, чем к генерации исключения.
profesor08
27.04.2016 02:02-1Благодаря этому коментарию, вспомнил что в php есть такая вот штука (http://php.net/manual/ru/control-structures.break.php). В сам break можно передать параметр, который укажет, через сколько уровней цикла можно перепрыгнуть. Добавляет приятный сахарок в синтаксис и отменяет необходимость в «флажках».
EvilBeaver
27.04.2016 14:05break с упоминанием какой именно цикл прервать??? И как такое читать потом?
herr_kaizer
26.04.2016 19:11+17Ничего страшного в GOTO нет, тем более в Си. Очень часто его использование очень оправдано.
5oclock
26.04.2016 19:36+4Нам, излишне наверное категоричный, преподаватель запретил использовать goto. Поначалу было не комфортно, но потом мозг перестроился и с тех пор уже 20 лет как отсуствие goto в программёрской практике совершенно не напрягает. Я уже про него и забыл.
Могу осторожно согласиться, что я просто не встречался с задачами, где без goto никак.Foolleren
26.04.2016 19:44+1Вот вам такая выскочить из середины одно цикла в середину другого. Обойтись можно но надо мудрить кучу if else.
PaGrom
26.04.2016 20:02+9Смутно представляю, когда может появиться такая необходимость. Уверен, что в таких случаях код можно переписать более красиво.
comargo
26.04.2016 20:10+1Я, честно говоря, плохо понял что имел ввиду Foolleren, но типовой случай использования goto в C/С++ это выход из двойного цикла (например если мы гуляем по дву-/трехмерной таблице и дошли до точки).
Википедияfor implementing multi-level break and continue if not directly supported in the language; this is a common idiom in C. Ссылка на википедию с ссылкой на источникDrSavinkov
26.04.2016 22:14bool 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; } } }
Чем не решение? Случай синтетический, лично не доводилось использовать такие конструкции.5oclock
26.04.2016 22:26+2break'ами мне кажется быстрее будет, чем на каждой итерации проверять состояние переменной.
DistortNeo
27.04.2016 00:29+1На ум приходит сразу 4 решения:
1. Обернуть код в функцию (предпочтительно).
2. Написать двумерный итератор (тоже хороший вариант).
3. После go_out поставить break, и проверять условие только во внешнем цикле.
4. Заменить go_out на x = 1025, y = 1025 (крайне нежелательно).
CTAPOBEP
27.04.2016 00:29+5Нужно просто вынести этот код в функцию и return'ом вернуть найденный элемент.
DjOnline
27.04.2016 13:07+5Тем что это медленнее.
Goto — это нативная команда ассемблера, JMP и куча нативных Jxx, из этого состоит весь компилированный код.
Вместо этого в твоём примере тратим память на абсолютно ненужную переменную, на доступ к памяти, на чтение памяти каждый раз в этой миллионной интерации, вместо того чтобы сделать один goto и съэкономить миллиадры циклов процессора. Даже если go_out будет лежать в регистре, это всё равно не бесплатная операция проверки.
А потом удивляемся, почему у нас всё везде тормозит на 8 ядрах и 4х гигагерцах, потому что каждый уровень разработчиков абстракции побоялся где-то чуть оптимизировать код и побоялся «богомерзкого» нативного goto, якобы «кто-то сказал что так нельзя». Эти же люди бояться писать без «ооп», делают фабрики фабрик даже там где это не нужно и совсем не думают о производительности.FoxCanFly
27.04.2016 15:23-1Если у вас " тормозит на 8 ядрах и 4х гигагерцах" и производительность упирается в проверки флагов и серьезно улучшается от внедрения повсеместно goto, тут что-то у вас не так.
DrSavinkov
27.04.2016 18:00Не согласен. Из-за частого обращения будева переменная будет висеть в кэше и время доступа будет крайне малО.
Foolleren
27.04.2016 18:08и я не согласен, закидывание переменных в регистры в зависимости от процессора даёт в худшем случае 1% буста в лучшем 20+%. профилирование кодека divx выявило, что вытаскивание переменных из стека занимает большую часть времени функции.
GennPen
27.04.2016 02:27Как вариант можно использовать 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) {}
eld0727
27.04.2016 08:26+8а ничего, что механизм исключений очень дорогой и является наихудшайшим вариантом из всех возможных?
alan008
27.04.2016 12:01а ничего, что иногда выйти из вложенных циклов нужно всего один раз. В таком случае дороговизна генерации исключения и его отлова роли не играет.
DistortNeo
27.04.2016 12:13+1При этом затраты на обработку исключения могут быть на порядок больше, чем собственно выполнение цикла.
murzilka
27.04.2016 21:33А чем исключение лучше goto? В ситуации, когда надо выйти из вложенного цикла, и то, и то — костыль. Но goto костыль дешевый и логичный. А генерация исключения — дорогой и нелогичный.
5oclock
27.04.2016 22:07Исключения лучше чем goto потому что корректно уничтожают автоматические переменные.
А goto просто прёт напролом.
Насколько я понимаю.tyomitch
28.04.2016 02:40Нет, 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.
5oclock
28.04.2016 07:40+1А там куда прыгнули — так же всё создастся в порядке появления в коде, как я понимаю?
Тогда это не просто jmp куда-то на метку, получается, а сложная конструкция.tyomitch
28.04.2016 11:50It 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.
5oclock
28.04.2016 18:34+1В общем, не всё так просто с этими goto.
Мутная тема. По крайней мере в С++, где не только POD.tyomitch
28.04.2016 18:55В С++ вообще нету простых тем :-Р
Но по крайней мере, компилятор вам не даст «запрыгнуть» внутрь блока в обход инициализации переменных. Или переменные инициализируются по умолчанию (некоторые компиляторы, включая MSVC++, в «нестрогом» режиме это разрешают), или будет ошибка компиляции.
Foolleren
26.04.2016 21:07Когда я полез за тем что бы узнать чем вообще заменить GOTO в повершеле, наткнулся на такой кейс
раскрашивание логов в html, мне он нужен был для совершенно не нормального применения — сравнить скорость работы алгоритма в разных ЯП ну и бонусом в повершеле.
также призывается comargo
5oclock
26.04.2016 20:25+1Волосы дыбом встают от такого алгоритма :)
Foolleren
26.04.2016 20:43Угу, без комментариев понять, что происходит совсем не просто, за это собственно GOTO и не любят, но местами с ним всё же проще чем без него.
DimkaI
26.04.2016 22:59Вы так или иначе условие выхода из цикла будете проверять через if или case. И если вы прервёте выполнение цикла по break или продолжить очередной цикл по continue не проходя до конца весь цикл, вы получите такой же функционал, который прекрасно работает без goto и значительно облегчает понимание алгоритма и его отладку.
Foolleren
26.04.2016 23:10Да выход в таком случае будет всё равно через if, но когда надо прыгнуть в середину другого цикла, без goto получается проблема.
DimkaI
26.04.2016 23:34Такой же if но уже в другом цикле. Разве нет? Ведь цикл у всё равно нужны условия начала, окончания цикла. Не всё ли равно начинать в начале цикла проверку какую часть выполнять или в середине?
Gutt
28.04.2016 09:36Надеюсь, я правильно понял семантику требования «прыгнуть в середину другого цикла».
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; }
В нужном месте той огромной нечитаемой функции, из одного из циклов которой нужно прыгать в середину другого, вместо цикла вставляете вызов функции. Заодно и читаемость повысится.Foolleren
28.04.2016 12:07когда я говорил про середину, то имел в виду совсем середину — не кратную
— надо начать с doAnotherJob_2();
private void doSecondCycle(from, to) { int i; for (i=from; i<to; i++) { doAnotherJob_1(); doAnotherJob_2(); return; }
Gutt
28.04.2016 16:33Можно задать выполнение нужных частей кода битовой маской или значением 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 будет удобнее. Но случай какой-то уж больно маргинальный.Foolleren
29.04.2016 01:01-1случай действительно очень редкий, и очень хорошо подходит чтобы запутать предсказатель ветвлений старого процессора, например разница между феном 1100 и вишерой 9590@ оказалась 8 раз при выполнении в 1 поток при выходе/входе через goto, интеловских свежаков для сравнения к сожалению нет,
когда руки дойдут сравню различные способы обойти goto где он действительно просится( запрыгнуть в середину цикла), но беглый взгляд подсказывает что goto должен отработать быстрее вызова функции.
Gutt
27.04.2016 14:56Надеюсь, я правильно понял семантику требования «прыгнуть в середину другого цикла».
private void doFirstCycle() {
int j;
for (j=0; j
alexhott
26.04.2016 21:09Написанный в прошлом такой свой код (с кучей IF и прыжками из одной части в другую в гигантском цикле) сейчас считаю примером того как не надо было писать.
И живет он теперь почти как ИИ, хрен знаешь что выкинет в следующий раз.
Лучше переписать так чтобы в принципе не нужно было из середины цикла кудато прыгатьFoolleren
26.04.2016 21:31ну вот смотрите у нас есть условия которые проверяются для какого то массива, если проходит, то проверяем другие условия во втором цикле, и вот тут если не проходит надо сделать первое и второе если не проходит то только второе.
можно сделать goto на второе
или сделать ещё одну переменную и break`ом оборвать первый цикл, а потом пройтись по куче if, когда количество итераций плавно так уходит за 6 лямов, каждый if в цикле делает вас печальнее.Cr558
26.04.2016 23:08+1А чем Вас return не устроит, с нужным разбиением на функции, как раз вывалитесь где надо?
Foolleren
26.04.2016 23:13в си функции по умолчанию передают параметры через стек, работа со стеком не на всех процессорах происходит без потерь для производительности.
HurrTheDurr
26.04.2016 23:25+3Я думаю, любой нетривиальный компилятор С сделает одиноко вызываемую функцию inline'овой, а все return'ы из нее заменит на jmp'ы, которые, по сути, те же goto.
Vladiator
27.04.2016 14:42В Джаве нет goto, а для выхода из нескольких циклов есть типа такого:
a: while(true) { while(true) { if (Math.random() < 0.5) { break a; } } }
bak
26.04.2016 19:58+9Основной паттерн использования goto в современном си — досрочный выход из функций с корректным освобождением ресурсов. Возможно у вас предмет называется c++, в котором использовать goto действительно не желательно. В си — это абсолютно нормальное явления — возьмите любой крупный сишный проект.
5oclock
26.04.2016 21:42+1Учили-то мы C, хотя последние лет 15 программирую в основном на C++.
Но первые лет 5 и после тогда отвлекался на С. Модуль ядра линукс даже помнится писал.
Но нигде алгоритм не упирался в goto. Так, что прям без него вот ну никак.
И даже на c++ не всегда RAII использую. Но обхожусь без goto и, повторю, ни разу не вспоминал про него в духе: эх, тут goto просится.
MichaelBorisov
26.04.2016 20:05+8Есть прекрасный паттерн использования 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; }
Без него при каждом открытии файла был бы иф с кучей команд освобождения ресурсов и возвратом по ошибке. При этом код освобождения ресурсов дублируется, что загромождает программу. А еще в таком коде легко допустить ошибку.SerJook
26.04.2016 20:14-5Как только люди не извращаются, лишь бы на нормальном C++ с RAII не писать.
comargo
26.04.2016 20:25+5И как Вы на «нормальном C++ с RAII» напишете модуль ядра линукса?
tangro
26.04.2016 20:44-8А это уже вопрос религии линуксоидов, а не технологии. Как-то вот в Windows и MacOs это можно сделать, а красноглазым чисто Эго не позволяет до С++ опуститься.
MichaelBorisov
27.04.2016 00:26+1Ядро Windows тоже на «голом» C написано. И большая часть драйверов, работающих в режиме ядра — тоже. Боюсь, что, даже если где-то в ядро можно влезть с C++ — то там будут ограничения по используемым возможностям, например — отсутствие полной поддержки исключений.
tangro
27.04.2016 01:53+1Есть нюансы, кто же спорит. Но уж такую мелочь как RAII всё-же потянет.
MichaelBorisov
27.04.2016 20:49RAII без исключений невозможно, а исключения — один из «тяжелых» механизмов C++, который в контексте ядра ОС может не поддерживаться или поддерживаться ограниченно. Например, для обычного кода использование исключений может быть возможно, а для всяких ISR и DPC — нет.
Также не стоит забывать, что обстановка в ядре ОС сильно отличается от обстановки в user-space. В user-space у вас обычно есть потоки, и каждый из них выполняет какой-то длинный код, захватывая ресурсы и освобождая их. Здесь RAII работает хорошо. А в ядре у вас в основном callbacks (в числе которых ISR и DPC), короткие функции, которые должны быстро отработать и выйти. Захваченные ресурсы зачастую удерживаются между вызовами этих функций, а вызваны они могут быть в контексте разных потоков и процессов. Так что RAII в чистом виде здесь имеет ограниченное применение, как, впрочем, и вышеприведенный паттерн с goto.5oclock
27.04.2016 22:13+3А почему RAII невозможно без исключений? o_O
MichaelBorisov
28.04.2016 21:04А как вы будете сообщать об ошибке из конструктора? Сообщать об ошибках инициализации членов класса или базовых классов? Уничтожать уже созданные члены?
Какие-то костыли, конечно, можно придумать, но от этого вся красота и удобство RAII сходят на нет.5oclock
28.04.2016 22:39Суть RAII заключается не в том, чтобы бросить исключение в конструкторе.
А по вашему вообще ООП без исключений невозможно получается?MichaelBorisov
28.04.2016 23:34+1Суть RAII заключается не в том, чтобы бросить исключение в конструкторе.
Я не говорил, что «бросить исключение в конструкторе — это суть RAII».
Но возможность бросить исключение в конструкторе является критической для реализации RAII так, чтобы код получался красивым и корректным. Поясните пожалуйста, как можно реализовать RAII без исключений в конструкторе?
А по вашему вообще ООП без исключений невозможно получается?
Этого я тоже не говорил.5oclock
28.04.2016 23:50В общем случае, ошибки при захвате ресурса может и не быть.
Так что вовсе не обязательно конструктор должен бросать исключение.
Ну и если могут быть ошибки, можно оставить проверку ошибок для отдельных функций, а не кидать исключения.
Конструктор открыл файл.
Внешний код вызвал функцию проверки всё-ли в порядке.
Файловые потоки stl c++ так и работают.MichaelBorisov
29.04.2016 00:06+1В общем случае, ошибки при захвате ресурса может и не быть.
Это скорее исключение, чем правило. В подавляющем большинстве случаев функции захвата ресурсов могут вернуть отказ. На то они и ресурсы, чтобы исчерпываться.
Ну и если могут быть ошибки, можно оставить проверку ошибок для отдельных функций, а не кидать исключения.
И тогда 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.5oclock
29.04.2016 00:53Вы не путайте выделение ресурса с его захватом.
И память может быть уже выделена и уже после отдаётся для управления RAII-объекту.
И мьютекс уже заранее создан и отдается на блокирование RAII-объекту.MichaelBorisov
29.04.2016 21:24Вы не путайте
Уважаемый, пожалуйста не используйте в разговоре со мной такой поучительный тон. Еще неизвестно, кто из нас что путает.
И мьютекс уже заранее создан и отдается на блокирование RAII-объекту.
То, что он заранее создан, не гарантирует, что функция блокировки по мьютексу завершится успешно. В винде, например, есть такой код возврата WAIT_ABANDONED. Можете погуглить, если интересно.
Ну и даже если вы найдете примеры, когда ошибка в конструкторе возникнуть не может — все же это не опровергает, что при захвате, выделении, или каких угодно операций в отношении ресурсов чаще встречается ситуация, когда может возникнуть ошибка, чем наоборот. И пример с goto, с которого началось обсуждение, как раз возник из задачи обработки ошибок. К чему вы вообще сюда приплетаете участки кода, где ошибок возникать не может?
Вам выше был задан вопрос, можете ли вы реализовать обработку ошибок на базе RAII, но без исключений. И привести пример для сравнения. Вопрос остался без ответа. Не можете?5oclock
29.04.2016 21:43Если Вы пишете:
«В подавляющем большинстве случаев функции захвата ресурсов могут вернуть отказ. На то они и ресурсы, чтобы исчерпываться.»
и не делаете разницы между выделением ресурса и его захватом, то мне ничего не остаётся как указать на этот недочёт, уважаемый :)
Теперь что касается RAII без исключений: RAII это всего лишь ООП-техника управления ресурсами. Вы отказались от «своих» слов, предложенных мною:
«А по вашему вообще ООП без исключений невозможно получается?
Этого я тоже не говорил.»
Стало быть согласны ООП и исключения — не две стороны одной медали. И одно без другого вполне может существовать.
Стало быть и RAII можно сделать без исключений.
И ошибочки после конструктора проверить незазорно (я привёл пример работы с файловыми потоками).
Или, например, какая может возникнуть ошибка в конструкторе какого-нибудь авто указателя, которому сдают на управление память? Что он не сможет в свою внутреннюю переменную-указатель положить переданное в параметре значение?
Вы написали, что без исключений нельзя построить RAII.
Для того, чтобы опровергнуть это утверждение — достаточно привести хотя бы один пример.
Указанной парочки хватит?MichaelBorisov
29.04.2016 22:52и не делаете разницы между выделением ресурса и его захватом
По сути дела, с точки зрения RAII, это одно и то же. В обоих случаях ресурс надо вернуть (очистить, освободить), и в обоих случаях может возникнуть отказ.
то мне ничего не остаётся как указать на этот недочёт, уважаемый :)
Вы так старательно заостряете внимание на мелочах — вам явно хочется увести обсуждение в сторону от исходной темы.
Стало быть согласны ООП и исключения — не две стороны одной медали. И одно без другого вполне может существовать.
Стало быть и RAII можно сделать без исключений.
Из одного не следует другое. Я вам дважды предлагал привести пример реализации RAII без исключений для открытия файлов и обработки ошибок их открытия. В ответ — тишина. Если можно сделать — сделайте. Думаю, что на написание ваших сообщений с придирками к мелочам ушло больше вашего времени, чем на написание предлагаемого примера.
И ошибочки после конструктора проверить незазорно (я привёл пример работы с файловыми потоками).
«Проверяние ошибочек после конструктора» — это по сути не RAII, так как при использовании RAII ресурс выделен (захвачен), пока существует объект, им управляющий, и наоборот.
Вы привели в пример весьма неудачное решение из стандартной библиотеки. Создается, к примеру, объект ofstream, но существование этого объекта не означает возможность записи в поток. Эта архитектура появилась до изобретения RAII в C++ (а возможно — и до введения в этот язык механизма исключений) и сохраняется лишь как наследство с целью совместимости.
Для сравнения возьмите приведенный выше класс RaiiFile. Здесь у объекта имеется инвариант: пока он существует, файл открыт, как только удаляется — файл закрыт. С такой архитектурой работать значительно проще.
Вы написали, что без исключений нельзя построить RAII. Для того, чтобы опровергнуть это утверждение — достаточно привести хотя бы один пример.Указанной парочки хватит?
Ваши примеры мое утверждение не опровергают. Случай отсутствия возможности ошибок в конструкторе не охватывает все области применения RAII, поэтому он не может рассматриваться как общее решение задачи. Что же касается ofstream — аргументы приведены выше. Это неполноценное RAII, так как не соблюдается инвариант.5oclock
30.04.2016 09:04Ещё раз:
Вы утверждаете, что RAII без исключений невозможно.
Я привёл 2 опровергающих примера. С точки зрения формальной логики достаточно и одного.
Вы акцентировали внимание на удобном Вам примере с файловыми потоками, не считая их по сути RAII. По вашему — RAII это однозначность: если объект есть — ресурс захвачен.
По мне так более важная работа происходит в деструкторе. Он «автоматически», самостоятельно, незаметно для программиста подчищает ресурсы. Конструктор же работает «под управлением» программиста и так или иначе — всё-равно проверка его работы осуществляется. Или вызвать функцию или ловить исключение. Всё-равно писать код. Или сразу после создания объекта или «где-то внизу». Это уже не принципиально и не является сутью RAII.
Суть его — в деструкторе.
И в этом смысле файловые потоки stl — самое обычное RAII.
А с какой «архитектурой» работать проще: с исключениями или с «ручной» проверкой ошибок — по большей части вопрос вкуса.
У исключений есть, на мой взгляд, только 2 существенных плюса:
1. Исключение не пропустишь. Вручную ошибку можно забыть проверить или, если какая-то стороняя библиотека, то в новой версии в ней могут появиться новые исключения.
Но, опять таки, что лучше — упавшая на непойманном исключении программа или программа не проверившая ошибку и ковыляющая дальше — зависит от ситуации.
2. Иерархия классов исключений, которая позволяет ловить их не по одиночке, а группами.MichaelBorisov
30.04.2016 11:18Я привёл 2 опровергающих примера. С точки зрения формальной логики достаточно и одного.
Вы не привели ни одного опровергающего примера.
Здесь ситуация такая же, как если бы я утверждал, что корни полинома 8й степени в общем случае нельзя найти аналитически, а вы «опровергали» бы это, приводя в пример уравнение вида x^8=64, которое таким образом решить можно.
Наличие легких частных случаев не означает, что общая задача решается так же легко, как эти частные ее случаи.
Вы акцентировали внимание на удобном Вам примере с файловыми потоками, не считая их по сути RAII.
Удобный мне пример? Ни в коем случае. Это был удобный вам пример, который вы настойчиво проталкиваете к обсуждению. Я вынужден был его разобрать, раз вы так настаивали.
По вашему — RAII это однозначность: если объект есть — ресурс захвачен.
Ну а как иначе? Прочитайте, что ли, определение RAII. «Resource acquisition IS initialization». В случае с ofstream, объект после отработки конструктора инициализирован? Инициализирован. Ресурс захвачен? Не захвачен. Какое здесь может быть RAII?
По мне так более важная работа происходит в деструкторе.
Деструкторы — это необходимый механизм реализации RAII в C++. Но недостаточный. Другим необходимым механизмом являются исключения.
Конструктор же работает «под управлением» программиста и так или иначе — всё-равно проверка его работы осуществляется. Или вызвать функцию или ловить исключение.
Полагаю, под фразой «вызвать функцию» вы имели в виду «выполнить проверку»?
Вот вы написали выше про деструктор: «Он «автоматически», самостоятельно, незаметно для программиста подчищает ресурсы».
Это очень важное преимущество. За счет автоматизации подчистки ресурсов исключаются ситуации, когда программист «забыл» это сделать вручную. Также код очистки ресурсов не загромождает программу, облегчая понимание ее основной логики.
Но не деструкторами едиными жив RAII. Есть еще вторая проблема — проверка ошибок при захвате ресурсов и досрочный выход из функции в случае ошибки. Этим в C++ занимается механизм исключений в конструкторах. Благодаря ему, вашими же словами: «автоматически», самостоятельно, незаметно для программиста проверяются ошибки при захвате ресурсов.
Не находите сходство? В обоих случаях идет автоматизация одного из важных аспектов работы с ресурсами.
Отсутствие исключений в конструкторах делает невозможной автоматизацию проверки ошибок при захвате ресурсов. От этого попытка реализации RAII в C++ теряет, грубо говоря, половину своих преимуществ.
А с какой «архитектурой» работать проще: с исключениями или с «ручной» проверкой ошибок — по большей части вопрос вкуса.
Если распространить вашу логику на деструкторы — то получится, что RAII можно сделать и без деструкторов, вручную очищая ресурсы, и это лишь вопрос вкуса.5oclock
30.04.2016 12:35Что-то у меня кнопки форматирования текста пропали, приходится отвечать просто текстом, без цитат.
1. У Вас прямым текстом было написано:
«RAII без исключений невозможно».
Никаких общих или не общих случаев. Просто написано: невозможно.
Я привёл примеры — ну хорошо, не нравятся Вам файловые потолки, но Вы уже второй раз игнорируете второй пример с автоуказателем.
У которого в конструкторе не может быть ошибок.
2. Ваши слова:
«В случае с ofstream, объект после отработки конструктора инициализирован? Инициализирован.»
С чего Вы взяли? Он — создан, а вот инициализирован он до конца (в его, объекта семантике) — это нужно у него узнать.
Да, спросить:
if (!myFileStream) return;
Или, как Вы настаиваете, ловить исключение:
try
{
…
}
catch (Exception& e)
{
return;
};
Оба варианта годятся.
Мне вариант с исключениями не нравится громоздкостью. Плюс Вы же сами упомянули, что исключения — «тяжелый» механизм.
Но не вижу причин делать тот или иной механизм обработки ошибок неотъемлемым признаком RAII.
3. «Вот вы написали выше про деструктор: «Он «автоматически», самостоятельно, незаметно для программиста подчищает ресурсы».
Это очень важное преимущество.»
Преимущество… Я настаиваю, что именно это и есть суть RAII. А не принцип проверки ошибок инициализации.
4.«Но не деструкторами едиными жив RAII. Есть еще вторая проблема — проверка ошибок при захвате ресурсов и досрочный выход из функции в случае ошибки. Этим в C++ занимается механизм исключений в конструкторах. Благодаря ему, вашими же словами: «автоматически», самостоятельно, незаметно для программиста проверяются ошибки при захвате ресурсов.»
Во-первых, Вы сами упоминали, что исключения — это не единственный способ сообщить об ошибке.
Во-вторых, никакой «автоматической проверки ошибок» исключениями — нет. Программист всё-равно должен написать код проверки.
Но по Вашему — не в месте возникновения ошибки, а в блоке catch. Ну, как я уже писал, это дело вкуса и к RAII не имеет отношения.
Единственное что однозначно характеризует RAII — это работа деструктора.
И именно поэтому не катит ваше утверждение:
«Если распространить вашу логику на деструкторы — то получится, что RAII можно сделать и без деструкторов, вручную очищая ресурсы, и это лишь вопрос вкуса.»MichaelBorisov
30.04.2016 13:481. У Вас прямым текстом было написано:
«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 так же, как и без деструкторов.5oclock
30.04.2016 14:07«Как говорится, переубедить мне Вас не удастся, поэтому сразу перейду к оскорблениям»
:)
Мы досконально, как я вижу, выяснили позиции друг друга.
Каждый остался при своём мнении, которое однако не мешает никому из нас использовать принцип RAII по своему. Благо он это позволяет.MichaelBorisov
30.04.2016 14:12Ну хорошо, можно остановиться и на этом. «Agree to disagree», как говорят американцы.
DistortNeo
29.04.2016 00:08Гораздо более пикантная ситуация — это ошибка в деструкторе.
MichaelBorisov
29.04.2016 21:17Ошибка в деструкторе, да… Как ее обрабатывать — непонятно совершенно. Красивых решений на данный момент я не нашел. Разве что логировать. Прерывать исполнение деструктора, как правило, недопустимо даже при ошибках.
beeruser
26.04.2016 20:21+3разве так не проще?
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;
}
Что тут дублируется?Layan
26.04.2016 20:58+2Ничего не дублируется. Но если файлов открывать не три, а десять (или просто много), то нормальные отступы будут выглядеть гораздо хуже, чем в ситуации с goto.
5oclock
26.04.2016 21:47+2Меня код даже с тремя 3 файлами в одной функции смутил, а уж 10…
MichaelBorisov
27.04.2016 00:30А каким образом вы будете писать код, если надо одновременно открыть 3 файла? В разных функциях будете открывать? А ошибки где проверять и закрывать уже открытые файлы, если часть из них открылось, а часть — нет?
Причем это не обязательно должны быть файлы, это могут быть любые другие ресурсы, у которых подобная модель захвата с возможностью отказа. Память, например.5oclock
27.04.2016 02:10Код можно структурировать и даже в принципе алгоритм реализовать — разными способами.
Но универсального ответа на ваш вопрос «как» — я дать не могу.
Это нужно разбираться в каждом конкретном проекте.
Ну и, повторю, наверное есть алгоритмы, где без goto или некуда или замена будет гораздо корявее, чем вариант с goto.
Но я с такими за 20 лет — не встречался.Keltir
27.04.2016 14:56Названия файлов в константу, дескрипторы в массив, если у вас сишников так все не просто, можно и флаги «файл 3 открыт» в массив записать. И никакого goto, и хоть 20 файлов открывай, кода больше не станет.
Я с таким за 3 года работы часто сталкивался, что в элементарных случаях пишут вот такую портянку, и говорят что «иначе не сделаешь», а в реальности надо было только немного подумать. Простите если кого-то сейчас обидел. Я всего лишь молодой и глупый питонист.
lumag
26.04.2016 21:00+5В итоге какая глубина вложенности будет? И какой сдвиг форматирования вправо?
DrSavinkov
26.04.2016 22:25+1vector<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]); } }
DrSavinkov
26.04.2016 23:33Только сейчас заметил, что там с NULL по "!=" сравнивать надо было. Опечатался.
MichaelBorisov
27.04.2016 00:33+3А что, если требуется захватывать разнородные ресурсы?
DrSavinkov
27.04.2016 10:50В enum перечислите типы ресурсов, по if или case применяйте открытие и закрытие, в массив вместо file* сделайте void*
MichaelBorisov
27.04.2016 20:55Разнородные ресурсы — это значит, что они захватываются, в общем случае, разными функциями, имеющими разный интерфейс. Вызывать их в цикле по массиву указателей невозможно из-за различий в интерфейсе.
Можно и эту проблему решить, конечно. Создать, к примеру, функции-адаптеры. Для большого числа ресурсов это, наверно, хорошее решение. Но для среднего числа (3-10) — это стрельба из пушки по воробьям. Логика одной функции оказывается размазана на несколько функций, появляются циклы и дополнительные переменные. Для восприятия программы все это, на мой взгляд, тяжелее, чем конструкция с goto.DrSavinkov
27.04.2016 21:08Подытоживая, для малого числа аргументов имеет смысл расписать каждый вручную, для большого — построить комбайн с унифицированным доступом к разным типам ресурсов.
Ambroyz
27.04.2016 01:26+1Такие конструкции прекрасно реализуются через
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);
}
Причем блок отката обычно выносится в отдельную функцию, которая позже вызывается как деструктор (например, если действия с файлами происходят не только в контексте вызова функции).MichaelBorisov
27.04.2016 01:52+4Операторы return, break и continue — это по сути замаскированные goto, они нарушают структурность программы (по Дейкстре). Так что, если у вас в свое время воспитали устойчивое отвращение к goto — то забыли это сделать в отношении остальных вышеупомянутых команд.
Ну и приведенная вами программа имеет следующие недостатки: цикл-который-не-цикл, лишние проверки («if(f1) fclose(f1);»). Не всякий ресурс допускает такую простую проверку на предмет существования. Для тех ресурсов, которые нельзя так проверить, придется заводить отдельные логические переменные.
В общем, goto в данном случае красивее и эффективнее. И приведенный мной паттерн — это не мое изобретение (хотя я его в свое время независимо изобрел), а классический пример-исключение, показывающий, что есть случаи, где применение goto оправдано.Ambroyz
27.04.2016 02:15+1При обучении озвучивался аргумент, что функции с goto выпадают из поля зрения оптимизатора. Потому и привился такой стиль программирования. Насколько я знаю, современные компиляторы не имеют такого недостатка. Кстати, приведенный мной пример не моя идея, это распространенный паттерн инициализации в драйверах Windows (функции создания объектов, StartDevice и прочие). Более адекватно код выглядит, если учесть, что описатели нужно закрывать не только здесь на откате при проблемах, но и при очистке объекта.
А в целом вы правы, это попытка не использовать goto там где он подходит лучше.MichaelBorisov
27.04.2016 21:13Спасибо, понятно.
Более адекватно код выглядит, если учесть, что описатели нужно закрывать не только здесь на откате при проблемах, но и при очистке объекта.
По-моему это неоптимальное решение. Если мы снова взглянем на RAII в C++ — то он выглядит примерно так:
class ResourceSet { private: Resource a; Resource b; Resource c; public: ResourceSet(): a(), b(), c() {} }
При создании объекта типа ResourceSet его конструктор поочередно захватывает ресурсы a, b и c. Если какой-либо из этих ресурсов недоступен — то соответствующий конструктор бросает исключение, и тогда создание объекта ResourceSet прерывается преждевременно. Исключение летит дальше вверх. А поскольку объект ResourceSet не был создан до конца (он считается созданным до конца после того, как будут созданы все объекты-члены и завершено исполнение тела конструктора) — то его деструктор не вызывается. Вызываются только деструкторы тех членов, которые уже были созданы на момент генерации исключения.
Соответственно, при уничтожении объекта ResourceSet() деструкторы членов вызываются безусловно, так как гарантированно известно, что все члены класса были успешно созданы.
Чтобы реализовать это на C, нужно иметь функцию, реализующую конструктор. Эта функция будет завершаться либо успешно — и тогда известно, что все ресурсы, которые она должна была захватить, захвачены; либо неуспешно — и тогда известно, что никаких ресурсов не захвачено, и вызывать «деструктор» не нужно. В таком случае в функции, реализующей концепцию деструктора, можно не проверять каждый ресурс, был ли он на самом деле захвачен.
5oclock
27.04.2016 02:40Эти операторы работают чётко в рамках конструкций: циклов, switch'ей и функций, и имеют вполне предсказуемые последствия.
В каком же состоянии окажутся ресурсы программы в результате goto — предсказать трудно.
GebekovAS
27.04.2016 16:01Если я не ошибаюсь, существование тьюринг-полного P" языка (в котором отсутствует goto оператор), уже говорит о том, что всегда можно обойтись без goto.
tyomitch
27.04.2016 16:18+1В самой машине Тьюринга нет ни goto, ни каких других операторов. Значит, без любых операторов можно обойтись. И что?
GebekovAS
29.04.2016 18:20-1Вы точно читали комментарий, на который я отвечал?
Цитирую:
Могу осторожно согласиться, что я просто не встречался с задачами, где без goto никак.
А теперь вам вопрос, при чем тут другие операторы?
alexover
26.04.2016 23:00Это смотря как использовать. Некогда, учась классе в 6-8, я не знал о существовании процедур и функций(правда это был паскаль, а не СИ) и вот тогда я с помощью goto выстраивал некие блоки, которые по сути своей были функциями. Да, дикий говнокод, но я умудрялся с таким подходом занимать призовые места :)
impetus
26.04.2016 19:57+7Это полный аналог русского мата — в каких-то коллективах это категорически не привествуется — настолько, что могут сразу попросить на выход, где-то наоборот — им не ругаются, а на нём разговаривают…
Т.о. goto, точнее его положение в языке поднимает Си на уровень именно что Настоящего Языка, который как известно делает население — народом.
<пыыхххх....>MichaelBorisov
26.04.2016 20:07Кстати о мате — если суд не только признает C иностранным языком, но еще и признает оператор goto нецензурным матерным словом на этом языке — то авторам рекламы будет совсем печально.
MaxAlekseev
26.04.2016 20:44+1Судя по минусам, пока лидируют сторонники
матаgoto.gxcreator
26.04.2016 21:16+6Это сотрудники Интела минусуют, они ярые фанаты goto, даже в процессор её встроили!
AbramovKS
26.04.2016 18:54+31Если суд увидит это, то точно признает иностранным языком).
EndUser
26.04.2016 18:56+3Налицо дискриминация людей по языковому признаку!
http://s670.photobucket.com/user/DeathLoveCrymo/media/see-computers-are-racist.jpg.html
magamos
26.04.2016 19:48+9Должна быть Wikipedia на С, Google Translate тоже с C, а также республика C вдобавок.
И чтобы Google Translate мог переводить C на Java / C++ / PHP / JS и прочие диалекты малых народностей.ySky
26.04.2016 23:01+4И переиздать Конституцию, все кодексы и федеральные законы. Так даже лучше — баги будет искать легче.
DrSavinkov
26.04.2016 23:27Я так понимаю, переизданные документы должны корректно компилироваться при отсутствии ошибок?
BelBES
26.04.2016 23:41Вот только не факт, что все юнит-тесты будут зелеными)
DrSavinkov
26.04.2016 23:48После этого мы наконец-то выясним, что любое действие, включая бездействие, по нашему законодательству является правонарушением)
BelBES
26.04.2016 23:40Да как бы в этих документов не появилось еще больше способов выстрелить себе в ногу...
hitmen047
26.04.2016 20:00+2Скоро стране потребуются переводчики с Си на русский!
MichaelBorisov
26.04.2016 20:13+1С переводом Си на русский неплохо справится и автомат. Ведь Си — формальный язык. Вот с обратным переводом — уже сложнее. Пока что в основном это прерогатива человека. Но такие переводчики уже есть. Называются в простонародье «программистами».
miriarder
26.04.2016 20:23+1Рискну высказать даже более сильное утверждение. С С, как, впрочем, и с любого другого формального языка, возможен абсолютно точный и 100% автоматический перевод на любой другой формальный или неформальный язык обладающий соответствующим свойством полноты. Достаточно лишь правила вывода задать.
MichaelBorisov
26.04.2016 20:18+2Сегодня, 26 апреля 2016 г., арбитражный суд Орловской области должен был решить вопрос, является ли язык программирования C иностранным языком.
Эхо Чернобыля?
golf2109
26.04.2016 20:24+1если язык иноСТРАННЫЙ, — то где та страна в которой на нем разговаривают?
ksr123
27.04.2016 04:25+2А где связь, простите? Языков как минимум на порядок больше, чем стран.
c4simba
27.04.2016 09:53В одной стране может быть языков больше чем один, так же как и наоборот — один язык больше чем в одной стране.
DrSavinkov
27.04.2016 18:36-1Тогда надо найти страну, в которой С признан государственным языком наравне с, к примеру, Суахили.
herr_kaizer
26.04.2016 20:32+4В первую очередь это именно английский. Тот факт, что фраза «разбавлена» Сишным синтаксисом, никак не влияет на семантику. Если я напишу какое-нибудь оскорбление, а потом между словами вместо пробелов буду ставить различные символы, это не перестанет быть оскорблением.
novice2001
27.04.2016 01:00+1Правда?
А если я сконструирую некий искусственный язык, в котором обыденные слова или некоторые внешне бессмысленные наборы символов будут иметь оскорбительное значение, а потом опубликую рекламное объявление на таком языке?
В какой момент объявление станет запрещенным? Сразу — или после того, как я опубликую словарь такого языка?herr_kaizer
27.04.2016 08:34Скорее всего, с момента опубликования словаря. Но это надо у лингвистов и юристов интересоваться.
beliakov
26.04.2016 21:46+25EndUser
26.04.2016 22:49+2Мда, на вполне внятном языке доходчиво читается. Хотя немного многословно.
Только момент не понял: через двое суток после собеседования сценарий падает?
petuhov_k
27.04.2016 12:30+1Ошибка в строке
Assert.IsTrue((DateTime.Now - visitTime) < new DateTime(0,0,0,2,0,0));
вычитание DateTime-ов даёт TimeSpan, который не сравнивается с DateTime.beliakov
27.04.2016 15:06+1Да, вот тут уже обсуждали — https://habrahabr.ru/company/devexpress/blog/126915/#comment_4195149
Скорее всего специально добавили чтобы проверить кандидатов на внимательность :)
LeoPlus
26.04.2016 22:04+4need job, have skill, go to — это, конечно, ни разу не иностранный язык? :-)
Английскую фразу обернули в Си-подобную конструкцию, теперь троллят несчастных провинциальных судей :-)magamos
26.04.2016 22:15+1Безграмотность и неквалифицированность не дает права развязывать руки и всячески ограничивать граждан в своих свободах. Суд в РФ уже давно не мерило справедливости и непредвзятости, а просто инструмент подавления со стороны государства и его чиновников.
LeoPlus
26.04.2016 23:35+2И кого тут подавили? Кого свободы лишили?
Реклама на иностранном языке, с чем спорим? :-)DrSavinkov
26.04.2016 23:39Я вот понять не могу: где вы рекламу углядели? Я вижу на картинке объявление для ищущих работу.
Baryonyx
27.04.2016 00:06+3Объявления о поиске сотрудников подпадают под Федеральный закон «О рекламе» в обязательном порядке, в котором, в т.ч., прямо оговорены условия, которые необходимо соблюдать в подобных случаях.
Areso
27.04.2016 08:25+1Неправда ваша.
Из ФЗ: «объект рекламирования — товар, средства индивидуализации юридического лица и (или) товара, изготовитель или продавец товара, результаты интеллектуальной деятельности либо мероприятие (в том числе спортивное соревнование, концерт, конкурс, фестиваль, основанные на риске игры, пари), на привлечение внимания к которым направлена реклама».
Таким образом, закон не содержит отсылки к вакансиям. Практика, как правило, такие объявления рекламой не считает, но есть ряд оговорок, к примеру, продукты/услуги компании упоминать в вакансии не стоит. Или если идет объявление о вакансии от трудового агенства — тогда это реклама.
magamos
27.04.2016 09:36-1Иностранный язык — язык иной страны. Язык C — язык какой страны? Если судьи настолько бестолковы, что не могут распознать, что такое «иностранный язык», то им место полы мыть, а не кресло судьи занимать.
В русском языке могут использоваться слова из других языков, но от этого фраза на русском языке не перестает оставаться таковой. Аналогично, выражение на языке C может использовать идентификаторы из любого языка с латинским алфавитом, но от этого оно все равно не перестанет оставаться на языке CCrash512
27.04.2016 14:42+3Дружище! В одной только России 37 официальных языков (слыхали про республики?), из которых 15 — официально признаны государственными. О каких странах речь идёт? Слыхали про Северный Кавказ? Там больше десятка языков, относящихся к стране России.
ProRunner
26.04.2016 22:08+8Никакого более важного занятия ФАС Орловской области не нашла?
Mixim333
27.04.2016 19:44Ну им же нужно как-то оправдывать получаемые из бюджета деньги и выдаваемую каждый месяц зарплату
DrSavinkov
27.04.2016 20:37А я, наивный, думал, что органы безопасности и прочие ЗП должны получать за отсутствие проблем на участке, а не за выполнение нормы по заведённым делам.
malan
27.04.2016 21:58Деда Мороза, тоже не существует, только тссс…
А вообще, палочная система не отечественное изобретение, и пользуются ей везде. Причём она всем не нравится, но заменить её нечем:)
april26
26.04.2016 23:03+2Человек далёкий от программирования будет уверен в том, что это иностранный язык. Мало ли какие скобки и знаки пунктуации там применяются. При мало-мальском знании английского смысл становится ясен. Так что для обычного человека это будет именно иностранный язык. Иначе внизу была бы ремарка:«Читать и понимать только программистам и тем, кто в теме».
antkatcin
26.04.2016 23:03Все-таки тут в названии переменных явно видно, что использован английский язык. Даже не смотря на то, что это общепринятая практика, в суде могу придраться к этому. Тогда русская модификация должна выглядеть как-то так:
if (nuzhna_rabota && est_umenie) {
kissarat
26.04.2016 23:04+1А также быть признан экстремистской организацией
Areso
27.04.2016 08:17+1Иностранным агентом, если быть точным. Все эти ваши C99, C11 явно пишутся под иностранную дудку. Мало ли чего там понапишут! Да еще и не на русском. Запретить, как бы чего не вышло. Просто запретить. Запретить!
kissarat
27.04.2016 10:39ГОСТ-ты не помогут?) Или для создания новых ГОСТ-тов нужно иметь большое влияния?
Возможно не в тему
nafikovr
26.04.2016 23:04При чем тут вообще язык программирования? Он здесь не более чем для стилизации.
teemour
26.04.2016 23:04ну если я китайский выучу то я же не стану китайцем
хотя…
если твойдед писал на С, отец писал на С и ты пишешь на С, то что-то в этом есть
PupkinVasia
26.04.2016 23:09+10Мне уже просто интересно, все чиновники реально так тупы как выглядят или прикидываются? Один не знает чем отличается свекла, другой никогда не видел сишного синтаксиса. Пиздец какой-то, а мы ведемся. И интересно то, что ВСЕ меры, депутаты и прочие выходцы нецифрового века, все они — пережиток СССР. Ни одного молодого и образованного человека. Видать потому что разумные люди не так рвутся к этой дурацкой официальной власти и взаимному подрачиванию законопроектов друг друга. Особенно когда вокруг столько простора для самых разнообразных действий.
Печалька. Вот бы всех расстрелять и заменить программой. Главное Сивиллой не называть и может все получится.withkittens
26.04.2016 23:41+3другой никогда не видел сишного синтаксиса.
А вы считаете, каждый чиновник должен уметь C?PupkinVasia
26.04.2016 23:48+1Я считаю что нельзя останавливаться в собственном развитии только потому что нашел кормушку и нажрал пузо. Хотя это дело личное.
Ну а в 2016 году не то что не знать, а и просто не видеть ни разу синтаксиса языков программирования это уже даже не смешно. Зато, могу поспорить, 9 из 10 чинуш заходят во вконтактики и вообще хоть чуть-чуть пользуются компьютерами.
Раньше считалось что учить детей в школах делать киянки и ложки это достаточно. Тогда не было компьютеров. Но вот в 2016 почему-то даже учителя информатики в школах не знают как работает компьютер и учат как ходить на яндекс.
Короче говоря, с прогрессом в этих странах сейчас совсем чуть-чуть малость адовая жопа. От начала (обучение детей) и до конца (любой начальник любой государственной конторы).withkittens
27.04.2016 18:08+1Ну а в 2016 году не то что не знать, а и просто не видеть ни разу синтаксиса языков программирования это уже даже не смешно.
Ну почему бы тогда не требовать с поваров знания ядерной физики? Принцип тот же. Как ниже подсказали, для подобных случаев существуют эксперты и экспертизы.
P. S. Компьютерная грамотность != знание синтаксиса каких-то там языков программирования.Renius
28.04.2016 12:51Потому что вы предлагаете знание, это крайность как и незнание. Но спросите у повара что такое ядерная физика, с очень высокой вероятностью он вам ответит что-нибудь про раздел физики такой, нужен для бомб и электричества. Это не крайность, это не знание и не незнание.
Никто не требует грамотности или знания синтаксиса. Это было бы крайностью.
В общем риторика от крайностей считается грязной и к использованию не рекомендуется вот уже почти 2000 лет.
Arkebuz
27.04.2016 00:33+1для этого по идее есть эксперты
MichaelBorisov
27.04.2016 00:58+1Ну да, в таком судебном деле напрашивается комиссионная экспертиза с участием экспертов-лингвистов и программистов.
MichaelBorisov
27.04.2016 00:58+2Ни одного молодого и образованного человека
Жизненного опыта мало. Чтобы руководить сложной системой, нужен опыт, который приобретается с годами. Иногда молодые (до 30) люди попадают во власть; если поискать, можно найти такие случаи. Но много ли вы знаете таких случаев, чтобы такой молодой властитель мудро руководил тем, что ему дали в управление?
все они — пережиток СССР
Вам не нравится СССР? Но ничего другого не было на территории современной РФ до 1992г. Все, кто родился на территории современной РФ до этой даты, не могут быть ничем иным, как «пережитком СССР». Вы предлагаете всех расстрелять:
Вот бы всех расстрелять
Но не за это ли ругают СССР, что, дескать, репрессии? Сами того не замечая, вы предлагаете совершать то, в чем обвиняете «совков».
Видать потому что разумные люди не так рвутся к этой дурацкой официальной власти
Погодите немного. Произойдет очередная смена поколений, и среди ваших сверстников начнется грызня не на жизнь, а на смерть, за участие в «дурацкой официальной власти».vconst
27.04.2016 16:36+1«Иногда молодые (до 30) люди попадают во власть; если поискать, можно найти такие случаи.»
____
Далеко ходить не надо:
Никифоров Николай Анатольевич, Министр связи и массовых коммуникаций Российской Федерации, родился: 24 июня 1982 (сейчас 33 года), 21 мая 2012 года указом Президента России Н. А. Никифоров был назначен министром — то есть 30 ему еще не было, а уже министр.
И да, руководитель из него еще тот…
olegkrasnov
27.04.2016 00:47+1Это они ещё AppleScript не видели:
tell application "Finder" to get POSIX path of (target of front Finder window as text)
White__Owl
27.04.2016 01:01+2Вообще-то знание иностранного языка не делает человека представителем другого этноса. Полиглотам в обратном случае будет вообще весело жить.
sokoloff-rv
27.04.2016 14:57Дело не только в знании другого языка. Суть в том, что у носителей этого языка нет своей территории и государства. И потому они могут требовать право на самоопределение.
MiXaiL27
27.04.2016 04:53+1И почему ни кто не обратил внимания, что сама по себе конструкция, по меньшей мере, не полная. Допустим мне нужна работа и есть навыки, однако навыки у меня из другой ветки и работа, скорей всего, нужна не та, что может подразумеваться.
В общем я хотел бы видеть объявление, которое покрывает все случаи без ложных срататываний. Собственно потому goto и является лишним и неправильным, вот для этого и нужна правильная конструкция с условиями. Ну или хотя бы правильно объявить переменные, раз уж так им хочется goto использовать.EndUser
27.04.2016 06:04+11) не ходите на это собеседование
2) если пойдёте, собеседование уточнит одинаковое ли у вас понимание
Dioxin
27.04.2016 08:30Немного потроллю ФАС:
Если вам кажется что вы понимаете смысл этой фразы то вам это просто кажется.DrSavinkov
27.04.2016 18:51Немножко потроллю Вас:
Если вам кажется, что вы не деаниномизированы, то вам это просто кажется.
ndka
27.04.2016 14:58+1Это же очень хорошо! :)
«Гражданский процессуальный кодекс Российской Федерации» от 14.11.2002 N 138-ФЗ (ред. от 30.12.2015) (с изм. и доп., вступ. в силу с 01.01.2016)
Статья 9. Язык гражданского судопроизводства
2. Лицам, участвующим в деле и не владеющим языком, на котором ведется гражданское судопроизводство, разъясняется и обеспечивается право давать объяснения, заключения, выступать, заявлять ходатайства, подавать жалобы на родном языке или на любом свободно избранном языке общения, а также пользоваться услугами переводчика.
iv_k
27.04.2016 14:58+1ПлАчу из-под стола. Какая прелесть. Пора уже гимн, герб и флаг нового государства придумывать. =)
master_of_mastery
27.04.2016 14:58+1Чтобы определить на каком языке написано это объявление, на английском или на C, можно провести простой мысленный эксперимент:
есть два человека: один знает английский, но не знает С и других языков программирования; другой знает С, но даже поверхностно не знаком с английским, вот вообще ни одного слова не знает. Кто из них поймет значение этого объявления?Namynnuz
27.04.2016 15:21Каким образом человек может знать си, но не знать английского? Тем более ни одного слова, если там все операторы представляют собой чистейший английский. Со стандартами именования переменных и прочего. И практически все конструкции написанные логичным англофоном можно прочитать как слегка кастрированный, но всё равно английский? Что-то выше anykey в современном мире для программиста начинается с английского, потому что там содержится основная прорва информации, в том числе новой, пока ещё актуальной. Именно там можно найти пути карьерного роста и более высокая вероятность встретить людей-гуру, при чём без разницы, на какой ступени развития сейчас находится соискатель.
master_of_mastery
27.04.2016 15:45+3Каким образом человек может знать си, но не знать английского?
Жил в пещере, и была у него одна книжка «С для чайников» на русском.
Я самолично (на курсах английского) видел несколько программистов, которые пользовались англоязычными терминами, названиями операторов, даже не задумываясь о «нормальном» значении слов, они их запоминали как имена.
Но это все не важно. Это мысленный эксперимент, в этом его суть.tyomitch
27.04.2016 16:28+2Подтверждаю. Я выучил бейсик раньше, чем начал учить английский; и с большим интересом обнаруживал, что у всех этих заклинаний, оказывается, есть и «непрограммистский» смысл.
Namynnuz
27.04.2016 16:59То есть «знать си» равнозначно прочтению одной книжки «С для чайников» на русском языке. Нафиг хотя бы лет семь работы над крупным проектом в тиме, нафиг общение с себе подобными, никакие новые веяния, версии и стандарты не нужны; покупайте наших слонов…
tyomitch
28.04.2016 02:47Предположим, он прочёл более 9000 книжек про си, все на русском языке, и работал над крупным проектом в русскоязычном коллективе. Если остальные участники проекта и знали английский сами, нет никакой причины, чтобы они стали насильно учить английскому своего коллегу.
XAHOK
27.04.2016 23:01Я самолично (на курсах английского) видел несколько программистов, которые пользовались англоязычными терминами, названиями операторов, даже не задумываясь о «нормальном» значении слов, они их запоминали как имена.
Оно запоминается не именами, а как раз «образом» из ЯП. Как то развлекался анализом своих фраз по работе: англицизмов невероятно много и все они служат для подчеркивания рабочих моментов. В итоге получается, что Дата и Данные — это разные слова с точки зрения смысловой нагрузки, а в английском оно вообще может иметь смысл только применительно к конкретному случаю. Практикуюсь в английском и приходится вычищать свою речь от Delete вместо Remove, Data вместо Information и т.п. Друг дико ржет над тем, как я порой фразы строю, а оно уже в подкорку забито.
Namynnuz
27.04.2016 15:15-1Есть предположение, что корректнее этот текст должен было выглядеть примерно так:
if ( you( need_job && have_skills ) ) { goto Stork; }
Не говоря уже о том, что этот код валиден на целом семействе языков с похожим синтаксисом (goto не выпиливается почти нигде, оператор ветвления, переменные, условный оператор AND и блоки кода — стандарт для высокоуровневых языков). А необходимость понимать это без перевода напрямую содержится в переменной have_skills...
magamos
27.04.2016 16:06нет, в C #define-константы принято писать полностью заглавными:
if ( you( NEED_JOB && HAVE_SKILLS ) ) {
goto Stork;
}Namynnuz
27.04.2016 16:55То, что код не соответствует некоторым стандартам, не означает, что он невалиден. Этот код прекрасно скомпилируется, при чём много где, для большого парка компиляторов и зоопарка языков, под разные системы. Не говоря уже о том, что need_job, как и have_skills, попросту не могут быть константами.
egormerkushev
27.04.2016 19:08Русскими символами можно пользоваться при программировании на Свифт, да что там: смайликами можно программировать!
Что они тогда скажут про рожицы и какашки? Что это язык?
magamos
27.04.2016 20:23Надо защиту в суде проводить на языке С. Как и писать прочие официальные бумаги.
Ритчи, Томпсон и Керниган — наши пророки. Страуструп — вероотступник, лживый мессия. Bell Labs — наша Мекка. И сейчас — 44-й год от основания мира. )
datacompboy
27.04.2016 23:20Ну, чем закончилось-то?
Jahkuba
28.04.2016 13:22+3Да глупость очередная.
Русский язык — это естественный язык, а Си — язык формальный, но нифига не иностранный. Если ФАС не понимает разницы между этими двумя понятиями, то это их проблема, а проблема суда – разобраться, для этого достаточно пригласить нормального лингвиста который разжуёт судье разницу между этими двумя понятиями.
Я думаю, что смогу сейчас найти штук 5 реклам с математическими формулами/кванторами, к которым ФАС не имеет никаких претензий по поводу необходимости перевода формул с математического языка на русский.Ilirium
29.04.2016 07:07Во, кажется хоть один комментарий по теме топика. Думаю они скажут, что язык программирования C использует слова из английского языка, а значит является подмножеством английского языка. А как же наличие особой формальной логики? Выше приводили большое количество примеров перевода на русский операторов и выражений языка, а также использование языка 1C, т.е. наличие такой логики не является неотделимой прерогативой C. Значит, компания нарушила закон о рекламе.
Интересно, а какие аргументы можно привести в защиту компании? Что-то я ни одного не могу придумать.5oclock
29.04.2016 07:54«Реклама — информация, распространенная любым способом, в любой форме и с использованием любых средств, адресованная неопределенному кругу лиц и направленная на привлечение внимания к объекту рекламирования, формирование или поддержание интереса к нему и его продвижение на рынке;»
(Из закона о рекламе)
В данном случае это информация адресованная определённому кругу лиц: программистам.
Arvalon
29.04.2016 00:38Написали бы не goto Stork(); а функцию какую-нибудь с передачей туда себя Stork(me);
MrYuran
29.04.2016 14:45try {
interview(&Stork);
}MrYuran
29.04.2016 14:55Кстати, написал ещё раз Stork и подумалось — а этот чудной процесс точно не часть рекламной кампании?
art_of_press
29.04.2016 15:33comargo
29.04.2016 16:53Спасибо.
А вот это мне понравилось:
Специалист Ершов М.Н. суду пояснил размещенное на рекламном щите изображение
не является текстом на каком-либо иностранном языке, а копирует часть авторского
программного продукта, написанного на языке программирования «С++».
Это был всего лишь кусок кода на C++ из некой программы (по мнению специалиста Ершова)
Я бы еще добавил, что это вообще картина неизвестного художника.
malan
AlexSam
Сишникам — НСР
(Народная Сишная Республика)
Nagg
Жители — наСильники.
vadimzz
Сионисты же
Ra-Jah
Мы так и до СС дошутимся.
svitoglad
Или до СС++.
Lisio
Главное за C# не загреметь
sguwenka
уже давно. не про программистов, но всё же: у нас в новостройке есть СС ИГ — совет собственников инициативная группа :)
vmchaz
Уже.
ramwoolf
В Новосибирске есть ИГиЛ СО РАН, с отделом взрывных процессов 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
eugenius_nsk
Ссылкой удобнее — https://ru.wikipedia.org/wiki/Институт_гидродинамики_имени_М._А._Лаврентьева_СО_РАН
ALHIMIK1992
Сишники
metalim
И сисишники
toshkageradot
Может, тогда Сишная Народная Республика? СНР даже удобнее произносить. Ну и фаны Marvell поймут :)
stsdc
People's Republic of C
Autonomous Republic of C++
v50110
Линуса — в президенты!
Столмана — в прокуроры!
Балмера — в жириновские!
Kenya-West
Наделлу в главу правительства!