Почему-то компилируется. Помогите!

Один мой друг написал hello world, который почем-то компилируется и работает. Компилятор - GCC. Объясните, пожалуйста синтаксис :slight_smile:

#include <stdio.h>

int typedef[[]]$;

int main($[[]]$) {
  [[]]$:&&$&&$&&puts("hello world");
}

Вторая версия тоё-же глубокомысленной программы, но попроще

#include <stdio.h>

void main() void;

void; {
  puts("hello world");
}

Есть еще самый первый вариант, но я прочитал у ШтраусТруппа, что goto - это плохой стиль :frowning:

#include <stdio.h>
#include <stdlib.h>

int main() {

  goto *puts("Hello world"), puts("Goodbye world"), exit;

}

не не не, надо найти код, где goto красивейшее решение, где if () и в подмётки не годилось из-за возникающей сложности конструкции

FreeBSD стетевой стек весь утыкан goto :). Любые попытки исправлять лишь делают хуже

Из анекдота:

  • Ты где потерял?
  • В кустах.
  • А почему ищешь под фонарем?
  • Здесь светлее.

IMHO если написал друг, с него и нужно спрашивать. Форум то тут при чем?

иногда яму на пути проще перепрыгнуть

может быть переписана проще

а третья версия - это просто операторы через запятую

вот тут нет ошибки ? может так или нет ?
void main();
void;

в Arduino IDE тоже компилируется?

Если расширение у файла будет .c - то будет компилироваться. с .ino не проверял, это же ++.

В Си++, который .ino, все совсем по другому: Например, можно не использовать { и } для оператора switch. Можно в switch отказаться от break

Ладно, шучу. В Си, все тоже самое можно. Специально для Ардуины: правильный switch() без всяких там break и скобок, которые ухудшают читаемость кода. Смешной варнинг вываливает, про то, что наш код никогда не исполнится, но таки исполняет:

// Самый Удобный switch(), для начинающих.
//

#include <Arduino.h>

void setup() {
  
  Serial.begin(115200);
}


void loop() {

  int i = 1;

  switch (i)

         if (0) case 1 ... 10: puts("i = 1 ... 10");          // if(0) или все же нет? :)
    else if (0) case 0:        puts("i = 0");
    else if (0) case 11:       puts("i = 11");
    else if (0) default:       puts("i = something else");


  delay(1000);
}

Кстати, else в данном примере можно и вовсе удалить. Поведение не изменится.

у вас, у дзен буддистов, особый ход мыслей и сознания, порой извращенный до безобразия.

Там не все так просто и даже есть немножко UB, но вроде с GCC проносит. :).

ЗЫЖ: goto в самом начале таки исполняется

Отнюдь. Мне открылась истина, после того, как я зачем-то полез в исходники ГЦЦ и обнаружил, что switch() и goto() это одно и то же, а case 2: и case_2: какой-нибудь для ГЦЦ - одно и то-же по сути. switch() это goto, case X: - это просто метка. Си - простой язык. А раз это просто goto и просто метка, то вполне себе можно туда воткнуть и if с else

Нет, ошибок нет.

я же и говорю, простые вещи вам не понятны, вы превращаете их в сложные.
для простых, смертных это выглядит так - смотри как я могу!
на вопрос, зачем? начинаются “сопли” :grinning_face_with_smiling_eyes:

…как много нам (вам) открытий чудных…

Не удивительно… goto умеет использовать адреса как метки
Более того, в GCC goto даже может отрабатывать массивы меток:

goto *array[i];

Самый первый пост в этой теме - это шуточный пост.

Идея в том, что люди, которые хорошр знают Си\Си++ (ну или считающие, что они его хорошо знают) - спотыкаются о такой код, типа, “а, погодите-ка, это вообще компилируется?”. Но если вас разражает, то ладно, прекращаю.

Будем серьезными.

Мы же тут Ардуинщики, в конце концов, а не в бирюльки играем.

Спойлер

Эх, надо на obfuscated code contest готовиться. Сделаем то, что никто не делал - не будем использовать #define :slight_smile:

Да нет, зачем раздражает, а? довольно забавно. Разминка для ума.

Могу сказать про себя - второй и третий код, хоть и выглядят необычно, особого отторжения у меня не вызвали.

А вот первый выглядит бредом… и почему-то именно его никто не прокомментировал.

goto the King!

Например, цикл for на основе goto:

#include <stdio.h>

int main() {

  /* Печатает на экране пять строчек i=0,  i=1  и т.д.  */

  int i = (i = 0) & ({_: 0;}) | printf("i = %d\n", i) * 
          (++i > 5) ?: ({goto *&&_; 0;});

  return 0;

}

Но это , конечно, месиво.

Правильным решением будет убрать весь код выше в макро с каким-нибудь именем, типа SELECT_SPECIAL(i, max_i, code_to_execute)

@BABOS ! Ты недавно спрашивал, как так писать код, чтобы кроме тебя его никто не смог сопрровождать? Мотай на ус.

Как говаривал автор первого кода:

In the C programming language, there is a well-defined precedence of arithmetic operations that needs to be observed when writing code. In particular, it’s important for every software engineer to remember that the && operator has a strict precedence over &&

Спойлер

PS: это шуточный комментарий, призванный еще более запутать. Любой оператор has precedence over itself :slight_smile: