Начало программирования в Виндовс 11

ЮСТАС - АЛЕКСУ

Итак, продолжим. Рад видеть вас всех здесь снова. Поскольку, Google перестал возвращать ссылку на этот сайт по соответствующим тематическим запросам, значит, предыдущая статья попала в точку и (в стиле GNU) свободный, действительно, значит безоплатный, огромный размер Go-программы не делает её лучшей и видимо, действительно, является единственным её достоинством, а вся современная свобода суть ещё одно проявление рабства тех рабов и никакое платное или бесплатное GNU-пиво от Р. Столмана тут не поможет.

Но ближе к телу :). Все вы, конечно, на собственном опыте уже знаете о том, что Google запрещает пересылать архивы, программы и объектные файлы напрямую адресату, как вложения к письмам. Раньше, бывало испросишь у владельца файлик, а он его и пришлёт с письмецом. Теперь же этот файлик владельцу надо закинуть на диск и поделиться ссылкой - многие не захотят. Делать лишние телодвижения? - зачем? Кроме того, файлы на почтовом диске Google это вещьдок-компромат-след-улика, который в любой момент перлюстрируется и не исчезает с удалением письма или автоматически. Парни из Google, вааще, странные и никогда не понимали, что многих не прёт от того, что к ним в задницу заглядывают хоть с эндоскопом, хоть фонендоскопом :).

Не знаю, слышали ли вы о легендарной немецкой машинке для шифрования Энигма. Поинтересуйтесь. Предлагаю накрапать нечто подобное программно. Для чего? - ну, чтобы нейтрализовать эту очаровательную инициативу Google, хотя бы. Во-первых, это достаточно просто и познавательно. Во-вторых - очень интересно и увлекательно. В третьих - утилитарно, а значит полезно. А заодно, попробуем слегка доработать немецкий гений, расширить сферу его применения и прикрутить к сегодняшнему дню. Ибо, будущее не за горами и фекально оно, весьма.

Что мы знаем об Энигме, кроме того, что она такая-растакая, огого какая и якобы легко тасует квинтиллионы квинтиллионов вариантов? А практически всё: три-четыре хитро распаянных колёсика, деревянная коробочка с лампочками и кнопочками и куча ограничений поверх всей этой мишуры.

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

Если колёсики можно переставлять друг относительно друга, то количество всех возможных стартовых позиций увеличивается до 105456. Хотя, для единичного сообщения останутся всё те же 17576, хоть и шесть раз подряд. Современный комп переклацает их все за пять минут. Но если сообщение прокатать через три колёсика коммерческой Энигмы дважды, то это будут уже не хилые, по тем временам, 308915776. А если порядок установки колёсиков можно таки менять, то разнообразие увеличивается до 11120967936 стартовых позиций, при двойной прогонке даже на коммерческой(не военной) Энигме .

Разумеется, "тупые" немцы сами до такого в годы войны додуматься не смогли - в смысле, пропустить одно сообщение через Энигму два-три раза подряд. По крайней мере не в случае с проектом Блетчли-парк. Хотя, ко мне эта идея, почему-то, пришла на пятой минуте просмотра фильма. Бывает. Я прямо вижу эту трогательную картинку. Приходят к Гитлеру его помощники и говорят -Мой фюрер, а давайте прогонять каждое сообщение через Энигму трижды. -И сколько же это будет стартовых позиций? -О, мой фюрер, много - лучше Вам и не знать. -Вы, что? С ума сошли! Но как же тогда Тьюринг и Велшман из Блетчли-парк нас раскусят?!

Не.. Ну.. Если предположить, что четыре официально главных товарисча Р.Ч.Г.С. были командой и дружно забивали голы в одни ворота, а Энигма существовала только для того, чтобы полковник Мося Исаев-Пупкин на радиоузле под Ростовом, случайно перехватив радиограмму, не смог ничего понять и проявив идиотскую и никому, в данном случае, ненужную бдительность, не морочил голову начальству, тогда - да. Тогда - конечно. Тогда, кино про Блетчли-парк в самый раз. Самое то. :))

Кстати, на сколько я понимаю, радиосвязь в те времена(1935-1945) напоминала сегодняшнюю сотовую. Не было ни прохождений, ни замираний, ни затуханий сигнала. Стукануть шифровку из Берлина на подлодку в Атлантике телетайпом в то время было так же просто, как сейчас к тёлке на соседнюю улицу позвонить. А ещё, у немецких подлодок, которые не ржавели и не ломались, никогда не заканчивались топливо, провиант и боеприпасы :). Короче, ты понял.

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

А, как многие уже догадались, с помощью этих 16-ти удивительных значков можно закодировать практически всё, что угодно а этом мире. Между тем, как для хранения всего этого чарующего волшебства достаточно одного полубайта. После некоторых манипуляций, разумеется. Как удачно :). И кроме того, используя "0123456789ABCDEF" можно превратить в текстовый файл любой архив, программу, объектный файл, фильм и всё, что угодно. А против пересылки текстовых файлов, gmail не возражает. Пока не возражает :).

Те, кто в теме, называют такую несложную трансформацию простым словом ДАМП(помойка) :). При этом, вдвое возрастает размер исходника. Но зато, теперь, наша Энигма сможет кодировать всё. Надо только написать крошечный перекодировщик. Этим и займёмся. Однако, не стройте больших надежд на будущее. В любой момент Google может запретить и пересылку ДАМПов, тоже. Потому, что честный от подлеца отличается только тем, что честный - не всегда честный, а подлец - подлец всегда.

Сделаем прикидочный расчёт. Примем, что наша new-Энигма будет иметь 10 колёс. Тогда, если одно колесо будет крутить один полубайт(4 бита), количество размещений(вариантов "распаек") в таком колесе составит 20 922 789 888 000, а количество стартовых позиций - 17 592 186 044 416. Если одно колесо будет крутить целый байт(8 бит), количество размещений(вариантов "распаек") в таком колесе составит 857817775342842654119082271681232625157781520279485619859655650377269452553147589377440291360451408450375885342336584306157196834693696475322289288497426025679637332563368786442675207626794560187968867971521143307702077526646451464709187326100832876325702818980773671781454170250523018608495319068138257481070252817559459476987034665712738139286205234756808218860701203611083152093501947437109101726968262861606263662435022840944191408424615936000000000000000000000000000000000000000000000000000000000000000, а количество стартовых позиций - 1 208 925 819 614 629 174 706 176. Понятно, что второй вариант, с миллионом миллиардов миллиардов стартовых позиций, на много привлекательнее и интересней. Перестановка 10-ти колёс между собой даст ещё 3 628 800 вариантов миллиона миллиарда миллиардов стартовых позиций. Не плохо, как для старушки Энигмы. И всё это программно. Как говориться, без единого болта. И даже, на х386-м компе. До чего техника дошла!

