Можно ли получить имя функции, не вызывая его? - PullRequest
4 голосов
/ 21 сентября 2019

Как я могу получить имя функции, не вызывая и не вызывая ее, или это вообще возможно?

У меня есть массив функций сортировки, моя цель состоит в том, чтобы иметь возможность перечислить имя каждой из них,динамически, без необходимости вызывать любой.После поиска в Интернете я не смог найти ни одного решения, которое бы не требовало вызова функции и использует __FUNCTION__ или __func__.

Массив используемых функций:

// Pointer to functions
char *(*srtFunc[])(int *, int) = {selection, bubble, recursiveBubble, insertion, recursiveInsertion};

Дополнительная информация о том, чего я хочу достичь с помощью этого:

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

Ответы [ 2 ]

3 голосов
/ 21 сентября 2019

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

#define ARRAY_SIZE(A) (sizeof(A)/sizeof(A[0]))

// Pointer to functions
    char *(*srtFunc[])(int *, int) = {selection, bubble, recursiveBubble, insertion, recursiveInsertion};
    const char *srtFuncNames[] = {"selection", "bubble", "recursiveBubble", "insertion", "recursiveInsertion"};
    _Static_assert(ARRAY_SIZE(srtFuncNames)==ARRAY_SIZE(srtFunc), "Function table and names out of synch!");

Наличие двух определений сразу после друг друга облегчаетсинхронизируйте их, и код легко читается._Static_assert (доступно из C11) поможет запомнить новые имена при добавлении новых функций.

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

typedef struct
{
    char *(*srtFunc)(int *, int);
    const char *srtName;
} sortMethod;

#define SORT_METHOD(S) {(S), #S}

sortMethod methods[] = {
    SORT_METHOD(selection),
    SORT_METHOD(bubble),
    SORT_METHOD(recursiveBubble),
    SORT_METHOD(insertion),
    SORT_METHOD(recursiveInsertion)
};
3 голосов
/ 21 сентября 2019

К сожалению, не легко.C не создан для самоанализа и не имеет таких функций, как это: имя функции foo и вызов функции foo скомпилированы донекоторые инструкции перехода и вызова в выходных данных;Фактическое имя "foo" по сути удобнее для вас при программировании и исчезает в скомпилированном выводе.

Макрос __FUNCTION__ является макросом препроцессора - и, как вы заметили, он работает только внутри функции, потому чтовсе, что он делает, это говорит препроцессору (как его перетаскивание по тексту): эй, пока вы сканируете этот токен, просто добавьте имя функции, которую вы сейчас сканируете, и продолжайте.Он очень «тупой» и находится выше по потоку даже от компилятора.

Существуют различные способы получить эффективный результат, который вы хотите получить, в том числе простое ручное построение таблицы строковых литералов с такими же именами, как у вас.функции.Вы можете сделать это довольно чистыми способами (см. Ответ @ nielsen для получения полезного фрагмента), используя макросы.Но препроцессор / компилятор не может помочь вам извлечь или применить таблицу из фактических функций, поэтому у вас всегда будет некоторый риск возникновения проблемы во время выполнения, когда вы будете вносить в нее изменения.К сожалению, у C просто нет возможности для элегантности, которую вы ищете в этом дизайне.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...