Как сделать вечный цикл?
От: vsb Казахстан  
Дата: 16.09.23 08:23
Оценка: :))
Пишу программу для микроконтроллера, нужно написать код, который просто будет крутиться в вечном цикле. Т.е. компилироваться в инструкцию b .

В голову, конечно, сразу приходит for ( ; ; ) {} но clang с оптимизацией этот цикл тупо выкидывает.

Можно написать for (volatile unsigned unused; ; unused++) {} этот код не выкидывает, но мне не нравится, что он постоянно гоняет трафик между процессором и оперативной памятью, например это может мешать DMA-передачам.

Можно ли это сделать на C, согласно стандарту и без ассемблерных вставок?
Отредактировано 16.09.2023 8:25 vsb . Предыдущая версия . Еще …
Отредактировано 16.09.2023 8:24 vsb . Предыдущая версия .
Отредактировано 16.09.2023 8:24 vsb . Предыдущая версия .
Re: Как сделать вечный цикл?
От: Нomunculus Россия  
Дата: 16.09.23 08:28
Оценка: +1
Здравствуйте, vsb, Вы писали:

while (true)
Re: Как сделать вечный цикл?
От: Pzz Россия https://github.com/alexpevzner
Дата: 16.09.23 08:31
Оценка: 16 (1) +3
Здравствуйте, vsb, Вы писали:

vsb>В голову, конечно, сразу приходит for ( ; ; ) {} но clang с оптимизацией этот цикл тупо выкидывает.


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

vsb>Можно ли это сделать на C, согласно стандарту и без ассемблерных вставок?


Нет.

Я бы вставил в цикл пустую ассемблерную вставку. Даже не из nop, а из пустой строки.

Компилятор не понимает этих вставок, но знает, что не понимает, и поэтому не выкидывает.
Re[2]: Как сделать вечный цикл?
От: vsb Казахстан  
Дата: 16.09.23 08:31
Оценка:
Здравствуйте, Нomunculus, Вы писали:

Н>while (true)


https://godbolt.org/z/5Gnsxh5cj

armv7-a clang, -Os

int main(void)
{
    while (true);
}


main:


Выкинул цикл.
Re[3]: Как сделать вечный цикл?
От: Нomunculus Россия  
Дата: 16.09.23 08:32
Оценка:
Здравствуйте, vsb, Вы писали:

Может потому что тело цикла пустое?
Виндовый цикл обработки сообщений именно так выглядит
Re[2]: Как сделать вечный цикл?
От: vsb Казахстан  
Дата: 16.09.23 08:33
Оценка:
Здравствуйте, Pzz, Вы писали:

Pzz>Я бы вставил в цикл пустую ассемблерную вставку. Даже не из nop, а из пустой строки.


Спасибо, так работает, конечно есть опасения, что "завтра" он может стать умней и выкинуть и такой цикл. Я так понимаю, asm это по определению implementation-defined. Ладно, будем надеяться, что хоть такой специальный случай оставят.
Re[4]: Как сделать вечный цикл?
От: vsb Казахстан  
Дата: 16.09.23 08:34
Оценка:
Здравствуйте, Нomunculus, Вы писали:

Н>Может потому что тело цикла пустое?


Ну да, в этом вопрос и состоит — как написать пустой цикл, чтобы компилятор его не выкидывал при компиляции.
Re[5]: Как сделать вечный цикл?
От: Нomunculus Россия  
Дата: 16.09.23 08:37
Оценка:
Здравствуйте, vsb, Вы писали:

Попробуй два ссылающихся друг на друга goto
Re[3]: Как сделать вечный цикл?
От: Pzz Россия https://github.com/alexpevzner
Дата: 16.09.23 08:37
Оценка:
Здравствуйте, vsb, Вы писали:

Pzz>>Я бы вставил в цикл пустую ассемблерную вставку. Даже не из nop, а из пустой строки.


vsb>Спасибо, так работает, конечно есть опасения, что "завтра" он может стать умней и выкинуть и такой цикл.


Нет, вряд ли. Ему для этого придется научиться понимать ассемблер, а зачем ему это надо?
Re[6]: Как сделать вечный цикл?
От: vsb Казахстан  
Дата: 16.09.23 08:38
Оценка: 3 (1)
Здравствуйте, Нomunculus, Вы писали:

Н>Попробуй два ссылающихся друг на друга goto


Такое

int main(void)
{
    a: goto b;
    b: goto a;
}


не работает, "оптимизирует".
Re[4]: Как сделать вечный цикл?
От: vsb Казахстан  
Дата: 16.09.23 08:39
Оценка:
Здравствуйте, Pzz, Вы писали:

vsb>>Спасибо, так работает, конечно есть опасения, что "завтра" он может стать умней и выкинуть и такой цикл.


Pzz>Нет, вряд ли. Ему для этого придется научиться понимать ассемблер, а зачем ему это надо?


