Please clarify my understanding of the data type 'void'

I have done a lot of research on this, looked at many explanations relating to both Arduino and C++. I've looked at text explanations and video tutorials both. Read over the Arduino.cc reference pages. I've searched this forum and others and read over lots of explanations.

I would like some feedback on whether my understanding of the 'void' data type is correct, so please bear with me as I explain it, and please give me as much explanatory information on this, in order to fully flesh out my understanding of it. If you need to explain it with different examples, please do - there is no such thing as too much information in helping me to understand. Thanks.

Here's my current understanding:

• void is a data-type. Along the same lines as int or float or boolean. You use it to declare a variable or structure (eg. myCustom) as having the data type of void.

• the void data type eg. void myCustom() has no value. Not a value of 0, since that technically IS a value, but rather it is devoid of any value.

• why would I use a variable (or structure) that is devoid of a value? This is because we are interested in what is contained within the variable or structure. eg.

void loop()  {
myVariable = 9;
myVariable = 10;
}

We don't care about loop per se, just the variables or anything else we have inside the loop structure.

• you wouldn't use void on a variable and then give it a value eg.

void myCustom = 10

• void is used on both setup() and loop() since the purpose of both of these is not to give any value to any other part of the code. Setup is just the structure in which we put things that we want to occur during the startup phase of the Arduino, we don't want 'setup' itself to have a value, just to run the things it contains. Loop will be devoid of value since we are only using it for it's ability to loop a chunk of code. It's usefulness lies in it being a looping container for other code. Having them both set to void, means that the program isn't expecting some sort of value from loop() and setup() and thus confusing it when it finds that they have never been given one.

I think that's all of my understanding of it at the moment.

Please correct me, re-explain it, give examples etc... I'm interested in fully understanding how it works and when it's used.

Are there other times it's used that I might not be aware of?

Thanks.

  • void is a data-type. Along the same lines as int or float or boolean Correct so far. But the void datatype does not contain anything (hence its namne). It is used for declaring function return values in those cases when these function do not return anything. Other languages have special constructs for sub-programs that do not return anything like procedures. C i much more general and has only functions. If have a sub program that does not return anything write it as a void function.
  • You use it to declare a variable or structure (eg. myCustom) as having the data type of void. There is no point in doing that since the void datatype holds no data. As i said above the most common use for void is function return datatypes. There is however another application for void. That is a generic pointer. This pointer does not point to any datatype at all but it can be typecasted to be used with any datatype. [/list]

void is a datatype that denotes there is no datatype.

In many computer languages you have functions (which returns a value of a specified type) and procedure (which does something but does not return a value). In C++ a procedure is simply a void function. This simplifies (!) the language and allows the same construct to be used for two different things. In traditional C there is no void type - not declaring the function any type defaulted the function to int.

Note that a function can still return a value and it can be ignored by the caller anyway.

You can also have a void * (ie a pointer to an undefined data type). This can be used to declare pointers that can then be cast to point to different data types, as required. This is a practice that can lead to a number of hard-to-find bugs but is very powerful when late binding (ie, undecided at compile time) types are being used. There are also other ways to achieve similar results that are less dangerous.

void has at least three meanings in C. void as a return type means the function is actually a procedure not a function, "void *" is a hack to allow a pointer type that has no alignment constraints. An formal argument list of "(void)" means that the function takes no argments (in general in C extra arguments are allowed to be passed and ignored, (void) means no arguments are accepted at all. C++ is different)

Perhaps for the first use an empty struct would be equivalent, since that's really the same thing "no values":

typedef struct {} void ;

However void isn't a datatype, for instance you can't say

int fun (int a, void b)
{
...
}

But the second use, a pointer with the arbitrary alignment, is to allow any pointer type to be cast to the same pointer type, as needed for memory management (not quite true, function pointers aren't guaranteed to work with void *)

void * malloc (int size)
{
  ..
}

void free (void * pointer)
{
 ..
}

Why is void * a hack? C has a clear need for a generic pointer type that can be cast to any other. Originally it used char * which is much more problematic.

Thanks to all of you for taking the time to answer my question.

Based on what each of you have said, I now have more questions and some thoughts that need clarifying.

• procedures in programming languages are functions that return no value to the rest of the program

• in c++ by using void on a function, it makes it a procedure • using procedures (a void function) kind of acts as a container, allowing you to reuse the procedure in multiple places within the code, using it for the chunk of code it contains. Like a shortcut.

• in terms of setup() and loop(). Does the void at the beginning of each of these, turn them into procedures? Without the void, they would be functions? • This chunk of code:

void myVariable(int yourFamily) {
int yourMum = 6;
int yourDad = 9;
}

This would be an incorrect usage of void because myVariable is defined as having a value by the arguments (int yourFamily). Is there a situation where we would want a void function to have arguments?

• the reason we see void setup() &

void loop()

in all arduino sketches is that they are required by the arduino board in every program. We are using two functions setup() and loop() as procedures

Again thanks for taking the time to answer elementary questions. It may seem like I'm repeating myself, but it's necessary for me to shape the concepts in my head by rolling them around as much as possible. Also I'm trying to get all the terminology sorted out which is some of the battle.

• procedures in programming languages are functions that return no value to the rest of the program

No. Some languages have procedures. Some have subroutines. C/C++ had functions. The return type is irrelevant.

• in c++ by using void on a function, it makes it a procedure

No, it doesn't. C++ does not have procedures. COBOL does.

• using procedures (a void function) kind of acts as a container, allowing you to reuse the procedure in multiple places within the code, using it for the chunk of code it contains. Like a shortcut.

No. Any function is a reusable bit of code. It can be called from anywhere, regardless of its return type.

You are reading far to much into void as a return type.

• in terms of setup() and loop(). Does the void at the beginning of each of these, turn them into procedures?

No.

Without the void, they would be functions?

Without the void, they would be syntax errors.

This would be an incorrect usage of void because myVariable is defined as having a value by the arguments (int yourFamily). Is there a situation where we would want a void function to have arguments?

Wrong on all counts. The function is perfectly valid, if stupidly named and useless. It is perfectly legal to have a function that does not return a value take arguments. Think Serial.begin(115200); Naming a function myVariable doesn't make it a variable and more than int myFloat makes the variable a float.

• the reason we see ... in all arduino sketches is that they are required by the arduino board in every program. We are using two functions setup() and loop() as procedures

Yes, they are required. No, they are NOT procedures.

The void in front of a function name merely means that it does not return a value. It does not change it into a procedure as they don't exist in C++. Parameters to a function have their own types which are separate from the type returned by the function.

Like PaulS says you are reading too much into this use of void. It is simply for the compiler to know that the function returns no value so that code like

void MyFunc()
{
}

int myVar = MyFunc();

creates syntax errors and you are prevented from creating bugs. This code would have been ok in C and myVar would have contained a rubbish value as there was no 'void'.

This guy is a troll. He is winding you up !

He claims to have done extensive research all over the place, obviously he hasn’t.

An important use of void is in type checking. For example:

void loop() {
  char *cptr;
  
  cptr =  function();
  
}

void * function()
{
  char *ptr;
  
  *ptr = 10;
  return ptr;
}

allows the compiler to make sure you: 1) don't try to return a value from the function other than a pointer, and if you do, 2) it forces you to cast the result to the proper data type. If you try to compile this program, it draws and error on line:

  cptr = function();

because you are trying to assign a void pointer into a char pointer. This confirms that void is "something". However, changing the line to:

  cptr = (char *) function();

is acceptable because the compiler can verify that the pointer returned from the function is cast to a char pointer.

As to PaulS statement:

Some languages have procedures. Some have subroutines. C/C++ had functions.

C++ also has methods, which are really similar to functions, but are defined within a class.

void * function()
{
  char *ptr;
  
  *ptr = 10;
  return ptr;
}

This is a fairly terrible example. Which location in the RAM are you stuffing the value 10 into, here ?

It is code like this, that leads me to teach students to always left-align the asterisk when declaring pointer variables.

michinyon: This guy is a troll. He is winding you up !

He claims to have done extensive research all over the place, obviously he hasn't.

That's not true, I'm actually trying to learn something. Yes I've read a lot on this, but there's either contradicting information, or I'm completely misunderstanding it all. I'm open to either option, which is why I'm posting here. Why does it seem like I'm trolling?

This is great, lots of corrections, thanks. Again let me mull these over in my mind and give me feedback. I realize I'm probably reading too much into this whole void thing, but I really do want to fully understand it, and the past few days has seen my understanding of void change. There's a lot of misinformation around the web on this subject, and I do want to understand. Thanks for bearing with me.

• My thoughts about procedures came from this "void as a return type means the function is actually a procedure not a function" by MarkT, is this incorrect or did I misunderstand it?

marco_c: This code would have been ok in C and myVar would have contained a rubbish value as there was no 'void'.

Sorry, I had trouble understanding this, until I quoted it just now and the missing "C" showed up in the sentence... Weird.. So in C, having integers (int) with non integer values is ok?

PaulS, your straight up answers made me laugh - thanks for being so succinct. "Without the void, they would be syntax errors." this one particularly was great. Using myVariable was a poor choice, I should have gone with something more generic since I wasn't trying to imply it was a variable. And yes that chunk of code was stupidly named and useless. Mostly because I'm new to this and I'm making up quick examples for illustration purposes. Even as I wrote it I think I said something to the effect of "this code is stupidly named and useless" c++ has no procedures? This has been invaluable, thanks for clarifying.

In response to these revelations:

• void isn't complex • void just tells the compiler that it shouldn't expect a value from whichever function it's preceding

I'll probably look back on this post in a year and roll my eyes at my apparent stupidity, but thanks for being understanding and humorous, all of you :)

Maybe the better decision here is for me to just leave the topic of void alone for now. I'll just keep learning and come back to it in a few weeks, maybe my understanding of syntax will help me to understand it all a little better. Is it critical for me to have a full understanding of void right now?

Thanks

Your labouriously loquacious first post. And despite repeated saying that you don't understand it, you then directly both contradict and misinterpret the advice of experts who try to assist you. These are typically ( but not always ) troll behaviour.

Laborious and loquacious because I am really interested in trying to understand something I find complex. Whose advice did I contradict? Whose advice did I misinterpret? If I did these, it was done unintentionally because I don't understand these concepts yet.

If it's common for trolls to ask questions, then aren't all new users trolls? What have I done to offend you?

c++ has no procedures

"procedure" is a generic word, which some textbooks on computer programming, which are not tied to a specific programming language, use to refer to computer program sub-units, in a generic and generalized sense.

These sub-units go by various names in various specific computer languages, such as "function", "subroutine", "sub", "proc", "method" and no doubt others that I don't recall right now. They are all basically the same thing.

The description and specification of the language may use the same words which appear as an actual key-word in the use of the language, or may use different words. For example , "FUNCTION" and "SUBROUTINE" are actual keywords that you use in the code of a Fortran program, but "function" is not a keyword normally used in writing the actual code of a C/C++ program, although that is the word that functions are called in the language specification.

So, yes, you can say that "C/C++ has procedures", although they are not called that in C/C++ . All useful computer languages have "procedures", in that generic use of the word. There are some obscure non-procedural languages which claim to not use any procedures (however names) at all.

Oh thanks, that's very useful... Actually an awesome explanation, it helped a lot.

I am thinking that the terminology of programming is my biggest barrier, as it seems to be causing confusion when I try to explain my problem, and confusion when I try to understand advice.

Thanks again.

@michinyon: It's not terrible...it's wrong! This should be a little better:

void * function()
{
  char c;
  char *ptr;
  
  ptr = &c;
  *ptr = 'A';
  return ptr;
}

econjack: @michinyon: It's not terrible...it's wrong!

I think that is what michinyon was pointing out by asking the question: Which location in the RAM are you stuffing the value 10 into, here? ;)

However in reference to the return, both examples are wrong.

Thellamie: void myVariable(int yourFamily) { int yourMum = 6; int yourDad = 9; }

You seem to have functions confused with arrays. Or maybe you enjoy writing functions that do nothing whatsoever?

A function that returns void returns nothing. The return is left on the stack by the ending function for the calling function to pick up. Void says there is nothing left on the stack, int says there is an int left on the stack.