¿Es void * function () un puntero a la función o una función que devuelve un void *?

26

Estoy confundido sobre el significado de void *function().
¿Es un puntero para funcionar o una función que regresa void*? Siempre lo he usado en estructuras de datos como una función recursiva que devuelve un puntero, pero cuando vi un código en multithreading ( pthread) hay una misma declaración de función. Ahora estoy confundido cuál es la diferencia entre ellos.

usuario9515151
fuente
55
@goodvibration C se hizo sin formato (y C ++ "heredó" esto). Even void*function();es sintácticamente correcto. Por ejemplo, para Python eligieron una decisión diferente: el formato es parte de la sintaxis. En mi humilde opinión, ambas formas tienen sus ventajas y desventajas.
Scheff
3
@goodvibration cuanto más intentas proteger al programador de hacer lo que quieren, más obtienes algo como Java;)
idclev 463035818
2
@ goodvibration Menos opciones, menos flexibilidad. Y, por favor, tenga en cuenta que fue hace décadas cuando lo hicieron. Es fácil quejarse después ... ;-)
Scheff
2
En el lenguaje C, void *function()es una función que toma un número arbitrario de argumentos y devuelve un valor que, cuando se desreferencia, es de tipo void . En C ++, void* function()es una función que no toma argumentos y devuelve un valor de puntero a vacío . Debes decidir en qué idioma estás preguntando.
Stephen M. Webb
1
@ StephenM.Webb No puede desreferenciar avoid * . Después de todo, incluso si pudieras, ¿qué harías con un void?
Fabio dice reinstalar a Monica el

Respuestas:

38

La función tiene el tipo de retorno void *.

void *function();

Así que siempre prefiero en tales casos separar el símbolo *del nombre de la función como

void * function();

Y como se Jarod42señala en un comentario, puede volver a escribir la declaración de función en C ++ usando el tipo de retorno final como

auto function() -> void *;

Si desea declarar un puntero para que funcione, debe escribir

void ( *function )();

O

void * ( *function )();

O un puntero a la función que devuelve el puntero a la función

void * ( *( *function )() )();
Vlad de Moscú
fuente
2
Por eso prefiero escribir void* function();. Eso no es tan tentador ... ;-) (La edición ocurrió justo mientras escribía esto.)
Scheff
en el código que declaro void * reader();luego en pthread_create(&thread1,null,reader,reader_arg)lugar depthread_create(&thread1,null,&reader,reader_arg)
user9515151
1
@Scheff: O incluso auto function() -> void*(C ++). :)
Jarod42
3
O un puntero a la función que devuelve el puntero a la función Para eso typedefestá ... ;-)
Andrew Henle
1
@AndrewHenle Con typedef no hay problema. Un problema surge cuando las declaraciones se usan sin typedef o una declaración de alias. :)
Vlad desde Moscú
7

Siempre que no estoy seguro acerca de los problemas de sintaxis de C, me gusta usar la utilidad cdecl ( versión en línea ) para interpretar por mí. Se traduce entre la sintaxis de C y el inglés.

Por ejemplo, ingresé su ejemplo de void *foo()y devolvió

declarar foo como función que devuelve el puntero al vacío

Para ver cómo se vería la otra sintaxis, ingresé declare foo as pointer to function returning voidy regresó

nulo (* foo) ()

Esto se vuelve particularmente útil cuando tiene múltiples niveles de tipos de letra, estrellas o corchetes en una sola expresión.

bta
fuente
2

Es una función que devuelve un puntero a void.

Piensa en tu declaración de esta manera:

void *(function());

Esta sería una función que devuelve void(o nada):

void (*function2)();

Piense en la declaración anterior de esta manera:

void ((*function2)());

Una forma mucho más fácil de escribir esto es usar typedefs:

typedef void *function_returning_void_pointer();
typedef void function_returning_nothing();

function_returning_void_pointer function;
function_returning_nothing *function2;

Esto generalmente elimina la confusión en torno a los punteros de función y es mucho más fácil de leer.

SS Anne
fuente
0

Las declaraciones en C / C ++ se leen desde el identificador hacia afuera siguiendo la precedencia del operador .

Una mirada rápida a la tabla de precedencia de operadores C / C ++ en wikipedia revela que el operador de llamada de función ()tiene una precedencia más alta que el operador de indirección *. Entonces, sus declaraciones de función se leen así:

  • Comience en el identificador: functiones

  • function() una función que no toma argumentos

  • void* function()y devuelve a void*.

Este principio general también se cumple con las declaraciones de matriz ( []también tiene mayor prioridad que *) y las combinaciones de las dos. Entonces

int *(*arr[42])();

se lee como

  • arr es
  • arr[42] una matriz de 42 elementos que son
  • *arr[42] punteros a
  • (*arr[42])() funciones que no toman argumentos y
  • int *(*arr[42])()devolver un int*.

Se necesita un poco para acostumbrarse a esto, pero una vez que haya entendido el principio, es fácil leer esas declaraciones sin ambigüedades.

cmaster - restablecer monica
fuente