Jump to content
  • Advertisement
Sign in to follow this  
Thirthe

[C/C++] recommended branching in functions?

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

Hello all! I'm wondering what is the better way of programming (in the sense of readability, performance, code generation...) the type of functions that do out-of-bound checking and must exit, if the data is indeed out-of-bound: #1
int getElement( const unsigned int id ){
    if( id < 0 || id > max_elements )
        return SOME_ERROR_NO;

    return array[id];
}

or #2
int getElement( const unsigned int id ){
    if( id >= 0 && id < max_elements )
        return array[id];

    return SOME_ERROR_NO;
}

Note: I don't have a specific problem, but I was often wondering what way I should code in the future.. Thank you!

Share this post


Link to post
Share on other sites
Advertisement
Whichever makes most sense to you. The compiler may well end up optimising both to the same code anyway, and even if it doesn't, the speed difference will be a couple of clock cycles.

Share this post


Link to post
Share on other sites
Well there's definitely something wrong with #1. Take a look at the type of "id" and then look at the first part of the if statement.

Actually...this really applies to both options.

Share this post


Link to post
Share on other sites
For readability, the first option is better, especially when you have several tests for error handling. A general recommendation if to test exceptional cases first : if (exceptional) ... else ...

About efficiency, compilers are able to optimize both methods very efficiently anyway, so use what you prefer.

Share this post


Link to post
Share on other sites
Your functions don't handle the problem. They leave it to the caller.

1) What happens if you go out of bounds? Assert? Exception? Default value? If so, which default value? Is OOB fatal error? Why? Why not?

2) Who is the caller? Should they expect a failure (file, network I/O), or assume operation succeeds (memory buffer)?

3) Do you need to check? Or can you encapsulate access in such a way that buffer can never overflow, so you have just use a debug-time assert? Network handler, for example, can pass buffer length into recv(), and we'll assume that function will never overflow.

4) Which language? Memory managed languages handle this condition already

5) Why are you checking unsigned int for < 0?

5) As it stands, your accessor functions have almost no added value. You could almost expose the array directly. Why not encapsulate:

bool valid_index(unsigned int id)
{
return (array) && (id < length); // unsigned, so only 1 test, check if array is valid
}

bool remove(unsigned int id)
{
bool valid_index = check_bounds(id);
if (valid_index) {

if (length > 1) array[id] = array[length-1]; // remove the element
length--; // decrease array size
}

return valid_index;
}

...

if (remove(17)) {
// we removed the element
}
...
remove(200); // we don't care if it was removed

...

if (!remove(42)) {
std::cout << "couldn't remove element";
}

Share this post


Link to post
Share on other sites
testing whether an unsigned int is >=0 is pointless....


int getElement(const unsigned id)
{
return (id < max_elements) ? array[id] : SOME_ERROR_NO;
}



Share this post


Link to post
Share on other sites
Quote:
Original post by murdock
I would also recommend that you use only one return statement in a function.


why is that?

Share this post


Link to post
Share on other sites
Quote:
Original post by Thirthe
Quote:
Original post by murdock
I would also recommend that you use only one return statement in a function.


why is that?


Some people prefer it that way, as they believe it makes the control flow more obvious. I dislike it, the code often ends up being unnecessarily complex trying to avoid using additional return statements. It is a personal style, try it out and see if you like it.

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!