5

I'm looking at some code that has a function that looks like this:

void f(A* a, B& b, C* c)
{
   (void)a;
   (void)b;
   (void)c;
}

What exactly does the (void) at the start of every line do?

Jesper Evertsson
  • 563
  • 8
  • 24

4 Answers4

9

What you see there is really just a "trick" to fake variable/parameter usage.

Without those lines, a pedantic compiler will warn you about the variables not being used.

Using a construct (void)variablename; will result in no instructions being generated, but the compiler will consider it a valid "use" of those variables.

Mario
  • 33,344
  • 5
  • 53
  • 74
  • Ok, but what is the point of the function then? Beacuse this is literally everything this function does. – Jesper Evertsson Feb 26 '15 at 08:04
  • 1
    This could be a stub then... Created for compatibility.. Main code calls function `f`. For say xyz architecture, this is defined, for abcd architecture it is stubbed as shown. – anishsane Feb 26 '15 at 08:05
  • 1
    @JesperEvertsson There's no use and a optimizing compiler will most likely strip it out completely (i.e. not generate any code for it). It's probably a placeholder for something to be implemented or some legacy thing. – Mario Feb 26 '15 at 08:05
  • @Mario Ok, after digging around some more in the code, this function is a virtual function in the base class of this class. So I guess it just doesn't need to do anything for this particualar sub class. And just to make sure I understand correctly, if I removed everything inside the function the program should still work the same? – Jesper Evertsson Feb 26 '15 at 08:08
  • 1
    @JesperEvertsson Exactly. It essentially means "don't do anything if not reimplemented in a derived class". Removing the lines in the function won't change anything (except possible complaints about unused variables). – Mario Feb 26 '15 at 08:08
  • @JesperEvertsson If you removed the three lines of the body of the function you'd get warnings. But seem my comment to your question. – juanchopanza Feb 26 '15 at 08:09
  • @Mario If a compiler strips that function out completely, the program may not link properly due to missing function. Compiler may shrink the function as a `ret` alone, but should not remove it. – CiaPan Feb 26 '15 at 08:12
  • @CiaPan If it would strip the whole function due to being empty, it would remove all calls/references as well of course (assuming this is possible and it's never assigned). Writing some library code or base class is a completely different topic of course. – Mario Feb 26 '15 at 08:13
  • @Mario It is NOT possible. The function seems public, so references/calls may be in other modules. – CiaPan Feb 26 '15 at 08:15
  • @CiaPan: The linker might though. – Lightness Races in Orbit Feb 26 '15 at 11:20
3

It's simply a kludge to avoid compiler warnings. For example, that code will emit

warning: unused parameter ‘a’ [-Wunused-parameter]
warning: unused parameter ‘b’ [-Wunused-parameter]
warning: unused parameter ‘c’ [-Wunused-parameter]

when compiled with gcc -Wall -Wextra if the kludge is not used. There are cleaner looking ways to achieve this though. You could omit the parameter names:

void f(A*, B&, C*) {
}

A gcc-specifc and somewhat verbose alternative is to use the unused attribute on each unused parameter:

void f(A* a __attribute__((unused)), B& b, C* c) {
}
Andy Brown
  • 8,676
  • 2
  • 30
  • 49
  • 1
    Another way to get rid of the lines and avoid the warning, just remove the names from the parameters and all is ok: `void f(A*, B&, C*) {}` – PaperBirdMaster Feb 26 '15 at 10:31
2

I see at least two rerasons. The first one is to avoid warnings of the compiler that the variables are defined but not used in the body of the function.

The second one is that it is very old code and sometimes programmers wrote casting to void before expressions if the result of the expressions is not used. This helped the compiler to optimize generated object code.

Vlad from Moscow
  • 224,104
  • 15
  • 141
  • 268
  • Second paragraph: It's not just very old code. Even most recent compiler versions (e.g. GCC) will complain if you enable pedantic warnings and don't use return codes of some functions without casting to `void`. Although to be honest, that second use isn't present in the code above, which might be a misleading statement, in case any of the parameters is a function pointer. – Mario Feb 26 '15 at 08:18
-3

Whenever we are writing a function in C++, we need to follow prototype of function, i.e.

type name ( parameter1, parameter2, ...) { statements }

here type- stands for type of value it returns

  1. A return type of void allows you to define a function that does not return a value. Note that it is NOT the same as returning 0. The value of 0 is of type integer, float, double, etc; it is not a void. (In other languages, a function with no return value may be called a "subroutine" or "procedure", whereas a "function" always returns something. In C/C++, they are all called functions.) returning void means returning nothing.

  2. A pointer to void is a generic pointer that can be used when the type of the data at the location is unknown. So you can use a type of void * to refer to an address in memory without knowing what is actually located there.

Sartaj Singh Sisodiya
  • 1,043
  • 11
  • 10