1.2х10^24 стартовых позиций, а при двойном прогоне - 1.46х10^48 или даже 1.92х10^61, много это или мало? Кто его знает. При бесконечном изобилии распределённых вычислителей в виде майнеров криптовалюты всех мастей, высчитывающих на своих компах не известно что и не известно для кого, возможно, что и не много. Поэтому, кладём всё в архив, закрываем архив паролем, ксорим, пропускаем через доступный шифрующий алгоритм и только потом засовываем этот синтетический натур продукт на тройной прогон в new-Энигму. Кладём результат ещё раз в архив, ещё раз закрываем этот новый архив паролем, закидываем его на диск Google, спим спокойно :)). Я параноик? - а ты пофигист? Не надо было gmail архивы трогать :). Привет Алану Тьюрингу.

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

Приведенный листинг демонстрирует компактный стиль и структурирование цветом в оформлении исходника. В программе не предусмотрено никаких проверок корректности происходящего в расчёте на вашу вменяемость. Благодаря этому всё компактно и обозримо. А заодно и расширяемо. Использование предельно просто - Any2Hex.exe My.exe. На выходе - файл any_hex.txt, который можно произвольно переименовать. Компилируется в чём угодно. Хотя, особо продвинутые компиляторы потребуют заменить char *argv[] на char **argv[]. Ну и фиг на них :).

Размер Any2Hex.exe у меня - жалкие 2560 байт, что очень уж как-то по плебейски, не солидно и конечно же не идёт ни в какое сравнение с такими весомыми мегабайтами языка Go. Хотя, Go не так уж и велик. Впрочем, как и VB вместе с C#. Недавно я узнал об одном компиляторе жабаскрипт, так в нём, как утверждается, Привет Мир имеет размер 22 мегабайта и то впритык. Вот это - Да! Хорошему предела нет :), а командам Гугл и Майкрософт пора уже подтягиваться к этому уровню. И вааще, компиляция жабаскрипт в машинный код вдохновляет. Против чего боролись, на то и напоролись :(. От чего ушли, покружили, покривлялись, повоняли, к тому же и пришли. Но, как-то уж совсем по дурацки

Кстати, по состоянию на 28.05.2021, Гугла перестал возвращать ссылки на эти странички, at all :). Это говорит о том, что заинтересованные товарисчщи нас внимательно читают, прислушиваются и остро реагируют на всё. В меру их ума и развития, конечно. Напоминает историю книги iКона Джобс. Ребята-гугл, какие вы одинаковые :). Дам вам ещё один повод отправить меня в ещё более глубокий игнор.

На чем основана лицензия GNU? - вопреки ожиданиям, на ваших, малыши, жлобских побуждениях. Дескать, а чаво это кто-то будет наживаться на твоём безоплатном труде, кроме Столмана? Верно? Это основной посыл. И только потом, спасение мира, альтруизм и польза для человечества в виде систем автоматического штрафования, блокировки банковских карт с нихера и т.д. Так-то, вот :).

Ещё один интересный момент. В выше приведенном листинге применён феерический, универсальный, нигде и никем не описанный цикл "loop - goto loop" с выходом из него по if(). Никто из старых пердунов, преподающих и/или пописывающих ради заработка книжонки, о нём ничего не говорит. Между тем, как именно с этого цикла и следует обучение начинать. И только потом, на его базе, переходить к объяснению циклов while, do while и for с иллюстрациями, постепенно расширяя или трансформируя "loop - goto loop" в эти три утилитарных варианта, созданных для простого, банального удобства и не имеющих в самих себе никакого сакрального смысла и содержания.

Теперь напишем перекодировщик в обратно.

Истинные ценители интерфейса командной строки via Free BSD & Linux должны быть довольны и уже празднуют. Усе же остальные, принципиальные противники ископаемой эротики такого рода, берут в руки PureBasic и быстренько варганят простенький gui-интерфейс под эти две тулзы :).

Естественно, это только наброски. Процесс можно полностью автоматизировать с тем, чтобы не прибегать к ручной корректировке имён файлов. И даже сделать его пакетным :). Но мы ведь не в обществе "Противодействия Google" :) ? Верно? Хотя.. хотя.. хотя... :)

Пару слов о том, что всё есть текстовый файл. Идею, разбивать большой программный комплекс на маленькие, законченные, составные части, а не валить все функции в один исполняемый файл, приписывают создателям AT&T Unix. Но это ложь. Просто, в те времена подобный гипотетический жирняк просто не в куда было бы загружать, вот и изощрялись. Хотя, идея очень даже хорошая, в виду простоты модернизации полностью автономных составляющих. Представь всю Винду в виде одного единственного исполняемого файла. Под него никакой памяти бы не хватило. Пользуйся этим правилом и далее - дели задачу на законченные исполняемые блоки и вызывай их с параметрами по мере необходимости, как сделано это в большинстве компиляторов.

Ну, а теперь Энигма. Сразу скажу, что я никакой не специалист в области шифрования. И до фильма "Игра в имитацию" я о шифровании, вообще, ничего не знал. Равно, как и о программировании в Виндовс, пока PureBasic не скачал. Поэтому, я взял и кое-что о шифровании почитал. Окунулся в атмосферу и проблематику, так сказать. Поиск простых сомножителей меня вряд ли заинтересует. В виду полного отсутствия соответствующих извилин в моей голове. А вот 16 колёсиков по 256 сваленных в неряшливую кучку циферок, расставленных в произвольном порядке, вкупе с небольшим количеством операций косвенной адресации, для меня - самое то. Как и для большинства из вас.

Кроме того, широкая пропаганда PGP( Pretty Good Privacy) сразу же настораживает. Ибо, такой классный и бесплатный сыр, как известно, должен быть только в мышеловке. А то, что крысоловок(программных закладок) вы в нём не видите, ничего не отменяет. И не важно, кто и как вас взломает. Важно, сколько инструментов внедрено в PGP для точной идентификации вашей "анонимной" личности. Все эти инструменты не только не скрываются, а наоборот, преподносятся, как огромное достижение, преимущество и достоинство. Поэтому, случись что, так просто от силовиков вы уже не отвертитесь. Да и метод взлома пользователя при помощи тяжёлого гаечного ключа, тоже, никто пока ещё не отменял.

Все эти Энигмы, PGP, Tor, VPN, NO-IP, TAILS и прочие нае$ушки-анонимайзеры написаны не тобой и очень опасны для тебя, а не только для дураков. Задумайся на секунду , что стало с теми удачливыми продавцами и покупателями с Silk Road, которые, согласно легенде, подняли там миллионы. Наверное, они все купили небоскрёбы в Майами и живут там себе в них припеваючи. Не иначе. При этом, все эти торгаши и перекупщики, прежде, чем лечь в их могилы, пользовалисьTor. Не очень хорошо. Увы. Обычно, Большой брат не понимает почему ты вдруг так от него шифруешься.

