vectores punteros puntero matrices lenguaje funciones declaracion con aritmetica c function-pointers const-correctness

punteros - ¿Qué es el significado de un puntero a una función constante?



punteros y matrices en c (6)

Los punteros se pueden declarar apuntando a datos mutables (no constantes) o punteros a datos constantes.
Los punteros se pueden definir para apuntar a una función.

Mis compañeros de trabajo y yo discutíamos el uso de "const" con punteros y surgió la pregunta sobre el uso de const con punteros de función.

Aquí hay algunas preguntas:

  1. ¿Cuál es el significado de un puntero a una función constante frente a un puntero a una función no constante?
  2. ¿Puede una función ser const?
  3. ¿Puede una función ser no constante (mutable)?
  4. ¿Cuál es la sintaxis correcta (segura) para pasar un puntero a función?

Edición 1: Función de sintaxis de puntero.

typedef void (*Function_Pointer)(void); // Pointer to void function returning void. void function_a(Function_Pointer p_func); // Example 1. void function_b(const Function_Pointer p_func); // Example 2. void function_c(Function_Pointer const p_func); // Example 3. void function_d(const Function_Pointer const p_func); // Example 4.

Las declaraciones anteriores son ejemplos de cómo tratar un puntero de función como un puntero a un tipo intrínseco.

Un indicador de datos, variables o memoria permite las combinaciones anteriores.
Entonces, las preguntas son: ¿puede un puntero de función tener las mismas combinaciones y qué significa un puntero a una función const (como el Ejemplo 2)?


1. ¿Cuál es el significado de un puntero a una función constante frente a un puntero a una función no constante?

No hay diferencia entre const y non-const: la función en sí misma no es modificable

Nota: En C ++, si la función es una función miembro de una clase, const significa que el estado del objeto dentro de esta función no se puede cambiar (se asignan variables miembro, se llaman funciones non-const memeber). En este caso, la palabra clave const es parte de la firma de la función miembro y, por lo tanto, hace una diferencia en términos del puntero.

2. ¿Puede una función ser constante?

Véase más arriba.

3. ¿Puede una función ser no constante (mutable)?

Véase más arriba

4. ¿Cuál es la sintaxis correcta (segura) para pasar un puntero de función?

Todos los punteros a las funciones libres se pueden convertir a cualquier otro puntero a la función libre (es decir, su tamaño es el mismo). Así que podrías definir un tipo para una función (hipotética): void f(); y convertir todos los punteros de función a este tipo para almacenar. Tenga en cuenta que no debe llamar a la función a través de este tipo común: necesita convertirla en su tipo de puntero a función original, de lo contrario, tendrá un comportamiento indefinido (y probablemente un fallo)

Para C ++: no se garantiza que los punteros a funciones miembro sean convertibles a punteros a funciones libres


1. No hay un lugar sintáctico donde colocar ''const'' para hacer que el contenido de una función sea constante.

Se encontrará con un error de ''la función no es un valor l'', independientemente de si tiene const o no.

typedef void (* FUNC)(void); FUNC pFunc; pFunc = 0; // OK *pFunc = 0; // error: Cannot assign to a function (a function is not an l-value) typedef void (* const FUNC)(void); FUNC pFunc; pFunc = 0; // error (const) *pFunc = 0; // error: Cannot assign to a function (a function is not an l-value) typedef void (const * FUNC)(void); // error: <cv-qualifier> (lol?)

2 y 3. Punteros de función: sí. Contenido de la función, no parece.

4. No creo que haya ninguna manera de hacer más seguro pasar un puntero de función. Con todas las constantes del mundo, lo único que puede proteger es que ''SetCallback'' no puede cambiar su propia copia local del parámetro.

