Какие доступны расширения GNU C, которые нетривиально реализовать в C99?
Почему ядро Linux может компилироваться только с GCC? Какие расширения GNU C действительно необходимы для некоторых проектов и почему?
5 ответов
В этой статье описываются используемые расширения: GCC-хаки в ядре Linux. Некоторые из них тривиальны, некоторые нет (в основном это приемы оптимизации).
Вот пара расширений gcc, которые использует ядро Linux:
- встроенная сборка
- встроенные функции gcc, такие как __builtin_expect,__builtin_constant, __buildin_return_address
- атрибуты функции для указания, например, какие регистры использовать (например, __attribute__((regparm(0)),__ атрибут __ ((упакованный, выровненный (PAGE_SIZE)))))
- конкретный код в зависимости от предопределенных макросов gcc (например, обходные пути для определенных ошибок gcc в определенных версиях)
- диапазоны в случаях переключения (случай 8 ... 15:)
Вот еще несколько: http://www.ibm.com/developerworks/linux/library/l-gcc-hacks/
Многие из этих спецификаций gcc сильно зависят от архитектуры или становятся возможными из-за того, как реализован gcc, и, вероятно, не имеют смысла указываться стандартом Си. Другие просто удобные расширения для C. Поскольку ядро Linux построено так, чтобы полагаться на эти расширения, другие компиляторы должны предоставлять те же расширения, что и gcc, чтобы иметь возможность собирать ядро.
Дело не в том, что Linux должен был полагаться на эти функции gcc, например, ядро NetBSD очень мало полагается на специфичные для gcc вещи.
GCC поддерживает вложенные функции, которые не являются частью стандарта C99. Тем не менее, необходим некоторый анализ, чтобы увидеть, насколько они распространены в ядре Linux.
Ядро Linux было написано для компиляции GCC, поэтому стандартное соответствие никогда не было целью разработчиков ядра.
И если GCC предлагает несколько полезных расширений, которые облегчают кодирование, или скомпилированное ядро становится меньше или быстрее, то было естественным выбором использовать эти расширения.
Я предполагаю, что это не они действительно так необходимы. Просто есть много полезных, и переносимость кросс-компиляторами - не такая уж большая проблема для ядра Linux, чтобы отказаться от тонкостей. Не говоря уже об огромном объеме работы, который потребуется, чтобы избавиться от зависимости от расширений.