LINUX.ORG.RU

Linux перейдёт на использование стандарта C11 в версии 5.18 или одной из следующих

 , ,


1

1

Во время обсуждения набора патчей, связанных с исправлением уязвимостей класса Spectre в коде для работы со связанными списками, стало ясно, что проблему удалось бы решить более изящно, если бы в ядро допускался код, использующий стандарт старше C89. Сейчас код в ядре должен соответствовать С89 (с GNU расширениями) на основе спецификации, сформированной ещё в 1989 году. Связанная со Spectre проблема была в том, что для перебора элементов списка используется макрос. Так как переменная цикла передаётся в этот макрос, то она определяется вне самого цикла и остаётся доступна после цикла. Использование более новых стандартов языка C позволит определять переменные для цикла прямо в блоке for.

В связи с этим, Линус Торвальдс предложил попробовать перейти в ядре 5.18 на стандарт C99, который был опубликован в 1999 году, на что получил встречное предложение перейти сразу на C11. При проверке сборки в GCC и Clang с новым стандартом проблем пока не возникло и, если при более тщательном тестировании ситуация не изменится, в сборочных скриптах ядра 5.18 опция --std=gnu89 будет заменена на --std=gnu11 -Wno-shift-negative-value.

В случае неудачи, переход будет отложен на один из следующих выпусков.

>>> Подробности



Проверено: xaizek ()
Последнее исправление: maxcom (всего исправлений: 5)
Ответ на: комментарий от anonymous

@#%^ь. Настолько мощного подкола в ответе я не ожидал. :-D

dimgel ★★★★★
()

Что может быть тупее чем требование объявлять счётчик цикла в начале блока кода, когда цикл в конце? Но линуксоидам и так сойдёт.

anonymous
()

Я сам был в культурном шоке, когда узнал, что разрабы ядра до сих пор махают каменными топорами с совершенно невозмутимым видом, мол «надежно и проверено временем».

byko3y ★★★★
()

Так как переменная цикла передаётся в этот макрос, то она определяется вне самого цикла и остаётся доступна после цикла. Использование более новых стандартов языка C позволит определять переменные для цикла прямо в блоке for.

Ну и зря. Будет грязный код. Я даже объявлять переменные где-то кроме начала функций (именно функций а не любых блоков {}) избегаю, хотя это разрешено в C89. Объявления локальных переменных это считай описатель внутреннего стека функции, этот стек на всю функцию единый и должен быть прозрачно указан в одном месте а не раскидан по разным местам.

firkax ★★★★★
()
Ответ на: комментарий от anonymous

Потому что объявляется не счётчик цикла, а резервирование места под него в стеке функции, что есть однозначно свойство функции а не цикла. Это си а не пхп.

firkax ★★★★★
()

Spectre

А что там по новым процессорам? Уже пофикшено или всё ещё штампуют с уязвимостями Spectre и остальными?

th3m3 ★★★★★
()
Ответ на: комментарий от anonymous

Товарищ. Вы выражаетесь не политкорректно. В вашей фразе следует слово «Rust» заменить на слово «Python»...

drfaust ★★★★★
()
Ответ на: комментарий от byko3y

Я сам был в культурном шоке, когда узнал, что разрабы ядра до сих пор махают каменными топорами с совершенно невозмутимым видом, мол «надежно и проверено временем».

это всего лишь доказывает, что нормальным разрабам и 30 летний стандарт не мешает.

crypt ★★★★★
()

Новость про АНБшный бэкдор Bvp47 в ядре Линукса будет?

anonymous
()
Ответ на: комментарий от firkax

А как же контекст? Как же скопы? Цикл это скоп и в нём свои локальные переменные. Ты же не объявляешь всё переменные в начале программы?

AVL2 ★★★★★
()
Ответ на: комментарий от dimgel

для этого надо минимальную версию гцц поднимать.

Thero ★★★★★
()
Ответ на: комментарий от crypt

это всего лишь доказывает, что нормальным разрабам и 30 летний стандарт не мешает

Если не читать ОП, то конечно, можно считать что им не мешает.

anonymous
()
Ответ на: комментарий от AVL2

Скопы это хорошо, но не надо перегибать и чрезмерно отходить от реализма.

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

Во-вторых. Да, я тоже иногда пользуюсь этим «приёмом» и ограничиваю область видимости переменных с помощью { } вокруг них (когда писать их в общий список будет ну совсем некрасиво), но почти всегда это костыли, и такой блок с собственными переменными следует выделять в отдельную функцию (у которой уже полноценно свои локальные переменные). О том, чтобы заниматься этим ради одной переменной цикла, речи конечно не идёт.

А ещё - вообще чётко отделять декларативную и императивную части описания функции хорошая идея. По той же причине избегаю конструкций вида int a = 1; - пишу int a; и уже под всеми переменными a = 1; Ещё хуже когда там не константа (единица) а какое-то вычисляемое выражение с вызовом других функций.

firkax ★★★★★
()
Ответ на: комментарий от crypt

нормальным разрабам и 30 летний стандарт

gnu89 ни разу не 30-летний

даже gcc-шный -std=c89 не 30-летний

-std=c89 -pedantic -Werror - возможно, но и то не уверен

firkax ★★★★★
()
Ответ на: комментарий от firkax

я по твоим коммента (про бзд) «не нужно», «вы все неправильно делаете» и незнанию банальных вещей решил, что ты школьник. а так, выходит, ты только в администрировании не понимаешь и даже какой-то код пишешь? или это тоже не по работе?

crypt ★★★★★
()
Последнее исправление: crypt (всего исправлений: 3)
Ответ на: комментарий от Crocodoom

C11 это всё ещё каменный топор кстати

В вводных книгах по C пишут, что одним из плюсов является простота написания компилятора под разные платформы.

Кто в курсе развития языка C, с новыми стандартами реализация компилятора усложняется (предполагая, что писать приходится с нуля), остаётся прежней или м.б., напротив, упрощается? В чём там вообще заключается развитие: добавляют новые фичи (усложняющие реализацию) или выбрасывают бородавки?

anonymous
()
Ответ на: комментарий от crypt

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

firkax ★★★★★
()
Ответ на: комментарий от Ford_Focus

да, думаю, как ты говоришь - это точнее.

crypt ★★★★★
()
Ответ на: комментарий от firkax

Так много слов написал.

Скопы это хорошо, но не надо перегибать и чрезмерно отходить от реализма.

Подобные искусственные сущности в си выглядят неуместно.

Это твои аргументы против? Какая-то лютая субъективщина.

По той же причине избегаю конструкций вида int a = 1; - пишу int a; и уже под всеми переменными a = 1;

Ты наверное и так ни при каких условиях не пишешь?

char str[STR_SIZE] = {0};

Пишешь под микроконтроллеры?

anonymous
()

Насколько в ядре важны именно GNU расширения?

Почему -std=gnu11, а не обычный -std=c11?

Отказ от GNU-расширений позволил бы собираться ядру многими компиляторами, а не только GCC.

EXL ★★★★★
()
Ответ на: комментарий от EXL

Важны. Без расширений даже кернельный max() превращается в тыкву. Без typeof - многие макросы. Без кучи атрибутов теряется куча предупреждений и оптимизаций. Стандартный си на что-то серьезное не годен.

anonymous
()
Ответ на: комментарий от byko3y

Вот где настоящие ретрограды:

Does Wine allow C++, Objective C, or other code?

