Jump to content
  • Advertisement
Sign in to follow this  
freeworld

is it common practice to use default arguments?

This topic is 3524 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

Is it common practice to use default arguments? Just curious, I myself like them and use them all the time, especially with arguments that are only used in special cases and so forth.

Share this post


Link to post
Share on other sites
Advertisement
It's fairly common, yes. But I'm not convinced it's a good idea.

Default arguments create maintenance nightmares, because it means functions now accept various mixes of arguments, and that means that changes in the signature can go undetected by calling code. If you're lucky you'll notice the bogus function call, but real life experience has shown that there's a tendency for these things to go unnoticed for a long time and cause headaches. It also makes reading the code a pain, because it's unclear at the site where the call is being made what the default parameters are doing in that case. You have to go to the actual function to figure out what's happening.

In short, I'd say it's common but it shouldn't be.

Share this post


Link to post
Share on other sites
In a project some time, when I wanted to add a piece of completely new functionality that required an additional parameter to a function, I'd sometimes give a default value to the added argument, so I wouldn't have to change the existing code using that function.

E.g


bool set_cell_value(int row, int col, int value, bool add_to_undo = true);

bool start_new_game(const RawData& data, unsigned diff, bool novice_game = false);


The first apparently reflects a change when the "undo move" feature was added, and the second when I added a "novice mode" which didn't quite follow all the ways of the normal difficulty settings.

I don't believe the design was entirely good (too big classes/functions) and perhaps the novice_game feature could have been implemented via inheritance and some design patterns (had I planned for the possibility upfront).

Another thing is something like that:


struct Coord
{
int x, y;
Coord(): x(0), y(0) {}
Coord(int x, int y): x(x), y(y) {}
};


Some typing could be saved by giving defaults to the constructor, but it doesn't feel right to allow Coord be constructed with one argument. Don't want the following to work:


void foo(const Coord& );

int main()
{
foo(1);
}

Share this post


Link to post
Share on other sites
Quote:
Original post by visitor


struct Coord
{
int x, y;
Coord(): x(0), y(0) {}
Coord(int x, int y): x(x), y(y) {}
};



Why would you want to initialize a structure with default values?

Quote:
Original post by visitor
Don't want the following to work:


void foo(const Coord& );

int main()
{
foo(1);
}


Declare the constructor explicit (assuming you use default args, of course).

Share this post


Link to post
Share on other sites
Quote:

Why would you want to initialize a structure with default values?


Because there is nothing so special about it that someone wouldn't want to have this default-constructed (and yet not left uninitialized)? A class/struct not having a default constructor is a pretty big restriction...

Quote:

Declare the constructor explicit (assuming you use default args, of course).


Right. Still the following might make you wonder whether someone made a mistake or not:


Coord c(1);

Share this post


Link to post
Share on other sites
Quote:
Original post by visitor
Quote:

Why would you want to initialize a structure with default values?


Because there is nothing so special about it that someone wouldn't want to have this default-constructed (and yet not left uninitialized)? A class/struct not having a default constructor is a pretty big restriction...


It is something special. Why would you want a coordinate or vector type default initialized to 0? If you want it to be (0, 0) just write it. But let the default constructor leave uninitialized values. Can a vector be in an invalid state? Members are public so you can assign anything, so anything is valid.

Quote:
Original post by visitor
Quote:

Declare the constructor explicit (assuming you use default args, of course).


Right. Still the following might make you wonder whether someone made a mistake or not:


Coord c(1);


I was thinking more about 1 arg constructor case.

Share this post


Link to post
Share on other sites
I seemed to think that it is the C++ mind-set that you shouldn't have uninitialized variables if you can help it. In C you can't help it (because there are no constructors), in C++ you can by default-initializing it.

If this wasn't so then why does std::pair (which is practically the same thing) default-initialize its members?

Share this post


Link to post
Share on other sites
Quote:
Original post by visitor
I seemed to think that it is the C++ mind-set that you shouldn't have uninitialized variables if you can help it. In C you can't help it (because there are no constructors), in C++ you can by default-initializing it.


No. You shouldn't have an object in an invalid state. For vectors, there are not invalid states. If you don't want an uninitialized vector, initialize it with some meaningful values.

I think we use the word initialize with different meanings. All structs/classes that have public constructors are always initialized. The thing is that basic types are initialized with undefined values. You cannot not initialize a member.

Now, what do you gain by initializing a vector to (0, 0) by default?
If you don't, then e.g. you can create std::vector<Vec2> v(100) that doesn't waste time for default initializing. There must be a reason why basic types are not default-initialized to 0, right?

Share this post


Link to post
Share on other sites
Quote:
Original post by rozz666
It is something special. Why would you want a coordinate or vector type default initialized to 0? If you want it to be (0, 0) just write it. But let the default constructor leave uninitialized values. Can a vector be in an invalid state? Members are public so you can assign anything, so anything is valid.

I understand your reasoning, but I don't agree. I cannot imagine that some random initial values are desirable. They may be technically 'valid', but they can introduce some unexpected behavior. Defaulting to (0, 0) simply makes your coordinate type more reliable. Which is well worth the cost, imo. After all, if default initializing values is a bottleneck, then the real problem is that you're creating way too many instances, way too often...


So, you can either 1) pass initial values as arguments, or 2) rely on an expected default state. Special cases such as random initial values should not be something to worry about: there are more important matters to attend to.

Besides, positions are usually stored as floating point numbers. Those can be NaN or (negative) infinite, so you cannot rely on their validity anyway. And if you're defaulting floats, but not ints, you're not being consistent, which can cause confusion, bugs, issues... in other words, make things easier for yourself by setting reliable, expected default values. Worry about those micro-optimizations later, when and if you actually need them.

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.

We are the game development community.

Whether you are an indie, hobbyist, AAA developer, or just trying to learn, GameDev.net is the place for you to learn, share, and connect with the games industry. Learn more About Us or sign up!

Sign me up!