Старые, добрые, почтовые голуби часто оказываются на много дешевле, надёжнее, практичнее, безотказнее, безопаснее и в конце-концов, вкуснее и универсальнее. По крайней мере, голуби вас, по их собственной инициативе, не предадут, в отличие от людей. Я тебя предупредил.

Массив 16х256 имеет 4096 ячеек. Заполнять их вручную, крутя самопальную рулетку, тасуя карты или кидая игральные кости - то ещё развлечение и довольно неприятная муть. Этого не захочется делать и один раз. Тем более, ручная расфасовка не позволит менять колёса(генерировать массивы) на лету. Воспользуемся генератором случайных чисел. Каким? Тем, что зашит в MSVCRT.dll. Он достаточно хорош, прост и доступен. Высчитывать количество размещений из 32768 по 256 мы не будем. Сразу в бой.

В бой-то оно в бой, но чёрная злая сила человеческой тупости, чванства и всепоглащающего задротства снова попыталась сломать стремительные крылья безудержного полёта моей пытливой и неукратимой мысли. Я уже неоднократно поднимал тему о том, что все компиляторы дерьмо и многократно подтверждал этот тезис исчерпывающими примерами. Вот ещё один.

Для автоматической генерации и хранения массивов-колёс new-Энигмы предполагается использовать файлы произвольного формата. Естественно, у файлов должны быть имена. Поскольку, априори, таких файлов предполагается в изобилии, следовательно, их имена должны генерироваться автоматически, например, так - WedJun230804262021. Для этого, была написана прото-функция, которая, помимо прочего, наглядно продемонстрировала возможность эквивалента оператора gosub и в языке Си.

Компиляторы Pelles C, Lcc Win32 и LLVM с задачей позорно не справились. Хотя, в программе нет ничего заумного. Таким образом и Pelles C, Lcc Win32, и LLVM немедленно вычёркиваются из Книги Живых и прямиком отправляются на помойку. А что делать? Компилятор, для меня, - он, как сапёр - ошибается только раз, а далее - прямиком нах$й. Вместе с аффтором. Вы, например, можете представить себе, что брат-Яша, брат-Пелле или патриоты из LLVM станут их "шедевры" переделывать? - я - нет. А зачема тюбе? Таким образом, по состоянию на сегодняшний день, их в живых осталось только двое - Tcc и MSVC.

Зато, с многопоточностью у Pelles C, Lcc Win32, и LLVM всё в порядке. :) И то, только лишь потому, что я её в них ещё не проверял. А зачема мине? :) Кстати, LLVM, в варианте поставки для Win, - классическая рыба прилипала, которой без MSVC, ну совсем никак. А до недавнего времени - особенно. Впрочем, как и компилятору INTEL.

Искусство управления компилятором, это, в первую очередь, точное знание того, как и когда он захочет ударить по рукам в следующий раз, а проще говоря - вые$ать. Не побоюсь повториться. Компилятор твой - враг твой!

Если б не емли мозги римляне и греки, курсовые б я писал только о минете. Возраст LCC win 32 и Pelles C перевалил уже за 25. Уже. Написан каждый из них, как бы одним, но в каждом случае иным человеком. Теоретически. Не считая, изначально лежащей в основе каждого из компиляторов, копипасты в виде LCC. И если то, что было содрано(творчески переработано) 25 лет назад, кое-как работает до сих пор, то самоличная надстройка над всем этим, в виде инлайн ассемблера для пущего выпендрёжа, явно не задалась. И если слон своим суровым и проворным хоботом пользуется, как угодно и во всю, то висячкой в виде инлайн ассемблера в LCC win 32 и Pelles C пользоваться совершенно не возможно. Никак.

LLVM, вааще, отдельная песня. Вы все, конечно, слышали о том какой LLVM офигенный. Офигенный дефект. Или, даже, офигенная дефекация. По крайней мере в Виндовс. При всём его офигенном размере, LLVM всего лишь жалкая, сиротская надстройка над MSVC. Программы, слинкованные lld v.3.7 не запускаются под XP. Нужен link. Сам по себе, LLVM - копипаста GCC от начала и до конца, хоть и переписанная сегодня, как говорят, своими словами. Инлайн ассемблер не работает от слова "вааще" и с первой строчки кода. Кому нужна такая поделка? - ну разумеется, Apple и Free BSD :). Мне? - нет :). И пусть всё так и остаётся. Кстати, в плане тупости, инлайн ассемблер LLVM от GCC совершенно не отличается. Старая история про яблочко и яблоньку.

И исчо :). Попался мне тут IBM_C_and_CPP_Compilers_for_WinNT-v3.6.5 за 1996-й год. Туфта. Не возбуждает. Ничего не знает даже о crtdll.dll. Инлайн ассемблера нет. С MSVC и рядом не лежал. Суди сам. Как тебе такие вещи в объектном файле: ?main, ?fopen, ?_printfansi, ?fclose, ?remove, ?fgetc, ?fputc, ?rename - сторонний линкер и библиотеки сразу в пролёте. Или

; 12 char stckprb[]={"\x09subl %eax,%esp\x0d\n"}; mov ecx,012h mov edx,offset FLAT:@CBE1 lea eax,[ebp-012h]; stckprb sub esp,0ch call dword ptr __pfmemcpy add esp,0ch; 13 char STR_NL[]={" ;#############################\x0d\n"}; mov ecx,022h mov edx,offset FLAT:@CBE2 lea eax,[ebp-034h]; STR_NL sub esp,0ch call dword ptr __pfmemcpy add esp,0ch

Как видно, робята из IBM всегда были за наукообразие в науке, чтобы компиляторы были компилятористыми, а пользователь, как собака, привязан к именно их поделке и функции pfmemcpy, навсегда. IBM_C_and_CPP_Compilers так просто за яички не возьмёшь :). В том же случае, MSVC генерит вполне автономный код.

;_____________________________________________________; Line 12 char stckprb[]={"\x09subl %eax,%esp\x0d\n"}; mov eax, DWORD PTR $SG1148 mov DWORD PTR _stckprb$[ebp], eax mov ecx, DWORD PTR $SG1148+4 mov DWORD PTR _stckprb$[ebp+4], ecx mov edx, DWORD PTR $SG1148+8 mov DWORD PTR _stckprb$[ebp+8], edx mov eax, DWORD PTR $SG1148+12 mov DWORD PTR _stckprb$[ebp+12], eax mov cx, WORD PTR $SG1148+16 mov WORD PTR _stckprb$[ebp+16], cx;_____________________________________________________; Line 13 char STR_NL[]={" ;#############################\x0d\n"}; mov ecx, 8 mov esi, OFFSET FLAT:$SG1151 lea edi, DWORD PTR _STR_NL$[ebp] rep movsd movsw

