2012-02-25 2 views
8

Как (в GCC/"GNU C") вы объявляете указатель функции, который указывает на функцию __attribute__((const))? Идея заключается в том, что я хочу, чтобы компилятор избегал генерации нескольких вызовов функции, вызываемой с помощью указателя функции, когда он может кэшировать возвращаемое значение из предыдущего вызова.Функциональный указатель на функцию __attribute __ ((const))?

+0

Никогда не сделали, и почти засыпая исследования, но попробуйте оберточной вызов по адресу такой функции с явно заявленной функцией, которая имеет константный атрибут и принимает, что указатель как параметр. Если gcc может определить, что адрес указателя и аргументы не меняются, он должен устранить ненужные вызовы. –

+1

@ Vlad: Я тоже об этом подумал, но затем gcc отказывается встроить функцию в тех случаях, когда я этого хочу. Первоначально у меня была такая оберточная функция, но я удалил ее, чтобы исправить поведение inlining. В случае, если это интересно, рассматриваемой функцией является '((pthread_t (*) (void)) 0xffff0fe0)' (функция-get-thread-указатель Linux-ARM). –

+0

Интересный вопрос. Получил ли ответ Джастина желаемый результат? – Praxeolitic

ответ

3
typedef void (*t_const_function)(void) __attribute__((const)); 

static __attribute__((const)) void A(void) { 
} 

static void B(void) { 
} 

int main(int argc, const char* argv[]) { 
    t_const_function a = A; 

    // warning: initialization makes qualified 
    // function pointer from unqualified: 
    t_const_function b = B; 

    return 0; 
} 

Или просто:

__attribute__((const)) void(*a)(void) = A; 
+0

Bleh, 'typedef' всегда является решением, когда у вас есть неприятный тип указателя функции. Принято. Но любая идея, если есть способ написать бросок в моем комментарии к основному вопросу без 'typedef'? –

+0

@R. К сожалению, я не * знаю, как вставить все это в один оператор без 'typedef' - он не представляется возможным в GCC 4.2. '((__attribute __ ((const)) pthread_t (*) (void)) 0xffff0fe0)' как я думаю, это будет сделано, но оно интерпретируется иначе, чем вы хотите (появляется GCC применяет атрибут к типу возврата, а не функция). – justin

0

Хотя это не совсем ответ на ваш вопрос, вы, вероятно, хотите знать это:

Вы не можете в общем случае ожидать, что компилятор выполняет оптимизацию вы ожидаете здесь. Компилятор в общем случае не может выполнить анализ псевдонимов, чтобы знать, что несколько применений указателя функции соответствуют одной и той же функции.

Функциональный вызов между двумя вызовами функции через указатель в общем случае может изменить содержимое указателя, в результате чего вызываемая функция будет отличаться во втором вызове.

Из-за природы C, выполнение правильного анализа псевдонимов часто является трудноразрешимым, и такого рода оптимизация, вероятно, не произойдет.

+2

Это то, что делает __attribute __ ((const)) - он сообщает компилятору, что вы знаете лучше, и дает зеленый свет для определенных оптимизаций. –

+0

В моем случае это может быть известно, потому что указатель является литералом адреса (целое число, отличное от указателя функции). См. Комментарии. –

+2

@ Vlad: Я думаю, что точка Перри заключалась в том, что даже если указана функция 'const', компилятор также должен быть уверен, что указатель * не изменился между вызовами. Но это не так сложно определить, и в моем случае это невозможно, поскольку это буквальный абсолютный адрес. –