Jump to content
  • Advertisement
Sign in to follow this  
MarkS

Why not use return type "void"?

This topic is 2595 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

I taught myself C in my early teens and every reference I could find had functions prefaced with "void" if they did not return a value. As such, I thought it was standard practice to do so and that void implied no return value. I have always followed this practice.

Now, I'm teaching myself C++ and I am finding references stating quite bluntly that you should never a return type of void. OK, I do understand that void is a valid type, but if there is no return statement in the function and it is very clear that nothing can and/or should be returned, why not use void?

Even more confusing is that I've read that not having a return type implies a type of "int". So, this would mean that if I do not want a function to return a value and do not include a return type in the definition, it is implied that the function *could* return an int. huh.gif

I'm lost here. Can someone explain this for me?

Share this post


Link to post
Share on other sites
Advertisement

I taught myself C in my early teens and every reference I could find had functions prefaced with "void" if they did not return a value. As such, I thought it was standard practice to do so and that void implied no return value. I have always followed this practice.

Now, I'm teaching myself C++ and I am finding references stating quite bluntly that you should never a return type of void. OK, I do understand that void is a valid type, but if there is no return statement in the function and it is very clear that nothing can and/or should be returned, why not use void?

Even more confusing is that I've read that not having a return type implies a type of "int". So, this would mean that if I do not want a function to return a value and do not include a return type in the definition, it is implied that the function *could* return an int. huh.gif

I'm lost here. Can someone explain this for me?


It's a recommended practice; a dubious one at that. The thought is that functions should do something. They take some input and provide some output. By returning void, you're not visibly doing anything which is frowned upon by those people.

Using void is fine. Function side effects have their own concerns, but they're not something you should worry about while learning a language.

Share this post


Link to post
Share on other sites
Returning void is perfectly fine. If there is nothing to return there is nothing to return. They are most likely saying return at least a boolean to say true or false, if the function actually worked correctly. Sometimes you have early breaks in functions such as checking for null and returning early so it does not crash.

Share this post


Link to post
Share on other sites

Returning void is perfectly fine. If there is nothing to return there is nothing to return. They are most likely saying return at least a boolean to say true or false, if the function actually worked correctly. Sometimes you have early breaks in functions such as checking for null and returning early so it does not crash.


That makes sense, however, it is never stated as such. I always read: "Never use a return type of void."

As Telastyn stated, it is dubious. This is especially true in C++, hence the confusion.

Here is the matrix header for a project I am working on:

[source]

#ifndef __MATRIX_H__
#define __MATRIX_H__

#include "math defs.h"
#include "vector.h"

/*
* |0 4 8 12|
* m[0..15] = |1 5 9 13|
* |2 6 10 14|
* |3 7 11 15|
*/

class matrix{
public:
float GetMatrixElement(unsigned int row,unsigned int column) const {if(row < 4 || column < 4) return(m[(column << 2) + row]);}
void SetMatrixElement(unsigned int row,unsigned int column,float _m) {if(row < 4 || column < 4) m[(column << 2) + row] = _m;}

float Get_m00() const {return(m[0]);}
float Get_m01() const {return(m[4]);}
float Get_m02() const {return(m[8]);}
float Get_m03() const {return(m[12]);}

float Get_m10() const {return(m[1]);}
float Get_m11() const {return(m[5]);}
float Get_m12() const {return(m[9]);}
float Get_m13() const {return(m[13]);}

float Get_m20() const {return(m[2]);}
float Get_m21() const {return(m[6]);}
float Get_m22() const {return(m[10]);}
float Get_m23() const {return(m[14]);}

float Get_m30() const {return(m[3]);}
float Get_m31() const {return(m[7]);}
float Get_m32() const {return(m[11]);}
float Get_m33() const {return(m[15]);}

void Set_m00(float _m) {m[0] = _m;}
void Set_m01(float _m) {m[4] = _m;}
void Set_m02(float _m) {m[8] = _m;}
void Set_m03(float _m) {m[12] = _m;}

void Set_m10(float _m) {m[1] = _m;}
void Set_m11(float _m) {m[5] = _m;}
void Set_m12(float _m) {m[6] = _m;}
void Set_m13(float _m) {m[13] = _m;}

void Set_m20(float _m) {m[2] = _m;}
void Set_m21(float _m) {m[6] = _m;}
void Set_m22(float _m) {m[10] = _m;}
void Set_m23(float _m) {m[14] = _m;}

void Set_m30(float _m) {m[3] = _m;}
void Set_m31(float _m) {m[7] = _m;}
void Set_m32(float _m) {m[11] = _m;}
void Set_m33(float _m) {m[15] = _m;}

void IdentityMatrix();
void RotationMatrix(float angle,float x,float y,float z);
void MatrixTransformVector(vector *vec);
void MatrixMultiply(matrix _m);
private:
float m[16];

const unsigned int m00 = 0;
const unsigned int m01 = 4;
const unsigned int m02 = 8;
const unsigned int m03 = 12;

const unsigned int m10 = 1;
const unsigned int m11 = 5;
const unsigned int m12 = 9;
const unsigned int m13 = 13;

const unsigned int m20 = 2;
const unsigned int m21 = 6;
const unsigned int m22 = 10;
const unsigned int m23 = 14;

const unsigned int m30 = 3;
const unsigned int m31 = 7;
const unsigned int m32 = 11;
const unsigned int m33 = 15;
};