C++BUILDER COMMAND LINE TOOLS. Полный отстой. Городит, что ему самому в голову взбредёт. Инлайн ассемблер такой же тупой, как и в LCC win 32, Pelles C, LLVM и GCC - оторви и выкинь. Я так себе думаю, что в Борланд работал засланный казачок. Из Майкрософт, например. И вот этот засланный казачок по тихому отключил возможность отключать типа-оптимизацию в bcc32. В результате, C++BUILDER самостоятельно приобрёл зачатки интеллекта и способность понимать замыслы Творца. Поэтому, не возбранно херит целые блоки кода, когда ему учудится, что они в твоей проге ему(bcc32) не нужны. Буквально. Видимо, руководители Борланд, как и положено всяким руководителям, были абсолютно тупыми и совершенно никогда не интересовались собственным кодом. Вот C++BUILDER и окачурился. А сам Борланд - вслед за ним.

Поэтому, глядя на всё это, не заморачивайся тестированием. Ни к чему оно тебе. Бери пример с LCC win 32, Pelles C, LLVM, GCC и C++BUILDER. Склепал(скопипастил) программку побыстрому и ладно. Вот выйдет продукт, тогда и начнёшь исправлять. Если выйдет.. Если начнёшь.. Ни к чему вперёд забегать, пока дурачки-пользователи не начнут feed backи за их счёт присылать. Если начнут.. В конце концов, что такое успешный стартап, для тебя, если не бабло в руках и размещение акций на нью-йоркской фондовой бирже? Верно? :) Потом - хлоп, всё продал и снова в баню к шашлычку и тёлочкам. Потребности пользователя? - да кому они нужны?! И потребности и пользователи. :) Речь всегда идёт только о тех кто платит за продукт сейчас. Те, кто уже заплатил, никому уже не нужны. Не замечал? Вспомни тогда, как все дружно и повсеместно прекратили поддерживать XP, вдруг. То-то. :)

Особенно ясно следует понимать, что Замысел, бесплатного ознакомительного периода с продуктом, прекрасен. Но предназначен он совсем не для ознакомления, а для того, чтобы ты/я/он-дурачок бесплатно потестили их прогу, нашарика, для чуваков. Глядишь и нарыли бы для них пару багов за так и в своё личное время. А нас, вместо заплатить и спасибо, ещё бы и нах послали. Не лезь, мол, не в своё дело, лошара - много панимашь. Тестер нашёлся. Чё? - примазуваишься, бля! Так всегда поступает Fred из PureBasic. Потом, потихому исправляет. Но мы-то уже ни при чём. А ты думал. Экономия! А то ещё ключики нашарика начнём просить. :)

Пора поумнеть. Попались мне недавно два текстовых редактора, из новых. Даже не сырых, а мокрых, как детские пелёнки. Хотел я было аффторам написать, но вдруг вспомнил - А зачема мине? Я прав? - Я прав! Я прав! Я прав! :) А как же доброжелательность(их/моя)? Так там она, родимая - в тёплой, влажной, скользкой и пушистой. Как вариант, шаражка спицальна вывесила дырявый продукт и под него отмывает бабки. Ни ты, ни я, ни наши рипорты, ни какие бы то ни было реальные пользователи ей и даром не нужны. Затем и продукт дырявый. -Ты же не лох? - ну вот и вали. Борланд и C++BUILDER подходят на эту роль лучше всего.

И ещё один вполне закономерный вывод. Правило, не просят - не пользуй и бесплатно не фидбэч, незыблемо для большинства. Нарыл? - прибереги и потом стукни или мигом обосри и тут же пропиарься. Инструкцию call loop в LCC win 32, Pelles C, LLVM, GCC и C++BUILDER до меня не применял никто и никогда. А почему? А потому, что LCC win 32, Pelles C, LLVM, GCC и C++BUILDER не пользуется никто. А кто попользовался и наткнулся, уже давно вернулся в MSVC навсегда. Ибо, все дефекты LCC win 32, Pelles C, LLVM, GCC и C++BUILDER их аффторы считают достоинствами, перлами, изюминками, свойствами из серии "Надо же, как интересно получилось!" и исправлять не умеют, не будут и не хотят. Им достаточно того, что они и так - сами для них(для себя) клёвые. А зачема тюбе?

Зацени листинг предыдущей распечатки. Лепота! Невольно залюбуешься. Хоть сейчас в MASM суй. Попробуй.

