What is the purpose of the void in C?

Asked

Viewed 41,801 times

33

I have doubts about the use of void in office.

1° Example:

int somaV(int valor_1, int valor_2)
{
    return valor_1 + valor_2;
}

I know this function will return me an integer which is the sum of the two parameters in the function valor_1 and valor_2.

2° Example:

void* soma(int valor_1, int valor_2)
{
    return (int) valor_1 + valor_2;
}

I saw in a program that contained an implementation similar to the second example above that I used to illustrate the situation I witnessed of the use of void. I tested the function soma() and it returns the sum of the two parameters even having the void specified as return or empty.

This confused me about the use of void, i thought it only served to say that a function will have no return or will not receive any parameters like this example soma(void).

After all, what is the purpose of this command in C? The use of the void* specified as pointer can return values even if void?

4 answers

33


The return void means no return. Already a type void * means a generic pointer, a pointer of an unknown or unspecified type, a pointer to anything, any memory address.

They appear a lot in the C language, although the programmer doesn’t always notice them. For example, the function malloc returns a pointer of the type void *:

int *meu_numero = (int *) malloc(sizeof(int));

Here, the return of malloc is the type void *. The cast for int * is necessary for you to tell the compiler type checker to consider which value returned (which the compiler will know to be void *) shall be considered to be a int *. In this case, you get an unknown type pointer and then tell the compiler what the type is. One proof of this, is that this same code can be written in another equivalent way, denouncing the void *:

void *algum_ponteiro = malloc(sizeof(int));
int *meu_numero = (int *) algum_ponteiro;

The void * can also appear as a parameter, such as in the function free. The function free can receive any type of pointer, no matter what is the exact type of object that is pointed. Because of this the type of your parameter is also void *.

Other functions also use or produce type pointers void *, especially those who work with things in memory without wanting to know exactly what those things are, but only that it is some region in memory. Example of functions like this are the fread, fwrite, memset, among many others.

  • 4

    +1. Just one detail: it is not a good practice to cast the malloc return in C, although it is mandatory in C++. A good argument here (in English): http://stackoverflow.com/a/605858/1796236

  • @Pablo Yes, excellent observation.

  • 1

    Thanks for the explanation, I will have a lot of good information regarding the void.

18

The void * strictly means a pointer to nothing. But it is best interpreted as pointer to anything. That is, this is a way of generalizing a type, no longer specifying the type.

When you use it, it means you can work with any kind of data there. It simply points to a memory address and is problem of the programmer who will receive it know how to treat properly and probably make a cast for the desired type, in a way compatible with what is there. Obviously tragedies can happen if you try to access inappropriately. It is called indirect.

You need to be careful when using it because it loses one of the advantages of C. It’s a way to create dynamism in a statically typed language. It is also a form of polymorphism.

Note that you are returning a pointer.

int x;
float y;
char * z;

void * var;
var = &x;
var = &y;
var = &z; //ou dependo da intenção: var = z;

I put in the Github for future reference.

  • Thanks for the @bigown explanation.

13

Pointers void* precedes C++ and templates as a mechanism to deal with "generic" types in C. To be more specific void represents the absence of type, which can be understood as the presence of any kind. As you have already discovered, it is possible to assign a int, char or any other type to a void*.

With void* functions that do not need to know the type details can do their job. Programmer, who knows the type, can do the Casts necessary. Note that absence of types basically puts the responsibility on typing on the back of the programmer .

#Why is that useful?

One of the best examples of using void* is the function qsort, whose signature is:

void qsort (void* base, size_t num, size_t size,
            int (*compar)(const void*,const void*));

With the qsort we can order an array base of any kind. You only need to define a function of the type int(const void*, const void*) able to compare array types base.

Example:

int compare(const void * a, const void * b)
{
  return ( *(int*)a - *(int*)b );
}

//...
int values[] = { 40, 10, 100, 90, 20, 25 };
qsort (values, 6, sizeof(int), compare);

You could have a method to compare char*, or who knows for a specific type of struct or anything else. Thanks to pointers void the function qsort is "generic".

But and functions that return void pointers*?

The idea is the same. Generic Apis can work with multiple return types. A good example are the pair of functions int pthread_setspecific(pthread_key_t key, const void *value) and void *pthread_getspecific(pthread_key_t key) of pthreads.h. You can store and recover any kind of value thanks to the use of void*.

Other good examples are the functions alloc as well mentioned in the previous answers. In c you do not need or should do cast of the result of malloc (That changed in C++):

// C
int *arr= malloc(sizeof(int)*length);
// C++ escrito para ser compatível com C
int *arr= (int *)malloc(sizeof(int)*length);
// C++ "de verdade"
int *arr= new int[length];
// C++11 - Melhor ainda, esqueça o delete
std::unique_ptr<int[]> arr(new int[10]);

  • [http://www.cplusplus.com/ - qsort][1]
  • [Open Group - pthread_setspecific][2] [1]: http://www.cplusplus.com/reference/cstdlib/qsort/ [2]: http://pubs.opengroup.org/onlinepubs/007908799/xsh/pthread_getspecific.html
  • Thanks for the explanation, as soon as I get back from college I’ll analyze the content better.

0

When used as a function return type, the keyword void specifies that the function does not return a value. When used for the list of parameters of a function, void specifies that the function does not use any parameters. When used in the statement of a pointer, void specifies that the pointer is "Universal"

source: https://docs.microsoft.com/pt-br/cpp/cpp/void-cpp?view=msvc-160

Browser other questions tagged

You are not signed in. Login or sign up in order to post.