Intereting Posts
c и object-c-const char * и char * # Определить область видимости в библиотеке? Переменная, объявленная и инициализируемая в инструкции switch SWIG возвращает returntype из String как массив String в java Проверьте, заблокирован или разблокирован мьютекс pthread (после того, как stream заблокирован) Возможно ли создать тип данных длиной один бит в C Препроцессор C: расширение макроса в #warning Внесение меркурийных изменений в качестве информации о версии в исполняемом файле C узнать версию libjpeg во время выполнения (или другие способы предотвращения прерываний)? добавление двух связанных списков эффективно в C При передаче массива int в короткий *, почему присвоение значения элементу переписывает целое целое число? Динамическое распределение памяти для массивов указателей Самая быстрая реализация для проблемы с парными краткими путями? Моделирование булевых в Bison с C Лучше ли программирование на основе сетевых событий …?

Что означает `((void (*) ()) 0x1000) ();` mean?

Вот код, который предназначен для установки счетчика программ для перехода на адрес 0x1000 . Я знаю, что он делает, но я не понимаю, как это сделать. Это связано с отсутствием знания языка C. Может быть, вы можете просветить меня. Вот инструкция / функция (я даже не знаю, что это такое :))

 ((void (*)())0x1000)(); 

Я считаю, что это указатель на функции, которые возвращают void и не принимают никаких аргументов. Пожалуйста, поправьте меня, если я ошибаюсь.

Объявления 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 */ 

(void (*)()) является указателем на функцию, возвращающую void и принимающей неопределенное, но фиксированное количество аргументов.

(void (*)())0x1000 отличает литерал 0x1000 к вышеуказанному типу.

Наконец, суффикс () вызовы, которые функционируют. Вышеприведенное выражение должно быть в скобках, иначе суффикс () будет привязан к 0x1000 который не является синтаксически действительным.

Вам решать проверить, действительно ли кастинг. Если нет, то поведение вашей программы не определено .

Постоянная

 0x1000 

получает бросок к типу:

 (type)0x1000 

Тип void (*)() – указатель (звездочка) к функции, которая не принимает параметров (пустые скобки справа) (oops, см. Комментарий pmg ) и не возвращает значения ( void слева). Дополнительные парнеры в звездочке не позволяют связать его с void , что неправильно создало бы здесь тип void * .

Итак, после актера у вас есть указатель на функцию с нечеткой параметром в addres 0x1000:

 (void (*)())0x1000 

И эта функция …

 ((void (*)())0x1000) 

вызывается путем добавления пустого списка параметров:

 ((void (*)())0x1000)(); 

Человек, который написал этот код, должен был переписать его читаемым образом:

 #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(); 

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