sirven que punteros puntero parametros para operaciones los funciones ejemplos con como cadenas aritmetica c function-pointers

que - punteros como parametros de funciones en c



¿Determinar a qué función apunta un puntero en C? (9)

Tengo un puntero para funcionar, supongo que cualquier firma. Y tengo 5 funciones diferentes con la misma firma.

En tiempo de ejecución, uno de ellos se asigna al puntero y se llama a esa función.

Sin insertar ninguna declaración de impresión en esas funciones, ¿cómo puedo llegar a conocer el nombre de la función a la que apunta actualmente el puntero?


  1. configura tu enlazador para generar un archivo MAP.
  2. pausa el programa
  3. inspeccionar la dirección contenida en el puntero.
  4. busque la dirección en el archivo MAP para averiguar a qué función se apunta.

Deberá verificar a cuál de sus 5 funciones apunta su puntero:

if (func_ptr == my_function1) { puts("func_ptr points to my_function1"); } else if (func_ptr == my_function2) { puts("func_ptr points to my_function2"); } else if (func_ptr == my_function3) { puts("func_ptr points to my_function3"); } ...

Si este es un patrón común que necesita, use una tabla de estructuras en lugar de un puntero de función:

typedef void (*my_func)(int); struct Function { my_func func; const char *func_name; }; #define FUNC_ENTRY(function) {function, #function} const Function func_table[] = { FUNC_ENTRY(function1), FUNC_ENTRY(function2), FUNC_ENTRY(function3), FUNC_ENTRY(function4), FUNC_ENTRY(function5) } struct Function *func = &func_table[3]; //instead of func_ptr = function4; printf("Calling function %s/n", func->func_name); func ->func(44); //instead of func_ptr(44);


El depurador podría decirle eso (es decir, el nombre de una función, dada su dirección).

La tabla de símbolos de un ejecutable ELF sin ELF también podría ayudar. Ver nm(1) , objdump(1) , readelf(1)

Otro enfoque específico de Linux GNU / libc podría ser usar en tiempo de ejecución la función dladdr(3) . Suponiendo que su programa está bien y dinámicamente vinculado (por ejemplo, con -rdynamic ), puede encontrar el nombre del símbolo y la ruta del objeto compartido dada alguna dirección (de una función con nombre global).

Por supuesto, si solo tiene cinco funciones de una firma determinada, puede comparar su dirección (con las cinco direcciones de ellas).

Tenga en cuenta que algunas funciones no tienen ningún nombre ((globalmente visible), por ejemplo, funciones static .

Y algunas funciones pueden ser dlopen -ed y dlsym -ed (por ejemplo, dentro de complementos). O su código puede ser sintetizado en tiempo de ejecución por algún marco JIT-ing ( libjit , gccjit , LLVM , asmjit ). Y el compilador de optimización puede (¡y lo hace!) Funciones en línea, clonarlas, tail-call , etc., por lo que su pregunta podría no tener ningún sentido en general ...

Ver también backtrace(3) y libbacktrace Ian Taylor dentro de GCC.

Pero en general, tu búsqueda es imposible. Si realmente necesita dicha información reflexiva de manera confiable, adminístrela usted mismo (mire el sistema CAIA de Pitrat como ejemplo, o de alguna manera mi sistema MELT ), tal vez generando algo de código durante la compilación.


En absoluto: el nombre simbólico de la función desaparece después de la compilación. A diferencia de un lenguaje reflexivo, C no sabe cómo sus elementos de sintaxis fueron nombrados por el programador; especialmente, no hay "búsqueda de funciones" por nombre después de la compilación.

Por supuesto, puede tener una "base de datos" (por ejemplo, una matriz) de punteros de función con los que puede comparar su puntero actual.


Esto es completamente horrible y no portátil, pero suponiendo:

  1. Estás en Linux o algún sistema similar basado en ELF.
  2. Estás utilizando enlaces dinámicos.
  3. La función está en una biblioteca compartida o usó -rdynamic al vincular.
  4. Probablemente muchas otras suposiciones que no deberías hacer ...

Puede obtener el nombre de una función pasando su dirección a la función dladdr(3) no estándar.


Generalmente, en C tales cosas no están disponibles para el programador.

Puede haber formas específicas de llegar al sistema utilizando símbolos de depuración, etc., pero probablemente no desee depender de la presencia de estos para que el programa funcione normalmente.

Pero, por supuesto, puede comparar el valor del puntero con otro valor, p. Ej.

if (ptr_to_function == some_function) printf("Function pointer now points to some_function!/n");


Los nombres de las funciones no estarán disponibles en tiempo de ejecución.

C no es un lenguaje reflexivo .

Mantenga una tabla de punteros de función marcados por su nombre o proporcione un modo de llamar a cada función que devuelva el nombre.


Para saber dónde apunta un puntero de función es algo que tendrá que seguir con su programa. Lo más común es declarar una matriz de punteros de función y usar una variable int como índice de esta matriz.

Dicho esto, hoy en día también es posible saber en tiempo de ejecución qué función se ejecuta actualmente, utilizando el identificador __func__ :

#include <stdio.h> typedef const char* func_t (void); const char* foo (void) { // do foo stuff return __func__; } const char* bar (void) { // do bar stuff return __func__; } int main (void) { func_t* fptr; fptr = foo; printf("%s executed/n", fptr()); fptr = bar; printf("%s executed/n", fptr()); return 0; }

Salida:

foo executed bar executed


Un puntero a una función C es una dirección, como cualquier puntero. Puede obtener el valor de un depurador. Puede lanzar el puntero a cualquier tipo de entero con suficientes bits para expresarlo completamente e imprimirlo. Cualquier unidad de compilación que pueda usar el puntero, es decir, que tenga el nombre de la función dentro del alcance, puede imprimir los valores del puntero o compararlos con una variable de tiempo de ejecución, sin tocar nada dentro de las funciones mismas.