Trying to understand void function

Hey guys, I'm very new to the Arduino programming language and I'm trying to learn. I am trying to implement a code that someone else did and I'm just reading through it trying to teach myself why certain things were done and I came to this section and I'm confused. Can someone please explain what the void function does in this case, and also, why would it be called out twice in a row?

Thanks

     // Read Oil Pressure
      total3 = total3 - readings3[index3];
      (void) analogRead(sensor1Pin);
      (void) analogRead(sensor1Pin);
      readings3[index3] = analogRead(sensor1Pin);
      total3= total3 + readings3[index3];      
      index3 = index3 + 1;                    
      if (index3 >= numReadings3)              
        index3 = 0;                          
      SensorAvg1 = total3 / numReadings3;

This use of ''void' tells the compiler that the value returned from the call to 'analogRead' is unused and should be ignored!

Hi,
Hmmm..

Can you please post a copy of your complete sketch?
What is it supposed to do?
Does the sketch compile?

Thanks.. Tom... :slight_smile:
If your sketch is too big, use REPLY rather than QUICK REPLY and it has an attachment facility.

From here it's hard to tell what part of the code is incorrect. An explanation of what you're TRYING to do would allow for a more useful answer.

If you're asking about this:

(void) analogRead(sensor1Pin);

there is not reason in the world for the "(void)" to be there, which tells me whoever wrote that code had no idea what he was doing. The superfluous "(voids)" are harmless (the compiler will ignore them), but they are also completely useless.

Regards,
Ray L.

if (index3 >= numReadings3) {
index3 = 0;
SensorAvg1 = total3 / numReadings3;
}

The superfluous "(voids)" are harmless (the compiler will ignore them), but they are also completely useless.

It's not clear to me that they will compile ad I get errors with simple examples.

If the compiler ignores these calls to analogRead() and the purpose of them was to stabilize the input capacitor with multiple reads, then the changed return type will be contrary to the purpose.

which tells me whoever wrote that code had no idea what he was doing.

I agree.

Ray is correct, as written it gets ignored by the compiler. But it shows that the value returned is not used.
Now the other contributors would benefit from reading the snippet instead of complaining about it as is customary here.

To the OP
The code reads an analog input ( three times ) which may not be stable, so it waits few cycles before reading it again.
Not the best and most obvious way to do it.

And no, we do not need to know what is it for - it reads oil pressure, as the comment states.
JIm

Hi,

And no, we do not need to know what is it for - it reads oil pressure, as the comment states.

From what?
What does it do with it?

From other comments about the "snippet", I also have grave doubts about the structure of the rest of the code and what it is trying to accomplish.
What we have here is a code not written by the OP, which the OP is trying to understand, but appears to have been written in a weird structure.
Not a good example to learn from. (Or is it?)

Tom.... :slight_smile:

there is not reason in the world for the "(void)" to be there, which tells me whoever wrote that code had no idea what he was doing. The superfluous "(voids)" are harmless (the compiler will ignore them), but they are also completely useless

Actually, it shows the opposite: that the person who wrote the code knew exacly how to write it correctly, and the writer of the above quote is the cluless one.

There are both compiler options and tools (it varies with the compiler) that examine a program for correctness. The most popular external tool is 'lint'. Using these options or tools, you will get a warning if you call a value-returning function and do not use the result. To tell the compiler or tool that you have done this deliberately, and not just forgotten to use the result, or, worse still, have naïvely chosen to ignore a possible error indication, the rule, supported by the syntax of C and C++, is to place a (void) cast as shown. This says that the author of that code is careful and meticulous, deeply knowledgeable about how to write warning-free code, and (possibly over-) cautious. It is neither incorrect nor redundant, and at high error-checking levels of the compiler, or the use of an external tool, it is most certainly not ignored.

[And if this seems a bit harsh, note that the person who posted this quote incorrectly stated that the person who wrote the code had "no idea what he was doing" and further incorrectly stated they were "completely useless". Not only are both statements false, they "teach away from" Best Practice]
joe
[former Microsoft MVP in C/C++/MFC/Windows]

there is not reason in the world for the "(void)" to be there, which tells me whoever wrote that code had no idea what he was doing. The superfluous "(voids)" are harmless (the compiler will ignore them), but they are also completely useless

Actually, it shows the opposite: that the person who wrote the code knew exacly how to write it correctly, and the writer of the above quote is the cluless one.

There are both compiler options and tools (it varies with the compiler) that examine a program for correctness. The most popular external tool is 'lint'. Using these options or tools, you will get a warning if you call a value-reurning function and do not use the result. To tell the compiler or tool that you have done this deliberately, and not just forgotten to use the result, or, worse still, have naïvely chosen to ignore a possible error indication, the rule, supported by the syntax of C and C++, is to place a (void) cast as shown. This says that the author of that code is careful and meticulous, deeply knowledgeable about how to write warning-free code, and (possibly over-) cautious. It is neither incorrect nor redundant, and at high error-checking levels of the compiler, or the use of an external tool, it is most certainly not ignored.

[And if this seems a bit harsh, note that the person who posted this quote incorrectly stated that the person who wrote the code had "no idea what he was doing" and further incorrectly stated they were "completely useless". Not only are both statements false, they "teach away from" Best Practice]
joe
[former Microsoft MVP in C/C++/MFC/Windows]

(void) analogRead(sensor1Pin);
      (void) analogRead(sensor1Pin);

Can someone put the snippet into a compiler which will compile it (the Arduino IDE won't) and see what the hex file is? Are the functions executed and the result ignored, or are the functions eliminated. If the purpose was to stabilize the analogRead(), I think the difference is critical.

It's not clear to me that they will compile ad I get errors with simple examples.

If the compiler ignores these calls to analogRead() and the purpose of them was to stabilize the input capacitor with multiple reads, then the changed return type will be contrary to the purpose.

Actually, they do compile, and a vague statement of the form "I get errors with simple examples" is meaningless noise unless accompanied by the simple example and the error message it generated. When a "simple example" fails, it usually means the example is wrong, and the compiler has properly reported this incorrect example as being incorrect.

I spent 15 years dealing with silly posts like this, and when we finally extracted the source code and error message of the "failing example", the example was, without exception, wrong. For example
extern int SomeFunction();
(void) SomeFunction();

This actually compiled correctly, but the OP of that issue got a linker error message that SomeFunction was an undefined symbol, and erroneously claimed that the example "would not compile". So without the example and the error message(s), you are wasting time making (silly) claims that "I get errors".

I have a related problem, that the library I am including does not compile. I didn't write the code, but it gets an error message. What did I do wrong? [If you answer that correctly, then I can understand why you didn't see the need to post the code of your "simple example". But I'm typing this on my iPad, which does not support PTP, so I don't know what you've done. (PTP is the Psychic Transfer Protocol)]

The compiler does not ignore the calls to analogRead(); no one, as far as I know, has suggested this as a possibility. What the (void) cast says is "I [the programmer] am ignoring whatever value this function returns, and I am doing this deliberately; I know what I am doing, so please, {compiler, tool} do not complain that I did not use the value returned". So at no point is the call ignored; in fact, the C/C++ language definitions mandate that the function be called.
joe

flounder:
Actually, they do compile, and a vague statement of the form "I get errors with simple examples" is meaningless noise unless accompanied by the simple example and the error message it generated. When a "simple example" fails, it usually means the example is wrong, and the compiler has properly reported this incorrect example as being incorrect.

I spent 15 years dealing with silly posts like this, and when we finally extracted the source code and error message of the "failing example", the example was, without exception, wrong. For example
extern int SomeFunction();
(void) SomeFunction();

This actually compiled correctly, but the OP of that issue got a linker error message that SomeFunction was an undefined symbol, and erroneously claimed that the example "would not compile". So without the example and the error message(s), you are wasting time making (silly) claims that "I get errors".

I have a related problem, that the library I am including does not compile. I didn't write the code, but it gets an error message. What did I do wrong? [If you answer that correctly, then I can understand why you didn't see the need to post the code of your "simple example". But I'm typing this on my iPad, which does not support PTP, so I don't know what you've done. (PTP is the Psychic Transfer Protocol)]

The compiler does not ignore the calls to analogRead(); no one, as far as I know, has suggested this as a possibility. What the (void) cast says is "I [the programmer] am ignoring whatever value this function returns, and I am doing this deliberately; I know what I am doing, so please, {compiler, tool} do not complain that I did not use the value returned". So at no point is the call ignored; in fact, the C/C++ language definitions mandate that the function be called.
joe

I am by no means a general after the battle, but I did not want to add cast to the discussion.
I have also learn that participating in a discussion after "Elvis (OP) have left the building" generally leads nowhere.
fast.
This one after your contribution is an exception. Thanks.
Jim

jross827:
Hey guys, I'm very new to the Arduino programming language and I'm trying to learn.

I'll give you the same advice I give everyone else: google "C++ tutorial", and do at least the first couple of chapters. Types, declarations, variables, program structure, statements. Stop trying to learn C++ by hacking up cookbook examples: this ain't Ruby or PHP. C has very strict syntax and a type system. Spend a few hours over the course of a few days doing a structured tutorial.

When switching analog input pins its a good idea to ignore the first read, the s&h cap may still hold residual voltage from the previous read (from another pin), so:

(void) analogRead(sensor1Pin);  // set mux to sensor1Pin but throw away the reading
       readings3[index3] = analogRead(sensor1Pin); // get "clean" reading

I use this construct once in a while but use a dummy variable like:

dummy = analogRead(sensor1Pin);  // set mux to sensor1Pin but throw away the reading
       readings3[index3] = analogRead(sensor1Pin); // get "clean" reading

For those of you who asked to see the full code, its attached...

So I think I understand what the void function is used for in this case now, but I'm still confused why its used twice in a row?

MultiGauge_Final_withScope_4DSystems.ino (13.6 KB)

The internal conversion circuit stores the voltage to be measured into a small capacitor through a resistor.

If you try to measure a high impedance circuit, you have to account for the time it requires to allow the capacitor to charge/discharge.

A easy way to solve the issue is to take two or more readings in rapid succession: each reading will give the capacitor a chance to equalize to the pin voltage.

BulldogLowell:
The internal conversion circuit stores the voltage to be measured into a small capacitor through a resistor.

If you try to measure a high impedance circuit, you have to account for the time it requires to allow the capacitor to charge/discharge.

A easy way to solve the issue is to take two or more readings in rapid succession: each reading will give the capacitor a chance to equalize to the pin voltage.

Are you saying that the input capacitor will get charged only when the pin is read ?
Please clarify.
Jim

Here is another one in this code that is confusing me...

Its like the function is calling to itself, like it seems like it would divide itself by 64 forever until its zero....

// Read Voltage
      (void) analogRead(voltPin);
      voltReading = analogRead(voltPin);
      voltReading = voltReading / 64;