; MSVC_2003_asm to better asm converter (c) Oleg E Tereshkov 2020; http://sites.google.com/site/excelmidi; Listing generated by Microsoft (R) Optimizing Compiler Version 13.10.3077
TITLE ...\file_name3.c .386P;##########################################################################if @Version gt 510.model FLATelse_TEXT SEGMENT PARA USE32 PUBLIC 'CODE'_TEXT ENDS_DATA SEGMENT DWORD USE32 PUBLIC 'DATA'_DATA ENDSCONST SEGMENT DWORD USE32 PUBLIC 'CONST'CONST ENDS_BSS SEGMENT DWORD USE32 PUBLIC 'BSS'_BSS ENDS$$SYMBOLS SEGMENT BYTE USE32 'DEBSYM'$$SYMBOLS ENDS_TLS SEGMENT DWORD USE32 PUBLIC 'TLS'_TLS ENDSFLAT GROUP _DATA, CONST, _BSS ASSUME CS: FLAT, DS: FLAT, SS: FLATendif;##########################################################################;##########################################################################_DATA SEGMENT;_____________________________________________________$SG500 DB 'wb', 00H_DATA ENDS;##########################################################################;##########################################################################PUBLIC _get_f_nameEXTRN _time:NEAREXTRN _localtime:NEAREXTRN _asctime:NEAR; Function compile flags: /Odt_TEXT SEGMENT_f_name$ = -24 ; size = 4_c2$ = -20 ; size = 4_c1$ = -16 ; size = 4_m_time$ = -12 ; size = 4_c3$ = -8 ; size = 4_s_time$ = -4 ; size = 4_get_f_name PROC NEAR; File ...\file_name3.c;_____________________________________________________; Line 8 char *get_f_name(void){ push ebp mov ebp, esp sub esp, 24 ; 00000018H;_____________________________________________________; Line 10 s_time=time(0);m_time=localtime(&s_time); push 0 call _time add esp, 4 mov DWORD PTR _s_time$[ebp], eax lea eax, DWORD PTR _s_time$[ebp] push eax call _localtime add esp, 4 mov DWORD PTR _m_time$[ebp], eax;_____________________________________________________; Line 11 f_name=asctime(m_time); mov ecx, DWORD PTR _m_time$[ebp] push ecx call _asctime add esp, 4 mov DWORD PTR _f_name$[ebp], eax;_____________________________________________________; Line 12 c1=f_name+3;c2=c1+1;c3=32;_asm{call aa}; mov edx, DWORD PTR _f_name$[ebp] add edx, 3 mov DWORD PTR _c1$[ebp], edx mov eax, DWORD PTR _c1$[ebp] add eax, 1 mov DWORD PTR _c2$[ebp], eax mov DWORD PTR _c3$[ebp], 32 ; 00000020H call $aa$492;_____________________________________________________; Line 13 c2++;_asm{call aa};c2++;c3=58;_asm {call aa}; mov ecx, DWORD PTR _c2$[ebp] add ecx, 1 mov DWORD PTR _c2$[ebp], ecx call $aa$492 mov edx, DWORD PTR _c2$[ebp] add edx, 1 mov DWORD PTR _c2$[ebp], edx mov DWORD PTR _c3$[ebp], 58 ; 0000003aH call $aa$492;_____________________________________________________; Line 14 c2++;c3=58;_asm{call aa};c2++;c3=32;_asm{call aa}; mov eax, DWORD PTR _c2$[ebp] add eax, 1 mov DWORD PTR _c2$[ebp], eax mov DWORD PTR _c3$[ebp], 58 ; 0000003aH call $aa$492 mov ecx, DWORD PTR _c2$[ebp] add ecx, 1 mov DWORD PTR _c2$[ebp], ecx mov DWORD PTR _c3$[ebp], 32 ; 00000020H call $aa$492;_____________________________________________________; Line 15 c2++;c3=10;_asm{call aa};c2=c2-6;*c2=0;return f_name; mov edx, DWORD PTR _c2$[ebp] add edx, 1 mov DWORD PTR _c2$[ebp], edx mov DWORD PTR _c3$[ebp], 10 ; 0000000aH call $aa$492 mov eax, DWORD PTR _c2$[ebp] sub eax, 6 mov DWORD PTR _c2$[ebp], eax mov ecx, DWORD PTR _c2$[ebp] mov BYTE PTR [ecx], 0 mov eax, DWORD PTR _f_name$[ebp] jmp SHORT $L485;_____________________________________________________$aa$492:;_____________________________________________________;_____________________________________________________$L494:; Line 16 _asm{aa:};while(*c2!=c3){*c1=*c2;c1++;c2++;} mov edx, DWORD PTR _c2$[ebp] movsx eax, BYTE PTR [edx] cmp eax, DWORD PTR _c3$[ebp] je SHORT $L495 mov ecx, DWORD PTR _c1$[ebp] mov edx, DWORD PTR _c2$[ebp] mov al, BYTE PTR [edx] mov BYTE PTR [ecx], al mov ecx, DWORD PTR _c1$[ebp] add ecx, 1 mov DWORD PTR _c1$[ebp], ecx mov edx, DWORD PTR _c2$[ebp] add edx, 1 mov DWORD PTR _c2$[ebp], edx jmp SHORT $L494;_____________________________________________________$L495:; Line 17 _asm{ret};} ret 0;_____________________________________________________$L485: mov esp, ebp pop ebp ret 0_get_f_name ENDP;##########################################################################;##########################################################################_TEXT ENDS;##########################################################################;##########################################################################PUBLIC _mainEXTRN _fopen:NEAREXTRN _fclose:NEAR; Function compile flags: /Odt_TEXT SEGMENT_f_out$ = -4 ; size = 4_main PROC NEAR;_____________________________________________________; Line 19 int main (void){int *f_out; push ebp mov ebp, esp push ecx;_____________________________________________________; Line 20 f_out=fopen(get_f_name(),"wb"); push OFFSET FLAT:$SG500 call _get_f_name push eax call _fopen add esp, 8 mov DWORD PTR _f_out$[ebp], eax;_____________________________________________________; Line 21 fclose(f_out);return 0;} mov eax, DWORD PTR _f_out$[ebp] push eax call _fclose add esp, 4 xor eax, eax mov esp, ebp pop ebp ret 0_main ENDP;##########################################################################;##########################################################################_TEXT ENDS;##########################################################################;##########################################################################END

Недавно, я узнал о принципе наименьшего сюрприза (principle of a least surprise), который предполагает буквально следующее: “что бы ты ни делал с твоим долбаным компилятором - скорее всего у тебя получится”. Согласитесь, это бы вдохновляло, если бы господа аффторы этих самых компиляторов и библиотек так упорно и повсеместно не следовали другому, тупому и непреложному правилу двойных стандартов в виде постоянных ударов кувалдами по пользовательской голове.

Не, ну, а вааще, беря в руки очередной Super-Pooper Vasyas Poopkins New Magestic Excelent Universal Compiler или исчерпывающий и всё отхвативший из него "Путеводитель по Нему" за аффторством Васиного блиськага друга Поцольда, ты должен сразу и безусловно офигеть от офигеннага щастя, не задавать глупых вопросов -А нафига эта фигня мине нада? и платить, платить, платить... и не один раз, при покупке, как раньше.. а каждый месяц.. и хер его знает за что. Почему Vasyas Poopkins во множественном числе? Потому, чито Вася Пупкин сильно поглупел и один явно уже не тянет. Много Васей нынче надо, очень много. Раньше это называлось коллективной ответственностью. Теперь - безответственностью. Но тоже - коллективной. :) Хотел ещё о зверинце-зоопарке PooreBASICов с тобой поговорить, но ты наверное и сам знаешь. :)

Смысл всего написанного здесь сводится к двум простым вещам. Первое - определяйтесь с выбором компилятора осознанно и как можно раньше. Второе - определившись, изучите предмет вожделения досконально и до конца. В Виндовс, MSVC может оказаться для вас идеальным вариантом. В других операционках - что-нибудь ещё. Главное, чтобы потом не было мучительно больно, когда вы наконец покончите с программками типа Hello World.

Скажу о себе и исходя из моего личного опыта. MSVC, для начинающего, в виде Command Line ToolKit 2003 на уровне командной строки языка С без плюсов - это бесплатно, доступно, в большинстве случаев надёжно, прозрачно, логично, понятно(даже мне) :) и без пидорского болота(геморроя) в inline ASM, в отличие от GCC. А если иные плоды коллективного/индивидуального творчества, по прошествии 30 лет, не могут отработать даже ассемблерные метки, о какой-такой многопоточности в них может, вообще, речь идти? Хотя, как всегда, выбор за вами. Ну, а что бывает, когда слепые ведут слепых, вы и сами уже хорошо знаете.

