Reputation: 11
I would like to ask if it is possible to use a "void" variable that works the same as the pointer void (where you can store a pointer to any type of data like int
, char
etc). For example, function(void variable)
to which I can pass any variable, like function(4)
or function("hi")
.
Thank you!
PD: I'm doing an exercise related to simple linked lists (through structs)
typedef struct _GNodo {
void *dato;struct _GNodo *sig;
} GNodo;
GList GList_agregar_final(GList lista, void dato) {
GNodo *nuevoNodo = malloc(sizeof(GNodo));
nuevoNodo->dato = dato;
nuevoNodo->sig = NULL;
if (lista == NULL)
return nuevoNodo;
GList nodo = lista;
for (;nodo->sig != NULL;nodo = nodo->sig);
/* ahora 'nodo' apunta al ultimo elemento en la lista */
nodo->sig = nuevoNodo;
return lista;
}
Upvotes: 1
Views: 747
Reputation: 1625
No, you can׳t because the compiler must know the argument size at compilation time, if you want to pass a generic object you should pass void * instead, this is fine because the size of a pointer is known at compilation time.
Upvotes: 2
Reputation: 1
This is not possible in standard C. Read e.g. n1570 or some newer standard. Since some implementations passes argument in CPU registers (a different register for int
and double
, for example Linux amd64 ABI)
.
See also variadic functions with <stdarg.h>
which requires at least one fixed argument
You could also pass a pointer to some union
, or a union
of pointers and other types. Of course, you need a documented convention to choose the union
member. Read more about tagged unions. Study for inspiration the source code of GNU bash or of the sash shell. They are open source software.
BTW GList
could be used in GTK (its Glib part). Study it carefully, it is a well written open source toolkit: download its source code and study it. It has some GVariant
Consider also using the Clang static analyzer, or Frama-C, or even Bismon (a static analyzer above GCC for embedded code written in C or C++) on your C source code. For Frama-C or Bismon contact me by email to [email protected]
If you use GCC to compile your C code, invoke it as gcc -Wall -Wextra -g
then use the GDB debugger to understand the behavior of your program.
Upvotes: 2
Reputation: 67546
In your case, you can:
List GList_agregar_final(GList lista, const void *dato, size_t dataSize) {
GNodo *nuevoNodo = malloc(sizeof(*nuevoNodo));
/* check if allocation did not fail */
nuevoNodo->dato = malloc(dataSize);
/* check if allocation did not fail */
memcpy(nuevoNodo -> dato, data, dataSize);
nuevoNodo->sig = NULL;
/* ... */
GList_agregar_final(lista, (int[]){4}, sizeof((int[]){4}));
GList_agregar_final(lista, "hi", sizeof("hi"));
Do not use types in the sizeof only objects as in my example
Upvotes: 0
Reputation: 2716
No, the compiler needs to know the size of a parameter. It works with a pointer since void *
has a known size, but void
does not.
Upvotes: 2