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

Dev/annagrin/remove explicit not null constructor #743

Conversation

annagrin
Copy link

@annagrin annagrin commented Nov 7, 2018

Removed explicit not_null constructor, sloppy_not_null, added strict_not_null

We added explicit not_null constructor in version 2.0.0.
It proved very difficult to switch to the new version for
large code bases that adopted previous versions of GSL,
due to not_null used extensively in the code. Still, using
explicit constructor is very beneficial for new code, since
it encourages better API design and make null checks intentional.

To resolve the issue, this change:

  • removes explicit keyword from not_null constructor
  • removes unneeded sloppy_not_null type
  • adds strict_not_null type to behave the same way as v2 not_null - updates tests

this closes #699

@annagrin
Copy link
Author

@neilmacintosh could you please review?

Copy link
Collaborator

@neilmacintosh neilmacintosh left a comment

Choose a reason for hiding this comment

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

Thanks for putting this together. I have a few questions, but other than that it looks good overall. Feel free to answer them at your discretion.

include/gsl/pointers Show resolved Hide resolved

{
int t = 42;
int* p = &t;
Copy link
Collaborator

Choose a reason for hiding this comment

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

Am I right in thinking we are missing tests for actual implicit construction of not_null from things like explicit pointer variables and address-of operations? Something like:
helper(p);
It seems that's the whole thing people need this change for, so we'd want to ensure it works. Highly possible I missed it somewhere though. I suppose you could argue helper(&t); is equivalent, but it would be nice to see the specific syntax just to be sure something hasn't been missed.

Copy link
Author

Choose a reason for hiding this comment

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

yeah, you are right, the idea was that &i cover those tests, but having them added would be nice. Will change.

strict_not_null<int*> snn = &x;
strict_helper(&x);
strict_helper_const(&x);
strict_helper(return_pointer());
Copy link
Collaborator

Choose a reason for hiding this comment

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

It would be nice to have the equivalents of these back in the not_null tests. That symmetry would help show the difference between the two very clearly (I'm thinking particularly of the return_pointer type tests here).

Copy link
Author

Choose a reason for hiding this comment

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

sure, makes sence

tests/test.cpp Outdated
@@ -20,7 +20,7 @@

// blanket turn off warnings from CppCoreCheck from catch
// so people aren't annoyed by them when running the tool.
#pragma warning(disable : 26401 26409 26415 26418 26426 26429 26432 26433 26434 26435 26436 26439 26440 26443 26444 26446 26447 26451 26460 26461 26466 26472 26481 26482 26485 26492 26493 26494 26495 26496 26497) // from catch
#pragma warning(disable : 26401 26409 26415 26418 26426 26429 26432 26433 26434 26435 26436 26439 26440 26443 26444 26446 26447 26451 26455 26456 26460 26461 26466 26472 26481 26482 26485 26492 26493 26494 26495 26496 26497) // from catch
Copy link
Collaborator

Choose a reason for hiding this comment

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

It might be simpler to just blanket-disable ALL /analyze warnings from Catch?

Copy link
Author

Choose a reason for hiding this comment

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

yes, i don't think we care about warnings in test.cpp itself... will change,

@@ -72,13 +72,13 @@ public:
static_assert(std::is_assignable<T&, std::nullptr_t>::value, "T cannot be assigned nullptr.");

template <typename U, typename = std::enable_if_t<std::is_convertible<U, T>::value>>
Copy link
Collaborator

Choose a reason for hiding this comment

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

I don't understand how this ctor doesn't get selected and allow nullptr_t through (which is explicitly excluded by the next ctor below). Maybe it all works for whatever obscure reason I can't remember?

Copy link
Author

Choose a reason for hiding this comment

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

deleted constructor from not_null seems to take precedence. Note that commenting out deleted constructor does compile. My efforts to find explanation in the standard were futile, maybe someone else can help?

See godbolt snippet

Copy link
Member

@CaseyCarter CaseyCarter Nov 27, 2018

Choose a reason for hiding this comment

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

= delete doesn't mean that the pertinent function doesn't participate in overload resolution, it means the program is ill-formed if the function is chosen by overload resolution.

EDIT: and in this particular case, the deleted std::nullptr_t constructor is selected over the U&& constructor template by the "non-templates beat templates with equivalent conversion sequences" tie breaker in http://eel.is/c++draft/over.match.best#1.6.

Copy link
Author

Choose a reason for hiding this comment

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

@CaseyCarter thanks, this exactly what I was searching for!

Anna Gringauze added 7 commits November 28, 2018 13:23
…not_null

We added explicit not_null constructor in version 2.0.0.
It proved very difficult to switch to the new version for
large code bases that adopted previous versions of gsl,
due to not_null used extensively in the code. Still, using
explicit constructor is very benefitial for new code, since
it encorages better API design and make null checks intentional.

To resolve the issue, this change:
- removes explicit keyword from not_null constructor
- removes unneded sloppy_not_null type
- adds strict_not_null type to behave the same way as v2 not_null
- updates tests
…not_null

We added explicit not_null constructor in version 2.0.0.
It proved very difficult to switch to the new version for
large code bases that adopted previous versions of gsl,
due to not_null used extensively in the code. Still, using
explicit constructor is very benefitial for new code, since
it encorages better API design and make null checks intentional.

To resolve the issue, this change:
- removes explicit keyword from not_null constructor
- removes unneded sloppy_not_null type
- adds strict_not_null type to behave the same way as v2 not_null
- updates tests
@annagrin annagrin force-pushed the dev/annagrin/remove_explicit_not_null_constructor branch from 7450292 to a82f1e7 Compare November 28, 2018 22:08
@annagrin annagrin merged commit 9ff6e19 into microsoft:master Jan 15, 2019
@annagrin
Copy link
Author

thanks @neilmacintosh and @CaseyCarter for reviews!

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

Successfully merging this pull request may close these issues.

2fc94db made gsl::not_null constructor explicit, why?
3 participants