Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Throw an early exception to prevent divide by zero error (#2481) #2530

Merged
merged 3 commits into from
Oct 11, 2018

Conversation

jatin69
Copy link
Contributor

@jatin69 jatin69 commented Oct 7, 2018

Closes #2481

Added a try catch block to throw a length error exception to report that at least 2 elements are required in array to perform the operation.

{
// throw a exception when there are less than two elements in vector `values`
// to prevent division by zero error while calculating standard deviation.
if(values.size() < 2 )
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why not less than 1?

Copy link
Contributor Author

@jatin69 jatin69 Oct 8, 2018

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Because standard deviation needs division by n and n-1 as done in this function's last few lines. and for n-1 to be atleast 1, n needs to be atleast 2.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You don't need division to compute standard deviation of a single number, it's simply zero.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes. But the code does not handle it. I just tested and stddev is nan when a single number is passed. I wonder how did that skip testing. I'll update the code to handle it.

throw std::length_error("Input array must have atleast 2 elements.");
}
}
catch(length_error& e)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What's the point of throwing an exception and immediately catching it?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I did not know if any top-level hierarchy is catching any exceptions or not, so I had to catch it here itself. Although I did forget to add a return statement after printing the error message. I'll add it.
But even that leaves the function call in a weird result state. What will the user expect when he passes an empty array? Should I find where this function is called and add a catch block there itself?
Something else on your mind?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The idea it to let it blow up for the user. That way he'll need to sanitize values before passing it to this method.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

oh. If you want to blow up, why throw an exception at all? Aren't exceptions caused to be handled?
Anyway, I'll assume you have a use case in mind for expecting such a behavior.
So, in short,
You want to display a message saying atleast 2 values and then crash, yes?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

oh. If you want to blow up, why throw an exception at all? Aren't exceptions caused to be handled?

Yes but, to be handled by the user ('s code). We have no way of guessing what he wants to do in case he doesn't have a sanitized input. We just want to make sure that he is explicitly dealing with it.

You want to display a message saying atleast 2 values and then crash, yes?

Yes.

@jatin69
Copy link
Contributor Author

jatin69 commented Oct 8, 2018

Hi, sorry it took a long time for such a trivial change. I'm not a frequent contributor.
Please let me know if this needs any more changes.

// Let the user explicity handle this exception as per his needs.
if(values.size() < 2 )
{
throw std::length_error("Input array must have atleast 2 elements.");
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

In your error message: there's a typo with "at least".

@taketwo should we throw a pcl derived exception, like the ones present in here?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'll update this, once you settle on which exception to use.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Well there is BadArgumentException which sort of fits, we may use it. Though I feel there is no consistency within PCL regarding exceptions.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

throw pcl::BadArgumentException("Input array must have at least 2 elements.", NULL, "getMeanStd");

is this alright?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'd use PCL_THROW_EXCEPTION following the example here:

/** PCL_THROW_EXCEPTION a helper macro to be used for throwing exceptions.
* This is an example on how to use:
* PCL_THROW_EXCEPTION(IOException,
* "encountered an error while opening " << filename << " PCD file");
*/

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

PCL_THROW_EXCEPTION(BadArgumentException, "Input array must have at least 2 elements "); 

This will do? I thought mentioning the filename will barely make any sense here, as it's just a utility function.

Copy link
Member

@taketwo taketwo Oct 9, 2018

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes. But please note my other comment regarding the minimum size of the array.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes. I commented on that thread. Please see to it.

@jatin69
Copy link
Contributor Author

jatin69 commented Oct 9, 2018

I handled a missing base case of input size 1 and added an exception for input size 0. Please let me know if is alright and I'll squash commits.

Copy link
Member

@taketwo taketwo left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thank you, looks good. Please check a few minor comments. We'll also need to format to PCL style (e.g. add spaces between function/macro/if and opening braces) before we can merge this.

common/include/pcl/common/impl/common.hpp Outdated Show resolved Hide resolved
common/include/pcl/common/impl/common.hpp Outdated Show resolved Hide resolved
common/include/pcl/common/impl/common.hpp Outdated Show resolved Hide resolved
@SergioRAgostinho SergioRAgostinho added needs: code review Specify why not closed/merged yet and removed needs: more work Specify why not closed/merged yet labels Oct 11, 2018
@SergioRAgostinho SergioRAgostinho added this to the pcl-1.9.0 milestone Oct 11, 2018
Copy link
Member

@taketwo taketwo left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Perfect, thank you.

@SergioRAgostinho SergioRAgostinho removed the needs: code review Specify why not closed/merged yet label Oct 11, 2018
@SergioRAgostinho SergioRAgostinho merged commit 4280ba2 into PointCloudLibrary:master Oct 11, 2018
@jatin69
Copy link
Contributor Author

jatin69 commented Oct 12, 2018

@taketwo Thank you 😄

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants