Здесь по-прежнему есть неопределённое поведение, поскольку выражение не удовлетворяет второй части того же самого требования стандартов C99 6.5:2/C++98 5:4:
Between the previous and next sequence point an object shall have its stored value modified at most once by the evaluation of an expression. Furthermore, the prior value shall be read only to determine the value to be stored.
В этой строке — неопределённое поведение, поскольку idx модифицируется дважды между точками следования. Выбор не между Div(0, 1) и Div(1, 0), а между запуском ядерных ракет и пробуждением кт-ху.
int a,b,c;
a=b=0;
c = a+++b;
printf(«Value a=%d\n», a);
В зависимости от вида компилятора либо a==1, b==0, либо a==0, b==1.
Эта программа не содержит ничего из описанного в статье и в результате её выполнения a всегда равно 1. Выражение a+++b трактуется компилятором соответствующим стандарту как (a++) + b. В С99 это описано в пункте стандарта 6.4, в С++98 — в пункте 2.4:3.
А ещё Makefile понимает параметр O=<путь к корневому каталогу сбоки> с помощью которого можно сборку вести в произвольном месте, в том числе за пределами buildroot.
как в Л действительно реализуется параметризация драйвера
существует набор макросов, которые следует использовать при создании исходного текста модуля, чтобы иметь возможность передавать ему параметры функционирования, например, адрес устройства на шине
По какой-то странной причине встречается такая ошибка у разработчиков (вот я точно по первому времени её совершал, но не помню, по какой причине) — отождествление «драйвера» и «устройства». И, соответственно, попытки параметризовать драйвер параметрами устройства. В мире, где в системе любое физическое устройство присутствует в единственном экземпляре это не имеет значения. Однако, такие драйвера имеют существенные проблемы при необходимости управялть двумя однотипными устройствами. Поэтому параметры драйвера в современных линуксах встречаются всё реже и реже, а устройства параметризуются через Device Tree, таблицы ACPI или через platform data.
Звучит как «я предпочитаю тёплое мягкому»: одних только барьеров недостаточно для реализации атомарных изменений памяти, сами по себе атомики не дают гарантий упорядочивания других обращений к памяти.
Ну и напоследок — как выделить младший бит числа (не знаю, зачем это может потребоваться, но вдруг пригодится)
define LowerBit(N) ((((N) — 1) ^ (N)) & (N)).
Для этого есть более короткая и понятная запись: #define LowerBit(N) (-(N) & (N))
ядро x86_64 запускается в файле ядра arch/x86/kernel/head_64.S, где мы найдем функцию сборки start_cpu0() и код, который явно создает стек и распаковывает zImage перед вызовом функции x86_64 start_kernel().
Всё смешалось в этом предложении. Ссылка указывает в arch/x86/boot/compressed/head_64.S, а в тексте — arch/x86/kernel/head_64.S. Это разные файлы, работающие в разное время. Первый работает сначала, он выполняет распаковку vmlinux. Он не является частью vmlinux, а добавляется в bzImage вместе с упакованным vmlinux. Второй является частью vmlinux. В нём находится код, выполняемый всеми процессорами при старте. start_cpu0 находится именно в нём.
Однако и gentoo/gentoo — это лишь зеркало. Чем зеркало gentoo лучше зеркала linux (torvalds/linux) или gcc (gcc-mirror/gcc)?
На системный ABI. Типа того.
Здесь по-прежнему есть неопределённое поведение, поскольку выражение не удовлетворяет второй части того же самого требования стандартов C99 6.5:2/C++98 5:4:
Between the previous and next sequence point an object shall have its stored value modified at most once by the evaluation of an expression. Furthermore, the prior value shall be read only to determine the value to be stored.
cppreference, конечно, популярный ресурс, но всё-таки это просто wiki в интернете. Лучше использовать стандарт.
В этой строке — неопределённое поведение, поскольку idx модифицируется дважды между точками следования. Выбор не между Div(0, 1) и Div(1, 0), а между запуском ядерных ракет и пробуждением кт-ху.
Эта программа не содержит ничего из описанного в статье и в результате её выполнения
aвсегда равно 1. Выражениеa+++bтрактуется компилятором соответствующим стандарту как(a++) + b. В С99 это описано в пункте стандарта 6.4, в С++98 — в пункте 2.4:3.А ещё Makefile понимает параметр
O=<путь к корневому каталогу сбоки>с помощью которого можно сборку вести в произвольном месте, в том числе за пределами buildroot.Я не сомневаюсь. Мой комментарий был о .
Есть варианты. Один — руками заполнить jmp_buf в InitTask. Для этого надо знать его структуру. Другой — в InitTask сделать что-то такое:
Возможно лучше сделать это через третью промежуточную функцию на ассемблере, которая только и делает, что устанавливает указатель стека.
Да ладно, на раз такая функция пишется на чистом С, без ассемблера и без фаз луны:
Мне кажется, что из этой фразы следует эквивалентность множеств целых и вещественных чисел, что, как известно, неверно.
По какой-то странной причине встречается такая ошибка у разработчиков (вот я точно по первому времени её совершал, но не помню, по какой причине) — отождествление «драйвера» и «устройства». И, соответственно, попытки параметризовать драйвер параметрами устройства. В мире, где в системе любое физическое устройство присутствует в единственном экземпляре это не имеет значения. Однако, такие драйвера имеют существенные проблемы при необходимости управялть двумя однотипными устройствами. Поэтому параметры драйвера в современных линуксах встречаются всё реже и реже, а устройства параметризуются через Device Tree, таблицы ACPI или через platform data.
Звучит как «я предпочитаю тёплое мягкому»: одних только барьеров недостаточно для реализации атомарных изменений памяти, сами по себе атомики не дают гарантий упорядочивания других обращений к памяти.
Неопределённое поведение, школьный пример.
Для этого есть более короткая и понятная запись:
#define LowerBit(N) (-(N) & (N))Можно сделать проще, командами checkout, merge и branch:
fireman — firefighter
mailman — mailfighter
fisherman — fisherfighter
garbageman — garbagefighter
snowman — snowfighter
Авторитетных?
$ git log --author='Jarkko Sakkinen' --oneline | wc -l
134
Авторитетные — это те, что сказали ему «не майся дурью».
Это же rot13.
Всё смешалось в этом предложении. Ссылка указывает в arch/x86/boot/compressed/head_64.S, а в тексте — arch/x86/kernel/head_64.S. Это разные файлы, работающие в разное время. Первый работает сначала, он выполняет распаковку vmlinux. Он не является частью vmlinux, а добавляется в bzImage вместе с упакованным vmlinux. Второй является частью vmlinux. В нём находится код, выполняемый всеми процессорами при старте. start_cpu0 находится именно в нём.