[7c2fa9c606354169d205e791dcab46986bdeb46e] #c #plan9 

Компилятор Си в Plan9

https://plan9.io/sys/doc/comp.html
Там отсутствуют (игнорируются): register, volatile, const.

   The compilers do their own register allocation so the register
   keyword is ignored. For different reasons, volatile and const are
   also ignored.

А я ведь по сути в Си коде тоже не хочу и не использую их, кроме const,
который по сути как подсказка для человека и lint играет роль только.
Ведь и в Go нет const аргументов.

[оставить комментарий]
комментарий 0:
From: kmeaw
Date: 2026-05-15 08:45:15Z

Интересно, ведь это лишает компилятор возможности делать более сложные
оптимизации (const) и после них генерировать правильный код (volatile).

Вырожденный пример для выдуманного микроконтроллера:

/* tied to a HW register by the linker */
extern volatile uint64_t OSCCTL;
extern volatile uint64_t TMR0CNT;

#define OSCCTL_UNLOCK_STEPS 4

const uint64_t OSCCTL_UNLOCK[OSCCTL_UNLOCK_STEPS] = {
    0x11111110,
    0x22222220,
    0x33333330,
    0x44444440,
};

#define OSCCTL_LOWPWR    0x80000000
#define OSCCTL_BUSY    0x00000001

void lowpower() {
    size_t i;

    for (i = 0; i < OSCCTL_UNLOCK_STEPS; ++i) {
        OSCCTL |= OSCCTL_UNLOCK[i];
        while (OSCCTL & OSCCTL_BUSY);
    }
    OSCCTL |= OSCCTL_LOWPWR;
    while (OSCCTL & OSCCTL_BUSY);
}

void msleep(uint64_t interval) {
    /* FIXME: handle timer overflows and tiny intervals */
    uint64_t now = TMR0CNT;
    uint64_t later = now + interval;
    while (TMR0CNT < later) {
        lowpower();
    }
}

const тут позволяет компилятору развернуть цикл и заинлайнить ключи.

volatile запретит кеширование аппаратного регистра в регистрах общего
назначения, без этого оптимизатор мог бы доказать, что цикл в msleep
бесконечный, а в lowpower BUSY никогда не случается, да и вообще
дооптимизироваться до OSCCTL |= 0xC7777770 - эту запись он выкинуть уже не
имеет права, потому что переменная не объявлена static, и может использоваться
в соседних единицах трансляции.
комментарий 1:
From: Sergey Matveev
Date: 2026-05-15 13:07:15Z

*** kmeaw [2026-05-15 08:46]:
>Интересно, ведь это лишает компилятор возможности делать более сложные
>оптимизации (const) и после них генерировать правильный код (volatile).

Не без этого. Видел в реальном коде (ассемблерном) как const и volatile
могут помочь соптимизировать код компилятору. Но зато и сколько проблем
компиляторы могут для криптографии создать из-за излишней оптимизации!

В Plan9 наверное считают что пофиг на производительность: главное
простота, ясность что получишь. Пайк вроде говорил, что у них нигде нет
endian-specific кода: везде endian-neutral. Я тоже в Си везде делаю
только такой, понимая что где-то может вредить, но насколько проще
человеку из-за него.
комментарий 2:
From: Yarik Sysoev
Date: 2026-05-15 14:46:47Z

Могу предположить, что область применимости компилятора для plan9
ограничена юзерспейсом plan9, так что чего-то удивительного тут нет. А
всякие случаи "хочу, чтобы программа данные зануляла перед тем, как
делать free()" или "хочу читать один и тот же кусок памяти в надежде на
изменение" - это уже задачи из области ответственности самой ОС.

Что мне кажется более странным, это то, что в plan9 нет poll() или
чего-то подобного. По крайней мере, я не нашёл чего-то подобного в
документации.
комментарий 3:
From: Sergey Matveev
Date: 2026-05-15 15:11:14Z

*** Yarik Sysoev [2026-05-15 17:46]:
>Могу предположить, что область применимости компилятора для plan9 ограничена
>юзерспейсом plan9, так что чего-то удивительного тут нет.

Но код то в итоге в машинный для железа генерируется. И его можно люто
оптимизировать бы было. Не очень понял причём тут ОС или userspace.

>Что мне кажется более странным, это то, что в plan9 нет poll() или чего-то
>подобного. По крайней мере, я не нашёл чего-то подобного в документации.

Я впервые вообще читаю доки по его функам, но как-будто Alt в thread(3):
https://9fans.github.io/plan9port/man/man3/thread.html как-раз про это.
комментарий 4:
From: Sergey Matveev
Date: 2026-05-15 15:21:57Z

*** Sergey Matveev [2026-05-15 18:11]:
>Я впервые вообще читаю доки по его функам, но как-будто Alt в thread(3):
>https://9fans.github.io/plan9port/man/man3/thread.html как-раз про это.

Точнее это не про select()/poll(), а про аналог select из Go. Но если
хочется IO, то, видимо, делаешь thread (rfork?), который связан Channel-ом
будет, и в него его слать то что придёт через IO.
комментарий 5:
From: Yarik Sysoev
Date: 2026-05-15 17:21:56Z

> И его можно люто оптимизировать бы было

так а что volatile оптимизировать позволит? вот const может быть, но при
условии, что компилятор сам не может понять по содержимому функции, что
она по переданному указателю только читает...

Ок, ладно, пока это писал понял, что это важно, т.к. функция может быть
из другой единицы трансляции и поэтому не выйдет понять, безопасно ли
оставить что-то константой, если оно по адресу в неё передаётся. Так что
в Си, наверное, const оставить стоило бы. Но вот в jai от него спокойно
избавились (есть, конечно, константы этапа компиляции aka x :: 5; но это
немного про другое)

 > https://9fans.github.io/plan9port/man/man3/thread.html

Я так полагаю, что для работы alt надо создать процессы/потоки/корутины,
каждый из которых будет слушать по дескриптору? Ну, это определённо одно
из решений.
комментарий 6:
From: Sergey Matveev
Date: 2026-05-15 17:30:27Z

*** Yarik Sysoev [2026-05-15 20:21]:
>так а что volatile оптимизировать позволит?

Ну в примере (комментарии) же от kmeaw продемонстрировано. Ну точнее оно
не для оптимизаций, а для, как верно было написано, корректного кода.

>наверное, const оставить стоило бы.

Ну вот в Plan9 решили забить. А кто-то в Си внедряет ещё и restrict.
Мнений много.

>Я так полагаю, что для работы alt надо создать процессы/потоки/корутины,
>каждый из которых будет слушать по дескриптору? Ну, это определённо одно из
>решений.

Я как диванный эксперт потративший только несколько минут, увидел такую
картинку. Как там точно надо -- не знаю :-), надо их код смотреть. Но по
мне это выглядит не то что даже адекватно, но даже более правильно и красиво.