C
заявления декодируются изнутри с помощью си mple rule: начните с идентификатора и проверьте правильную сторону для []
(массив) или ()
(функция), затем проверьте на левой стороне тип значений (хранящихся в массиве или возвращенных функцией), не пересекая круглые скобки; вырваться из круглых скобок и повторить.
Например:
void (*p)()
p
не (ничего справа) указатель (на левой стороне, не пересекаются круглые скобки) в (побег скобки, читайте следующий уровень) a функция (справа) , которая ничего не возвращает (слева).
Если идентификатор (в этом случае отсутствует) отсутствует, все, что остается, является объявлением типа.
Тип, заключенный в круглые скобки, помещаемый перед значением, является типом.
(void (*)())0x1000
преобразует число 0x1000
в указатель на функцию, которая ничего не возвращает (посмотреть, что за пределами скобок в пункте о декларации p
выше).
На следующем уровне выражение, приведенное выше (указатель на функцию может использоваться так же, как имя функции), используется для выполнения указанного кода.
Ниже все выражение де-составе:
(
(
void (*)() /* type: pointer to function that doesn't return anything */
)0x1000 /* value 0x1000 treated as a value of the type declared above */
) /* enclose in parentheses to specify the order of evaluation */
(); /* the pointer above used as a function name to run the code */
Что такое платформа и процессор, где вы будете запускать этот код? –
Эта инструкция может использоваться, если попытаться вызвать процедуру с известным фиксированным адресом, т. Е. процедура BIOS. В старой IBM PC вы можете называть '(void (* far)()) 0xFFFFFFF0ul'. Эта процедура перезапускает ПК. –
Я чувствую, что это имеет побочный смысл «F ** k you», когда вы находите его в коде, который вы должны поддерживать. Опять же, как не-C-dev, все C выглядят как непостижимый беспорядок для меня, поэтому я вполне мог ошибиться. –