существует ли волшебная переменная в gcc содержание указателя на текущую функцию?
Я хотел бы иметь своего рода таблицу, содержащую для каждого указателя функции ряд информации.
Я знаю, что существует __ func __ переменная, содержащая название текущей функции как строка, но не как указатель функции.
Это не должно вызывать функцию затем, но только использоваться в качестве индекса.
ОТРЕДАКТИРУЙТЕ В основном, что я хотел бы сделать, способность выполнить вложенные функции непосредственно перед выполнением текущей функции (и также получение возврата для выполнения некоторых вещей.) В основном это похоже __ cyg_profile_func_enter и __ cyg_profile_func_exit (функции инструментария)... Но проблема состоит в том, что эти функции инструментария глобальны и не выделенные функции.
РЕДАКТИРОВАНИЕ В ядре Linux, можно использовать unsigned long kallsyms_lookup_name(const char *name)
от include/linux/kallsyms.h
... Обратите внимание что CONFIG_KALLSYMS
опция должна быть активирована.
Вот трюк, который получает адрес вызывающего абонента, его, вероятно, можно немного почистить. Получить значение метки можно с помощью расширения GCC GCC.
#include <stdio.h>
#define MKLABEL2(x) label ## x
#define MKLABEL(x) MKLABEL2(x)
#define CALLFOO do { MKLABEL(__LINE__): foo(&&MKLABEL(__LINE__));} while(0)
void foo(void *addr)
{
printf("Caller address %p\n", addr);
}
int main(int argc, char **argv)
{
CALLFOO;
return 0;
}
#define FUNC_ADDR (dlsym(dlopen(NULL, RTLD_NOW), __func__))
и компиляция вашей программы, как
gcc -rdynamic -o foo foo.c -ldl
Если вы пошли на C ++, следующая информация может помочь вам:
набираются объекты, Функторы функции, завернутые в виде объектов, RTTI позволяет идентифицировать тип во время выполнения.
Функторы несут накладные расходы времени выполнения, и если это проблема для вас, я бы предложил жестко кодировать знания, используя кодовое поколение или использовать oo-heirarchy функторов.
Я думаю, что вы могли бы построить свою таблицу, используя в качестве ключей строки (имена функций), а затем посмотреть вверх, сравнивая со встроенной переменной __func__
.
Для принудительного использования действительного имени функции можно использовать макрос, который получает указатель на функцию, выполняет с ней какую-нибудь фиктивную операцию (например, присваивает ее временной переменной совместимого типа функции), чтобы проверить, что это действительно действительный идентификатор функции, а затем строчит (с #) имя функции, прежде чем она будет использована в качестве ключа.
UPDATE:
Я имею в виду что-то вроде:
typedef struct {
char[MAX_FUNC_NAME_LENGTH] func_name;
//rest of the info here
} func_info;
func_info table[N_FUNCS];
#define CHECK_AND_GET_FUNC_NAME(f) ({void (*tmp)(int); tmp = f; #f})
void fill_it()
{
int i = -1;
strcpy(table[++i].func_name, CHECK_AND_GET_FUNC_NAME(foo));
strcpy(table[++i].func_name, CHECK_AND_GET_FUNC_NAME(bar));
//fill the rest
}
void lookup(char *name) {
int i = -1;
while(strcmp(name, table[++i]));
//now i points to your entry, do whatever you need
}
void foo(int arg) {
lookup(__func__);
//do something
}
void bar(int arg) {
lookup(__func__);
//do something
}
(код может нуждаться в некоторых исправлениях, я не пытался скомпилировать его, это просто чтобы проиллюстрировать идею)
.Нет, функция не знает о себе. Вам придется построить таблицу, о которой вы говорите о себе, а затем, если вы хотите, чтобы функция была в курсе самой, вам придется пройти индекс в глобальную таблицу (или указатель функции) в качестве параметра.
Примечание. Если вы хотите сделать это, у вас должна быть последовательная схема именования параметра.
Если вы хотите сделать это в «обзоре», то вам следует использовать объекты, которые вы уже упоминали ( __ Cyg_profile_Func *
), так как это то, что они предназначены для Отказ Все остальное должно быть как специальное, что и ваш профиль.
Честно говоря, делая вещи общим способом (с фильтром), вероятно, меньше, если любой новый метод, который вы вставите на лету.
Вы можете захватить эту информацию с помощью SETJMP ()
. Поскольку он экономит достаточно информации, чтобы вернуться к вашей текущей функции, она должна включать эту информацию в предоставленной JMP_BUF
.
Эта структура очень неотступна, но вы явно упоминаете GCC, так что это, вероятно, не проблема блокировки. См. Это пример GCC / X86 , чтобы понять, как он примерно работает.
Ответ, данный моим Мэдхупом, является правильным ответом. UITableViewController является подклассом UIViewController, поэтому добавление метода viewDidLoad в UITableViewController работает отлично.
-121--3759087- Если вы не против специфичности для платформы, можно использовать system ()
call:
system("del index*.txt"); // DOS
system("rm index*.txt"); // unix
Вот некоторая документация по вызову system ()
, который является частью стандартной библиотеки C (cstdlib).
Если вы хотите создать код, я бы рекомендовал GSLGen от Imatix. Он использует XML для структурирования модели вашего кода, а затем простой PHP, такой как язык генерации сверху вниз, чтобы выплюнуть код - он был использован для генерации кода C.
Я лично крутился с lua, чтобы генерировать код.
Другой вариант, если переносимость не проблема, будет Настроить исходный код GCC ... Любые волонтеры?!
Если вам нужен только уникальный идентификатор для каждой функции, то в начале каждой функции поставьте следующее:
static const void * const cookie = &cookie;
Значение cookie
гарантированно будет значением, уникально идентифицирующим эту функцию.