А если - нет, простой и вполне актуальный пример. Размер clang-cl.exe более 100 мегабайт. Солидно. Куда тому Go :). Видимо, команде LLVM, действительно, есть что нам сказать. Понятно, что судя по размеру clang-cl.exe, Objective-C не очень эффективный язык, а LLVM не очень оптимальный кампелятар :). Пока Оно-Это(100 мегабайт) всё в память прогрузится и стартанёт, проходит около 10-и секунд. Впечатляет. Cool! Вау! Есть время перевести дух, сделать глоток, вспомнить о Вечном и его за этот глоток возблагодарить! ГосподА Поцольды, расскажите команде LLVM об эффективном программировании и оптимизации, хоть что-нибудь, ещё раз. Ну пожалуйста :). SISO - дерьмо на входе и на выходе то же самое дерьмо. Не, ну, если речь каждый раз идёт только о том, что дарёным троянским коням в брюхо не смотрят: тогда - да, тогда - конечно, тогда - всё ОК. :)

И клянусь тебе. Специально я ничего не выискиваю. Просто, дерьмо из компиляторов само лезет изо всех щелей. Есть такой забавный компилятор (DCC32 V0.96b fБr DiceRTE Entwicklungssystem (Build 050) (c) 1996-2001 Christian Diefer) на немецком языке. Маленький, забавненький, аккуратненький и рабочий. Но тоже, сможет удивить. DiceRTE, по задумке, вроде, как универсален - Windows-DPMI, но на стеке сохраняет всё, что угодно, кроме регистра EBP. Вариант с mov ebp,esp в потрохах DiceRTE, вроде, как, тоже, зрительно просматривается, но как включить этот режим, естественно, не знает никто. Поскольку содержимое EBP не меняется и никак не привязано к ESP, который тоже живёт своей собственной жизнью и никак компилятором не затрагивается, то все-все типа-локальные переменные, будь в проге хоть 250000 функций, адресуются относительно значения EBP на старте. Поэтому, если какая-то локалка будет выглядеть, как [ebp+89000], не удивляйтесь и со всеми вытекающими. Куда при этом указывает сам EBP не знает никто. Но в коротких программах с двумя переменными, под Виндой всё работает на ура. :)

А ишо у господина Christianа весьма превратные представления о вызове stdcall. Такой компот link.exe уже не скормишь.


// msgbox1.c user32 kernel32// for DiceRTE dcc32// (C)O.E.Tereshkov 9:18 11.08.2021// http://sites.google.com/site/excelmidiextern int __stdcall MessageBoxA(int,char *,char *,int);extern int __stdcall ExitProcess(int);#define NULL 0#define MB_OK 0char szMsgCaption[]="Message_Box_A";char szMsgBoxText[]="dcc32 is Great!";void main(void){MessageBoxA(NULL,szMsgBoxText,szMsgCaption,MB_OK);ExitProcess(NULL);}

Вот поэтому-то(из-за превратных представлений идиотов) у каждого компилятора своё лицо, своя индивидуальность, свой неповторимый стиль. Как-то бабка Ирины Аллегровой сказала(о компиляторе): - Пусть 99-й, но хороший! - и пустилась во все тяжкие(поиски). Как по мне, пусть бы был 1 компилятор, но без заё$ов. Или ещё иллюстрация:


21 - fclose(infile);remove(argv[1]);return -3;}56 - fclose(infile);fclose(outfile);remove(argv[1]);57 - rename("_-_-_.asm", argv[1]);return 0;}
Warnung lasm2.c 21: Fehlender PrototypFehler lasm2.c 56: Redeklaration von "remove"Warnung lasm2.c 57: Fehlender Prototyp

Что происходит? В DCC32 дважды неопределённая в программе remove превратилась в переопределённую. Лечится подключением местного io.h. Компиляция заканчивается успешно и тут садится в лужу линкер. Потому, что _coutp и _fillbuffer, которыми в исходнике и в помине не пахло, взять негде. Но это стандартная практика всех компиляторов - знать лучше, что для тебя лучше. Прощай, DiceRTE-педрило! Таскать повсюду твою CRTD.DLL я не буду. Не буду и не хочу. Хотя, всё поправимо, если не пользоваться его стандартными хедерами, а выписывать все определения функций стандартной библиотеки, как внешние и вручную . Стон_дартная ситуация к вопросу 'А можно ли без include?'. Поздно пить Боржоми. В IBM_C_and_CPP_Compilers не лечится. Тяжёлый случай. Стойко стоит на своём до конца, а в варианте IBM VisualAge, вообще, скатывается в маразм. Хочешь, чтобы твой компилятор не интересовал хакеров и вообще никого? - скопируй идеологию IBM VisualAge. Но DiceRTE-DCC32, как неожиданная, забавная игрушка , как на автомате голый, не допиляный Си-компилятор без stdcall, пока поживёт :). При этом, возможность допилить DASM32 весьма сомнительна. Ибо @@ - там признак метки. Да и зачема мине?:)

И в живых остались только трое - DCC32, Tcc и MSVC :). Теперь тебе понятно почему ассемблер всё ещё жив и будет жить всегда? Он хоть и начинается со слова ASS, что как бэ намекает, но только один Asm особо не возражая делает то, что ему говорят с первого раза. Повторяю ИШО раз. Не заморачивайся тестированием, когда пишешь для других. Не трать своё драгоценное время зря. Не пиши документацию. Совсем делать нечего? Учись, как делают остальные. Собралось? Запустилось? И хватит с них - дураков. Пусть сначала, сами, хоть один нормальный компилятор предъявят. Хоть один. Чтобы пользоваться им и об него не спотыкаться.

Страуструп как-то высказал здравую мысль о том, что C++ отличный язык, просто под него ещё не создан хороший компилятор. Страуструп, бери выше! Как видишь, хороший(бездефектный) компилятор за 50 лет не создан даже для C и не предвидится. Ключа 'Слушаюсь и повинуюсь' в трансляторах C/C++ пока нет и никогда не будет. Зародыши в пробирках выращивать можно, но вырастить нельзя. Страуструп, как я слышал, свой/его хороший компилятор C++, тоже, ещё за 40 лет не дописал. А теперь представь: ты, дебагер и Hello World размером 22 мегабайта. Не смешно? Или какого-нибудь барана, который с помощью бараньего полиграфа, написанного таким же тупым бараном, на тупом бараньем компиляторе, в такой же кишащей багами и вируснёй бараньей операционке, стоящей на таком же дефектном бараньем железе, будет определять правду ли ты говоришь, а потом клеить на тебя бараньи ярлыки? Не даром же спутники мимо планет промахиваются. Вот, то-то и оно. (MS CL.EXE 2003)+(DCC32) реально рулят. Спросишь, а нахера козе баян? В DCC32 строгий синтаксис. Без компромиссов. Так-что сам понимаешь - для контроля правописания.

Короче и так далее, под занавес собрания, предлагаю тебе эротический и эзотерический квэст с главной эрогенной зоной в твоём мозгу. В последнем листинге есть такая строчка _asm{aa:};while(*c2!=c3){*c1=*c2;c1++;c2++;}_asm{ret};. Это классическая подпрограмма, как в бейсике или ассемблере. Главное отличие подпрограммы от функции - подпрограмма, хоть и используется, тоже, многократно, не требует параметров передаваемых ей через стек на входе, а возврат из неё происходит в пределах тела той же функции или другой подпрограммы, в/из которых она вызвалась.

