С учетом следующего кода:
unsigned int global_flag = 0;
void exception_handle()
{
global_flag = 1;
}
void func()
{
/* access will cause exception which will assign global_flag = 1
then execution continues */
volatile unsigned int x = *(unsigned int *)(0x60000000U); /* memory protection unit configured to raise exception upon accessing this address */
if (global_flag == 1)
{
/* some code */
}
}
Учитывая тот факт, что volatile
нельзя переупорядочивать по точкам последовательности :
Минимальное требование заключается в том, чтобы в точке последовательности все предыдущие
доступ к летучим объектам стабилизировался, и никаких последующих
доступы произошли
И учитывая следующее о точках последовательности :
Точки последовательности встречаются в следующих местах ... (1) .. (2) .. (3) В конце полного выражения . Эта категория включает в себя выражение
операторы (такие как присваивание a = b ;), операторы возврата,
управляющие выражения if , операторы switch, while или do-while,
и все три выражения в выражении for.
Обещано ли, что volatile unsigned int x = *(unsigned int *)(0x60000000U);
будет иметь место до if (global_flag == 1)
(в двоичном ассмблере выполнение CPU не по порядку здесь не актуально)?
Согласно приведенным выше цитатам, volatile unsigned int x = *(unsigned int *)(0x60000000U);
должен быть оценен до конца следующей точки последовательности, а volatile unsigned int x = *(unsigned int *)(0x60000000U);
является самой точкой последовательности, поэтому это означает, что каждое назначение volatile
оценивается во время назначения
Если ответ на поставленный выше вопрос - нет, то следующая точка последовательности находится на конце if
, означает ли это, что может быть выполнено что-то подобное:
if (global_flag == 1)
{
volatile unsigned int x = *(unsigned int *)(0x60000000U);
/* some code */
}
Система представляет собой встроенную одноядерную кору m0, одноядерное, однопоточное приложение.