РаздражатьУдивлять программистов, конечно, для чего же ещё может понадобиться "оптимизировать" пустые циклы (:
Re: Как сделать вечный цикл?
От: andyp  
Дата: 16.09.23 09:06
Оценка:
Здравствуйте, vsb, Вы писали:

vsb>В голову, конечно, сразу приходит for ( ; ; ) {} но clang с оптимизацией этот цикл тупо выкидывает.


Ну так сделай это внутри отдельной функции, скажем forever() в отдельном файле. Для файла оптимизацию выключи. Не лучший варик, но хоть по всей программе не будет расползаться.
Re: Как сделать вечный цикл?
От: kov_serg Россия  
Дата: 16.09.23 09:12
Оценка:
Здравствуйте, vsb, Вы писали:

vsb>В голову, конечно, сразу приходит for ( ; ; ) {} но clang с оптимизацией этот цикл тупо выкидывает.

Просто выкиньте clang и используйте нормальный компилятор.

Пишется на ассемблере загрузчик, который после инициализации стека и другой фигни
вызывает setup() и потом loop() в бесконечном цикле. Посмотрите на arduino
void setup() {
  //
}
void loop() {
  
}


vsb>Можно ли это сделать на C, согласно стандарту и без ассемблерных вставок?

да, но для этого отключите е$@нутые оптимизации clang для файла boot.c
void _start() {
  SET_STACK();
  setup();
  for(;;) loop();
}
Re[5]: Как сделать вечный цикл?
От: Pzz Россия https://github.com/alexpevzner
Дата: 16.09.23 09:40
Оценка:
Здравствуйте, vsb, Вы писали:

Pzz>>Нет, вряд ли. Ему для этого придется научиться понимать ассемблер, а зачем ему это надо?


vsb>РаздражатьУдивлять программистов, конечно, для чего же ещё может понадобиться "оптимизировать" пустые циклы (:


Они по дефолту оптимизируются. Чтобы они не оптимизировались, надо специально усилия предпринимать.

P.S. В инструкции к gcc, когда я ее читал последний раз, было написано, что gcc понимает пустой цикл, как такой специальный случай, и сознательно его не оптимизирует.

Похоже, это еще одно знание, утраченное цивилизацией — то ли в clang, то ли вообще...
Re[6]: Как сделать вечный цикл?
От: Нomunculus Россия  
Дата: 16.09.23 09:48
Оценка:
Здравствуйте, Pzz, Вы писали:

Pzz>Похоже, это еще одно знание, утраченное цивилизацией — то ли в clang, то ли вообще...


Как и любое такое знание — из разряда умения постройки пирамид. Утратилось, потому что не нать
Re[7]: Как сделать вечный цикл?
От: Pzz Россия https://github.com/alexpevzner
Дата: 16.09.23 09:56
Оценка: +1
Здравствуйте, Нomunculus, Вы писали:

Pzz>>Похоже, это еще одно знание, утраченное цивилизацией — то ли в clang, то ли вообще...


Н>Как и любое такое знание — из разряда умения постройки пирамид. Утратилось, потому что не нать


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

А если теперь в нем это постепенно отмирает, нафиг он вообще нужен?

Просто раньше за ним живые люди стояли, типа Ричи и Томпсона, которые понимали, что они делают. А теперь коллективный разум в виде коммитета по стандартизации. А "коллективный" — это, считай, никакой.
Re: Как сделать вечный цикл?
От: Pavel Dvorkin Россия  
Дата: 16.09.23 10:33
Оценка:
Здравствуйте, vsb, Вы писали:

vsb>Можно ли это сделать на C, согласно стандарту и без ассемблерных вставок?


Попробуй

loop : goto loop;
With best regards
Pavel Dvorkin
Re: Как сделать вечный цикл?
От: Alekzander  
Дата: 16.09.23 11:46
Оценка: 1 (1) +3 :)
Здравствуйте, vsb, Вы писали:

vsb>В голову, конечно, сразу приходит for ( ; ; ) {} но clang с оптимизацией этот цикл тупо выкидывает.


А на каком, пардон, основании? Бесконечный цикл — это же не if (false). Совсем охренели эти оптимизаторы.
Re[8]: Как сделать вечный цикл?
От: kov_serg Россия  
Дата: 16.09.23 11:59
Оценка: +2
Здравствуйте, Pzz, Вы писали:

Pzz>Просто раньше за ним живые люди стояли, типа Ричи и Томпсона, которые понимали, что они делают. А теперь коллективный разум в виде коммитета по стандартизации. А "коллективный" — это, считай, никакой.

Точно: — У семи нянек детё без глаза.
Re[2]: Как сделать вечный цикл?
От: vsb Казахстан  
Дата: 16.09.23 12:01
Оценка: :)
Здравствуйте, Pavel Dvorkin, Вы писали:

vsb>>Можно ли это сделать на C, согласно стандарту и без ассемблерных вставок?


PD>Попробуй


PD>loop : goto loop;


Выкидывает.
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.