Попробуй переписать генератор автоматических названий файлов, превратив эту подпрограмму в отдельно стоящую функцию, передать ей параметры, завершить её так, чтобы всё было тип-топ. Мне это удалась часов за 5 скрипения мозгами или, что том у меня есть :). Я и сейчас практически не понимаю, что же на самом деле я там написал. Представь, как мелко я плаваю :). Но работает :). Для самоконтроля используй DiceRTE DCC32 V0.96b, если сможешь, или какой-нибудь Dev-Cpp. MSVC очень либерален к синтаксису :). Кстати, размер ексешника после DCC32 - 2560 байт, после TCC - 2046 байт, после mingw32 4.9.2 - 105321 байт. Больше - лучше!

Итак, всё достаточно просто. Требуется заменить строчку _asm{call aa}; каким-нибудь вызовом shift();. Вот доказательство теоремы.

Немного не разборчиво. Но работа, ведь, самостоятельная. Когда ты закончишь, если закончишь, и сравнишь изначальный оригинал и то, что у тебя получилось, наверное, единственной мыслью в твоей голове будет - Какой дол$оё$ всю эту #уйню придумал?! В смысле, отсутствие операторов call-ret в языке C. Но вряд ли мы узнаем. Иначе, у Ритчи была шизофрения :). В языке C не возможно вызвать подпрограмму. Это доказанный факт. И уже по одной только этой причине, никаким изяществом в языке C и близко никогда не воняло. Сравни. Одна, всем понятная, уместная и адекватная строчка кода - _asm{aa:};while(*c2!=c3){*c1=*c2;c1++;c2++;}_asm{ret}, которая пишется за 30 секунд. И вместо нее, 5 часов никому не нужной е$ли. Спасибо, Ритч!

Кстати, если ты(как и я) сталкиваешься с подобным вызовом впервые(поэтому, у меня эта возня и заняла 5 часов), полезно будет не то, что бы прокачать скил, но просто кое-что почитать и освежить себе мозг. Вот https://narodstream.ru офигенный сайт, ну просто офигенный сайт, для этого. С удивительными, ну просто удивительными https://narodstream.ru/programmirovanie_n_c/ уроками в количестве 45 штук по языку СИ. Керниган и Ритчи, медленно сгорая от стыда, нервно курят в сторонке, пытаясь незаметно повесить свой ЖАЛКИЙ СПРАВОЧНИК на гвоздь в туалете. Я писал shift(), что называется снизу вверх, используя отладочный вывод и постоянно заглядывая в ассемблерный листинг MSVC, стараясь понять, что эти идиоты из комитета ANSI C от меня хотят. Но у тебя, теперь, есть реальный шанс, всё познав и осознав, сделать это, как учат Шилды и Поцолды, сверху вниз, ничем не пользуясь - одной только силой мысли. Хотя, вряд ли. :) Но всё равно, СПАСИБО https://narodstream.ru/.

Кстати, об идиотах из комитета ANSI C. Допустим, там было 89 "коней" и 99 "кобыл". И вот, ни в одну светлую "лошадиную" головку не зашла мысль о том, что не плохо бы было добавить и пару новых операторов call - retcall, добавить возможность по необходимости делать метки goto глобальными и доступными, как указатели. Узаконить inline asm. Зазывать библиотеки прямо из тела программы - #libs msvcrt.lib, kernel32.lib, user32.lib. Но не затем они там штаны и юбки просиживали. А тянули функциональную парадигму во все дворы. Зачем делать просто, если можно сделать сложно? Не, ну,а чё? Переходим на MSIL - Microsoft Intermediate Language. Он такой понятный и легко читаемый, прямо, как из лекций о хорошем стиле программирования.

Правда, специально я ничего не выискиваю. Фигня из GCC, TCC, PCC, LCC win 32, Pelles C, cc386, DiceRTE DCC32 V0.96b и прочего LLVM сама изо всех щелей прёт. Не даром же спутники мимо планет промахиваются. MSVC is BEST! А не веришь, - возьми карандашик и сам пидрахуй. 8/3=? И нафиг мне такая ваша многопоточность сдалась? SISO - фигня на входе и на выходе та же самая фигня. Копирасты. Привет комитету ANSI C. :)

Примечательно, что в функции my_div() DiceRTE DCC32 впервые на моих глазах задействовал регистры EBP и ESP по стандартной схеме. Что тут можно сказать? Чужой компилятор - потёмки. Самый избыточный код в функции my_div() замутил PCC. Он приготовил указатель стека к вызову следующей функции, которого никогда не будет и совершил один бессмысленный безусловный переход по стандартной схеме TCC, что говорит о наличии у этих двух общего дедушки или бабушки, а возможно, даже, о том, что многие компиляторы пишутся под диктовку Святага Духа, причём, некоторые, даже, под диктовку клонов одного и того же Святага Духа, при этом, работу над его ашиппками этот святой дух никогда не делает. Не очень хорошо.

Однако, копирастия и святой дух, это немножко о разном. А то, что новые Скрижали Моисея, пока, ещё не предвидятся, так подождём-с, подождём-с. Эпизод с делением 8 на 3 со всей очевидностью показал, что тестированием компиляторов не занимается никто, а изначально, самостоятельно писался только MSVC. За него и держись. MSVC is BEST! А остальные просто осваивали, осваивают и будут просто осваивать выделенные под их байду средства. Это к вопросу о бараньем компиляторе, на котором тупые бараны пишут их тупые бараньи полиграфы, пытаясь выковырять изо всех остальных их(баранов) тупую, баранью баранью ложь, а сами при этом, даже 8 на 3 не могут истинно поделить.

Ты был прав! Страуструп! Ты был абсолютно прав!

Не ту жену тогда ты для нас украл!

Ты нам взвалил на плечи чужой липучий крест,

А сам в свою нору залез.

Вот три выходных листинга одной и той же моей программки на пять строк из под трёх разных компиляторов. Верхний и нижний листинги, как бы дефектные. Каждый по своему, с ярко выраженной индивидуальностью. Но на самом деле иллюстрируют изменения в памяти при попытке записи за пределами массива. Систематизировать что-либо не представляется возможным. Интересно, что DiceRTE DCC32 и Digital Mars эту программку скомпилировать не смогли. Но это частности. Язык Си хороший, даже, ОЧИНЬ хороший - некоторые компиляторы плохие. Правда же, Страуструп? И так целых 50 лет подряд. А шо ж такое? :)

Короче, пора подводить итог. Все компиляторы разные, с разным интеллектом у их создателей и этого никому не удастся избежать. Когда лично твоя компилюга поставит тебя раком и воспользуется тобой без вазелина - вопрос твоей изобретательности, настойчивости, времени и труда. Шо делать, если ты хочишь, шобы твоя морковка всё-таки долетела до той самой далёкой и мунящей тебя звизды, а не слегла в соседней канаве, надолго?

1. Ясно осознавать, что компилятор тупой. Вероятно, что, даже, на много тупее тебя.

2. Более того. Компилятор твой - враг твой. Ты с ним только борешься. Как дерево с садоводом. Перестань доверять ему, очнись.

3.Компилятор, конечно, очень ловко тасует байты. Но толк из этого получается только иногда. Сказывается небольшое отсутствие у него интеллекта.

4. Если твой компилятор не в состоянии выдать ассемблерный листинг с чёткой привязкой к строкам исходника, значит у его создунцов не хватило на это мозгов и ума, а следовательно и на всё остальное. Сразу нах. (Не касается TCC). А что, где, как и у кого они скописпиз#или пусть волнует уже других.

5.Не важно на сколько эффективный код генерит компилятор, если этот код неправильный.

6. Твой удел Ассемблер. Если нет, все равно, твой удел Ассемблер. Максимум, что ты можешь себе позволить - MSVC из командной строки в режиме Си без плюсов. Хотя, TCC, тоже, очень хорош. А как следует из предыдущей картинки, даже лучше, чем MSVC. TCC - 10 балов из 10. И если совсем честно, TCC меня всегда только выручал. Но не создаёт выходной асм и 8 на 3 делить всё-таки не умеет :). Равно, как и жевать sall $2,%eax.

7. Получаешь из под MSVC асм. Контролируешь, деребанишь на функции, пересобираешь и тд, и тп, отправляешь всё в MASM/UASM.

8. Везде, где только нужно, используешь inline asm и никаких указателей на указатели. Перестань тратить жизнь на всё это фуфло. Оставь указатели на указатели подлецам из комитета ANSI C. Пусть сами в них играют.

9.Одна строка - одно действие, хороший принцип. Когда заработает, потом укрупнишь.

10. Всегда иметь под рукой 2-3 компилятора. Если все 3 тупят одинаково, возможно, что тупишь ты. Вопрос "Что делать?", если прога неправильная, а все 3 компилятора тупят по разному, остаётся открытым.

11. Проверяешь, проверяешь и ещё раз всё перепроверяешь. Если надо, начинаешь с начала.

12. Когда пишешь для других, так не заморачиваешься. Цепляешься. к каждой букве договора. Собралось? Запустилось? - Будь здоров! Я не я. Один раз живёшь. По Писанию. Как они к тебе, так и ты к ним.

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

14. Держись подальше от бараньих полиграфов.

Сечёшь ASM? Зацени, каким разным может быть один и тот же переключатель switch.

Зачем было это всё? Ну так мы же пишем Энигму. Совершенно очевидно, что во многих компиляторах её писать просто опасно. Вот зачем. Компилятор, который не может поделить 8 на 3 не вызывает доверия. Компилятор Си, который не умеет работать с указателями, вызывает доверие ещё меньше. Что же выбрать? :)

В русскоязычной среде принято поливать говном индусский код. 8 лет назад некий, нет не Рамачарака, а скромный и застенчивый Roshan Singh явил миру Micro C Compiler v1.0.0.0 Copyright (C) Roshan Singh 2013 2014 2015. Добротный, вполне, компилятор. Мою прогу жуёт. И это хорошо. Одно печалит. На поверку, Micro C Compiler v1.0.0.0 оказывается слегка урезанным TCC v.9.26. Roshan Singh индус. В моём понимании, индусы - те, кому не хватило смелости стать настоящими цыганами. Не будем пускаться в риторику по поводу врождённой честности индусо-цыган, просто, в следующий раз, когда будете поливать говном индусский код, присмотритесь, а вдруг этот код ваш. С копирастией при написании компиляторов Си, думаю, разобрались.

На сегодня, пользоваться компиляторами Си, без потом пристального разглядывания в микроскоп того, что они в ексешнике наоткладывали, просто опасно. Мне ещё повезло, что свой путь я начал :) именно с TCC. Пока пользуешься Си, как до предела урезанным Бейсиком, ну там 2+3 или 3+2, но только не 8/3 - всё в порядке. Как только сделал шаг на встречу Pure_C - всё, пиз#ец, приплыли, сразу начинаются проблемы с компилятором, лучше не подходи. Думаю, Андрюшка Столяров мною бы гордился. Но, Андрюшка, зачем морочить головы детям тем, чем они всё равно никогда не смогут воспользоваться? Дебильные звёздочки в массивах корректно отрабатывает не каждый компилятор, некоторые садятся в лужу. А раз так, то никому твои звёздочки при использовании массивов и нахер не нужны. И в первую очередь писателям компиляторов.

Скажешь, пиши свой? - сам пиши. Писунов и без меня хватает. :) Но знаете, что печальнее всего? - ни горячо любимый мною MSVC ToolKit 2003, ни LCC 4.1, ни LLVM v3.8, ни прочие игрушки-побрякушки уже никому и никогда не исправить. Да и надо ли?

Никогда не пробовал компилятор IBM, но как нибудь из принципа попробую. Даже прям щас. V.3.6 - антиквариат. Дело пяти минут. Ой, программка сходу вылетела с ашиппкай - no fate(узнать не судьба:). Кстати, в IBM_C_and_CPP_Compilers_for_WinNT-v3.6.5 нет, даже, собственного компилятора языка ассемблера. Опять паразитируем на Майкрософт.

И ишо прикол, на прощанье. Ни один кампелятар Си в мире, кроме MSVC, не может даже 8 на 3 разделить. А чуваки на них PGP ломают :). Видел, как только что построенные дома на глазах разваливаются? Ну, и чему удивляться? Предложат тебе тест на полиграфе пройти, - знаешь, теперь, что делать? Или рассказать? Пока-пока:).

(с) Терешков Олег Евгеньевич. .Август 2021.

Если бы у меня спросили за что я люблю Си, я б ответил, что не люблю, а если б и любил, то очевидно, за определённость - в нём не вазможна ашиппиться. Ни мне, ни, особенно, компилятору. Почему? А потому, что язык Си, очевидно, создавался сверху вниз, по чёткому, неукоснительно продуманному плану, как нас и учили, а не по принципу - кому, что и когда в голову взбредёт. (Это шутка - скорее всего по наитию - стандарт ANSI C нарисовался только через 15 лет, после появления самого языка.) И жаль, что те тайные заказчики языка Си, которые наняли Дениса Ритчи, не слышали, даже о языке Бейсик. Это, тоже, ясно вполне.

Но при всех недостатках, подкупает способность некоторых компиляторов языка Си и сегодня не совать в объектные файлы всякую никому не нужную дрянь. Вот это-то весьма редкое сейчас качество и можно назвать ИЗЯЩЕСТВОМ.