#endif
[/source]


It is clear that the functions "IdentityMatrix", "RotationMatrix", "MatrixTransformVector" and "MatrixMultiply" operate on the class variable "m". As such, they cannot possibly return a value, other than maybe a bool. So, from Telastyn's reasoning, the functions are incorrect to return a type of void as they should be returning something. However, these are proper C++ function definitions.


What reference is stating that ?


The book "Teach yourself C++ is 24 hours" which I no longer have and then various references and quotes online, including from members on this site. Sorry, I cannot be more specific. I never thought it worth the time to save a link just for this.


Having functions/procedures/methods with a void returntype however is not necessarily wrong if you are doing procedural programming. (If you are doing functional programming then void functions can be considered bad since they will always be non pure)

void pointers on the other hand is a almost always an awful idea in C++, especially if you use them like you would in C.


Good to know.

Share this post


Link to post
Share on other sites

I would say you should probably disregard anything else such a source tells you.

There is no "default int" in C++. A function must have a return type, and there is nothing wrong with having a return type of "void". The standard C++ library itself provides many functions that have a return value of type "void."


Thanks. I figured as much. I am also willing to admit that I may have misunderstood the intent of the comment(s). I just wanted to make sure I wasn't doing anything incorrectly.

Share this post


Link to post
Share on other sites
Your source should be shot. According to their logic, the C++ standard is violating this "rule" (std::swap, std::fill, std::replace, std::reverse, std::string::resize, std::vector::clear, etc, etc, etc...). [font="Courier New"]void[/font] is a part of the C++ language for a reason, and it should be used if it is needed. They obviously have no clue what they're talking about.

As others have said, that part about the "default int" type is BS as well.

Share this post


Link to post
Share on other sites
As part of the recommended process of splitting up complicated bits of code into multiple functions, you're likely to end up with functions/methods which perform some operation on whatever structure without needing to return anything. Now you COULD, for eaxmple, have a std::vector resize() function that created a separate copy of the resized vector instead of performing the operation in-place. But that would be horribly inefficient. There's ongoing debate over where to draw the line. Should you provide a matrix multiply function that returns the resulting matrix by value, or should it use an output reference parameter? Return Value optimisation will often eliminate the overhead anyway, but if you never did any operation in-place, you'd have a pretty significant performance impact.

Share this post


Link to post
Share on other sites
The curious thing about those advices is that they makes a lot more sense in legacy C (I mean C89 and before). The default return value of a C89 function is indeed int and if you do not write the return value in that language the compiler interpret it as int. In the early days of C, void wasn't supported (before the ANSI standard). If you programmed in C back then, the advice to avoid to use void made therefore sense. Moreover, the return value is the main method to return errors conditions to the user and some C style standard advocate the use of int as the only acceptable return value (with the use of the parameters for returning value). But those advices are just BS in C++ and probably also "modern" C.

Share this post


Link to post
Share on other sites
Sign in to follow this  

  • Advertisement
×

Important Information

By using GameDev.net, you agree to our community Guidelines, Terms of Use, and Privacy Policy.

GameDev.net is your game development community. Create an account for your GameDev Portfolio and participate in the largest developer community in the games industry.

Sign me up!