Wine is written entirely in C. No C++ code is allowed. Furthermore, C code must be recognizable by all sane compilers, including notably the Microsoft Visual C compiler. In practice this means code must conform to C89, with some C99 features allowed. To be somewhat more specific, we allow inline functions, variadic macros, and designated initializers, but not variable-length arrays or mixed declarations and code. We also do not use C++ comments (i.e. those beginning with //).

https://wiki.winehq.org/Developer_FAQ

X512 ★★★★★
()
Ответ на: комментарий от anonymous

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

anonymous
()
Ответ на: комментарий от firkax

Во-первых, «локальные переменные цикла» это на самом деле локальные переменные функции (технически), просто с искусственно ограниченной областью видимости.

Нет. Память (стек, регистры) под них может выделяться в начале цикла и освобождаться в конце.

X512 ★★★★★
()
Ответ на: комментарий от anonymous

Это твои аргументы против? Какая-то лютая субъективщина.

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

Ты наверное и так ни при каких условиях не пишешь?

Если речь про локальные стековые переменные, то в коде, позиционируемом как прод - не пишу. Для глобальных и для «локальных» static - пишу конечно, там эта конструкция имеет совсем другой, и весьма полезный смысл. В этом и проблема: оно выглядит как преинициализированная переменная, и если в случае глобальной переменной - так и есть, то для локальной это только синтаксическая обёртка к «char str[STR_SIZE]; str[0] = 0; memset(str+1, 0, STR_SIZE-1);»

Хороший современный компилятор наверно оптимизирует нелепое отдельное присваивание, включив его в memset, а вот в бинарниках скомпилированных старыми, я кучу раз видел эту фигню, в начале удивлялся что за странные люди их писали (исходников нет), а потом понял откуда это взялось. Но даже в оптимизированном виде - это всё равно объявление + отдельные процессорные инструкции для заполнения нулями, так пусть они явно будут указаны. Да и тут точно надо всю строку нулями заполнять, может достаточно только первый байт? Если пишешь явно - всё сам и решишь.

firkax ★★★★★
()
Ответ на: комментарий от anonymous

В вводных книгах по C пишут, что одним из плюсов является простота написания компилятора под разные платформы.

Что характерно ни одного актуального компилятора Си на Си больше нет. На практике нужен не просто компилятор, а оптимизирующий. А его на голом Си писать крайне затруднительно.

X512 ★★★★★
()

По теме, команде разрабов ядра надо было бы засесть и сделать новый язык на основе C. С учетом ошибок, проклятий Линуса и войн в багтрекере gcc. Собственно, C делали такие же ядерщики, только слишком давно, и не имея сопоставимого опыта.

anonymous
()
Ответ на: комментарий от EXL

gnu11 это не только gcc. Даже упёртые, молящиеся на С-комитет, авторы clang-а поняли что надо в целом поддерживать и этот (gnu) стандарт, иначе их компилятор был бы почти никому не нужен.

firkax ★★★★★
()
Ответ на: комментарий от X512

Нет. Память (стек, регистры) под них может выделяться в начале цикла и освобождаться в конце.

Выделяться-освобождаться? ESP каждый цикл вверх-вниз гуляет чтобы место переменным добавить? Сомневаюсь. Не говоря уже о том, что «освободить регистр» это вообще что-то немыслимое.

Может быть, ты имел ввиду что один и тот же регистр или место в памяти может по очереди использоваться разными переменными? Так это никак с скопами не связано. С регистрами динамическое их использвание было с давних времён, с памятью - не совсем с давних, но суть в том, что если компилятор видит, что области использования двух переменных не пересекаются, он может назначить им одно и тоже место в стеке. Не говоря уж о том, что одна переменная может «гулять» из памяти в регистр и обратно в память по ходу выполнения.

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

firkax ★★★★★
()
Ответ на: комментарий от X512

На практике нужен не просто компилятор, а оптимизирующий. А его на голом Си писать крайне затруднительно.

Статистика по всего двум-трём компиляторам (а больше и нету) не особо достоверная чтобы делать такие выводы. Я думаю что скорее всего в команды разработки просто проникли С++-ники и захотели писать на нём.

firkax ★★★★★
()
Ответ на: комментарий от firkax

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

TCC вроде так и делает.

X512 ★★★★★
()
Ответ на: комментарий от firkax

то для локальной это только синтаксическая обёртка к … memset

Ты в этом уверен? Это зависит от компилятора и в данном случае твое

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

Уже теряет актуальность, если она там была. И ты говоришь синтаксическая обёртка так, будто это что-то плохое, когда плохое это или нет зависит от контекста.

Так я угадал, что ты пишешь под микроконтроллеры или нет?

anonymous
()
Ответ на: комментарий от firkax

Ты не допускаешь более динамическое использование стека?

void foo() { //# push bp; mov bp, sp;
	int a, b, c; //# sub sp, 12;
	
	if(1) {
		int d, e, f; //# sub sp, 12;
		...
		//# add sp, 12;
	};

	if(1) {
		int g, h, i; //# sub sp, 12;
		...
		//# add sp, 12;
	};
}

Ихмо объявлять все переменных в начале функции чтобы якобы видеть сколько стека она сожрет это путь к ошибкам. А подобное видение мне ни разу не пригождалось даже на мк.

bga_ ★★★★
()
Ответ на: комментарий от firkax

Я думаю что скорее всего в команды разработки просто проникли С++-ники и захотели писать на нём.

Они там давно были потому что отдельный компилятор Си обычно не делают, делают общий компилятор для C и C++. Си – это по сути урезанный C++.

X512 ★★★★★
()

А более свежего, чем C11, нет? Хотя, в принципе, лично мне дальше C99 нифига и не нужно было никогда. А уж динамические массивы на стеке, а не куче — вообще зло. Разве что, классная штука — возможность инициализировать элементы массива по индексам.

anonymous
()

C11

Вопрос к знающим людям. Кто пользуется atomic types в C? Годно? Плюсы/минусы?

anonymous
()
Ответ на: комментарий от anonymous

Очень годно! Раньше приходилось извращаться с мьютексами, а теперь для надежного изменения переменных в многопоточных приложениях все намного проще стало!

anonymous
()
Ответ на: комментарий от anonymous

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

anonymous
()
Ответ на: комментарий от anonymous

Народ очень инертный. Я вот знаю одного программиста, который почти в духе K&R пишет. Да еще и любит однофайловые приложения делать (по паре сотен тысяч строк в одном файле!).

anonymous
()
Ответ на: комментарий от anonymous

Чё-то я сам спросил, сам попробую ответить :) С год назад гуглил этот свой вопрос и не нагуглил, сейчас загуглил и сразу нашел такое (2015 год):

https://lwn.net/Articles/691128/

Там еще есть ссылки. Сам полностью прочту позже, но вроде бы любопытно.

anonymous
()
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.