Что означает `((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();

То, что делает код, теперь довольно самодокументировано.