Что означает `((void (*)()) 0x1000)();` mean?
Вот код, который предназначен для установки счетчика программ для перехода на адрес 0x1000
. Я знаю, что он делает, но я не понимаю, как это сделать. Это связано с отсутствием знания языка C. Может быть, вы можете просветить меня. Вот инструкция/функция (я даже не знаю, что это такое:))
((void (*)())0x1000)();
Я считаю, что это указатель на функции, которые возвращают void
и не принимают никаких аргументов. Пожалуйста, поправьте меня, если я ошибаюсь.
Ответы
Ответ 1
C
декларации декодируются изнутри с помощью простого правила: начните с идентификатора и проверьте правильную сторону для []
(массив) или ()
(функция), затем проверьте на левой стороне тип значений (хранимых в массиве или возвращаемых функцией), не пересекая круглые скобки; выйдите из круглых скобок и повторите.
Например:
void (*p)()
p
- это (ничего справа) указатель (слева, не пересекайте круглые скобки), чтобы (бежать из круглых скобок, читать следующий уровень) функцию (справа), которая ничего не возвращает (слева).
Если идентификатор (p
в этом случае) отсутствует, все, что остается, является объявлением типа.
Тип, заключенный в круглые скобки, помещенный перед значением, является типом.
(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 */
Ответ 2
(void (*)())
- это указатель на функцию, возвращающую void
и принимающую неопределенное, но фиксированное количество аргументов.
(void (*)())0x1000
отличает литерал 0x1000
к указанному выше типу.
Наконец, суффикс ()
вызывает эту функцию. Вышеприведенное выражение должно быть в скобках, иначе суффикс ()
будет привязан к 0x1000
, который не является синтаксически действительным.
Вам нужно проверить, действительно ли кастинг действителен. Если нет, то поведение вашей программы будет undefined.
Ответ 3
Постоянная
0x1000
передается в тип:
(type)0x1000
Тип void (*)()
- указатель (звездочка) к функции, которая не принимает параметров (пустые скобки справа) (oops, см. комментарий pmg) и не возвращает значения (void
слева). Дополнительные парсеры в звездочке не связывают его с void
, что неправильно создало бы здесь тип void *
.
Итак, после актера у вас есть указатель на функцию void с параметром-меньше в addres 0x1000:
(void (*)())0x1000
И эта функция...
((void (*)())0x1000)
вызывается путем добавления пустого списка параметров:
((void (*)())0x1000)();
Ответ 4
Человек, который написал этот код, должен был переписать его читаемым образом как:
#define ADDRESS_OF_FUNCTION_X 0x1000
typedef void (*func_ptr_t)(void);
...
func_ptr_t function_x = (func_ptr_t)ADDRESS_OF_FUNCTION_X;
function_x();
То, что делает код, теперь довольно самодокументировано.