typedef void (* const FUNC)(void); void SetCallback(const FUNC const pCallback) { FUNC pTemp = pCallback; // OK (even though pTemp is not const!!) pCallback = 0; // error (const) }


Bajo C, no hay tal cosa como una función const . const es un calificador de tipo, por lo que solo se puede usar para calificar un tipo, no una función. ¿Quizás te refieres a un puntero constante a una función o un puntero no constante a una función?

En C ++, los métodos pueden ser const . Si un método es const , significa que después de llamar a ese método, el objeto que contiene el método estará en el mismo estado que antes de llamar al método (ninguna de las variables de instancia [1] se ha modificado). Por lo tanto, puede apuntar a un método const y un método no const, y esos métodos son diferentes.

Puede aceptar un puntero de función en una lista de argumentos como retType (*variableName)(arguments) .

[1] A menos que sean mutable .


De acuerdo con la especificación C ( C99 , sección 6.7.3):

Las propiedades asociadas con tipos calificados son significativas solo para expresiones que son valores l.

Cuando la especificación dice "tipos calificados", significa cosas definidas con la palabra clave const , restrict o volatile . Las funciones de Snice no son lvalues, la palabra clave const en una función no es significativa. Usted puede estar mirando a algún tipo de extensión específica del compilador. Algunos compiladores lanzarán un error si intentas declarar una función como const .

¿Está seguro de que está viendo un puntero a una función constante y no un puntero constante a una función (es decir, es el puntero que es const , no la función)?

Con respecto al # 4: consulte esta guía para obtener una descripción general útil de cómo crear, pasar y usar punteros de función.


En C, las funciones pueden ser const si estás en el mundo de GCC! Las funciones se pueden declarar const mediante el uso de atributos adjuntos a las declaraciones de funciones y otros símbolos. Básicamente, se utiliza para proporcionar información al compilador sobre lo que hace la función, aunque su cuerpo no está disponible, por lo que el compilador puede realizar algún tipo de optimización con él.

Una función constante se define generalmente en términos de una función pure .

Una función pura es una función básicamente sin efecto secundario. Esto significa que las funciones puras devuelven un valor que se calcula en función de los parámetros dados y la memoria global, pero no puede afectar el valor de ninguna otra variable global. Las funciones puras no pueden carecer razonablemente de un tipo de retorno (es decir, tener un tipo de retorno nulo).

Y ahora podemos definir qué es una función const,

Una función pura que no accede a la memoria global, sino solo a sus parámetros, se denomina función constante . Esto se debe a que la función, al no estar relacionada con el estado de la memoria global, siempre devolverá el mismo valor cuando se le den los mismos parámetros. Por lo tanto, el valor de retorno se deriva directa y exclusivamente de los valores de los parámetros dados.

Aquí const no implica nada acerca de la mutabilidad de la función. Pero es una función que no toca la memoria global. Puede asignar punteros normales a tales funciones. De todos modos, la región del código generalmente (olvidando el código de modificación automática durante un tiempo) será RO y no podrá modificarlo mediante el puntero normal.

Lea el artículo completo aquí.

Entonces, cuando se trata de funciones constantes de GCC, estamos hablando de optimizaciones y no de mutabilidad de funciones.


En C, no existe una función que sea const o no, por lo que un puntero a una función constante no tiene sentido (no debería compilarse, aunque no he comprobado con ningún compilador en particular).

Tenga en cuenta que aunque es diferente, puede tener un puntero constante a una función, un puntero a la función que devuelve const, etc. Esencialmente todo, pero la función en sí puede ser constante. Considere algunos ejemplos:

// normal pointer to function int (*func)(int); // pointer to const function -- not allowed int (const *func)(int); // const pointer to function. Allowed, must be initialized. int (*const func)(int) = some_func; // Bonus: pointer to function returning pointer to const void const *(*func)(int); // triple bonus: const pointer to function returning pointer to const. void const *(*const func)(int) = func.

En cuanto a pasar un puntero a una función como un parámetro, es bastante simple. Normalmente solo quieres pasar un puntero al tipo correcto. Sin embargo, un puntero a cualquier tipo de función puede convertirse en un puntero a otro tipo de función, luego volver a su tipo original y conservar el valor original.