-
Notifications
You must be signed in to change notification settings - Fork 740
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
not_null has converting constructors? #395
Comments
I agree with Andrzej. It could at least be optional to force explicit conversions with something like: #if defined(GSL_NOT_NULL_EXPLICIT_CONVERSION) |
+1 In other words if had both not_null and not_null_explicit, I will use not_null_explicit. |
Whatever the solution: Please don't make its behavior dependent on some macro. I'm dreading the day when I include two external libraries, where each of them is relying on a different behavior. |
@MikeGitb Full agreed. |
There is a related PR from last year: #83 |
@akrzemi1 you make a good point. I think the principle to apply here is not whether or not we can catch more errors at compile-time. After all, the sorts of errors the compiler could catch this way are going to be relatively obvious, and the change would not substantively affect what other compile-time tooling could catch. What convinces me here is a broader issue. If someone applies As @MikeGitb observes, there was a previous PR last year that got lost amidst conflicts with other changes to the GSL. I've closed that out as it is probably painful to revive at this point with all the file renames and so on that have occurred. Would you be interested in providing a new one? |
@akrzemi1 I just noticed that you had provided a PR, sorry! It looks as though it's failing the automated checks at the moment...could you fix that up? Then I can take a look ;-) |
Neil, I know it would be decent of me to provide a complete patch, unit-tests included. I even tried it. But then the licensing process starts. It wants to know my home address, and I do not want to give such data to Microsoft. In contrast, if I just talk to you, and convince you, and you implement it, it appears that this is fine from the legal point of view. I realize, it is a bit arrogant, but can we do it this way, without having Microsoft collecting my sensitive data? |
Also, the copy assignment from p = not_null<T>(t); |
@akrzemi1 There's no need to convince me here, this is an issue with I've replied on the PR explaining why I can't accept the PR as-is and why the CLA is a requirement for contributing. |
This issue is holding us back for quite some time now. So, CLA is preventing progress, but how to move forward and fix it? |
@Amaroker You could provide an alternate PR. :-) As I observed a while back, there was an earlier PR that was made obsolete by source movements, perhaps that one can be revived? |
I notice Looking at it, Otherwise if The later you re-arrange things the more painful it will get. Although moving |
I'll consider it, but I'm new to github so I'll first need to learn how it works. I once read Microsoft's CLA, but the jurisdiction/legal mumbo jumbo made me cringe. I'm not sure what it all means, nor am I familiar with the American laws referred to, or how my personal information will be used. |
@galik this sounds like you have identified a useful issue, but probably unrelated to this one. do you want to open a separate issue so we don't lose track of your thoughts on header file structure with regard to @Amaroker No problem. I am sure that someone will get to this eventually (perhaps even me). I was just suggesting that if this is a particular problem for you, you may want to contribute a fix. But, I completely understand that there are some hurdles to doing so ;-) |
@neilmacintosh done. |
xref: issue #502: Relocate |
Maybe I'm misunderstanding, but making the constructor explicit doesn't seem to require any special sauce to sneak a nullptr into it:
If I'm understanding it, I'm against this change. |
on the line "c(pi)" (L15 in your godbolt link), you are constructing a not_null object from a raw pointer, so you consciously made the choice to ignore the possibility that the passed pointer is null. I don't see any way to be more "explicit" in case of object construction like this. |
I should not be able to accidentally create a null not_null. Imagine the API for S changed from being a raw pointer to being a not_null (or in this case C). This code should throw an exception to let me know that I'm doing the wrong thing, not let it go because I did not make a conscious choice to ignore the possibility it was null when it wasn't allowed - in my hypothetical example, when I made my conscious decision, it was allowed. Catching runtime errors due to programmer logic error is a significant part of what not_null is about. |
Sure, but making constructors explicit does not change anything to runtime check, it just forces you to think about it when compilation fails |
If you really need a free pass past the one-time on-creation null check, I'd suggest we make an additional type Oh, I did misunderstand the original question. |
It's not the point of this issue, nobody suggested changing the run time checks. The point here is just adding some compile time safeguards. |
That phrase in the original question is what threw me. What I guess he meant is that he's stating that he is aware that the pointer should not be null. |
I'm not a fan of the change (assuming I now understand it). I want to be able to put a not_null somewhere in my code when I just want to add a runtime check (and know that I'm safe from there on in) and not push that knowledge to the caller necessarily with an API change. It would be trivial to make your own not_null wrapper that added this functionality, but you can't write something that would take it away (I don't think). |
I fail to see where explicit constructor changes the situation you are describing. Maybe you have a precise example in mind ? |
say my API has a function some_function(int *) and it doesn't dereference that pointer until a long time later and I decide I want to know now that it's not null. So I just cahnge my function to take a not_null<int*> instead. My caller never has to care. They may be determining that hte pointer is valid in some other way or getting the pointer from some other system.. They may know that the pointer is valid without having to think about whether it's null or not. I don't want to push that extra information to them necessarily. |
In this case you don't have to change the signature of your function, you just check inside your function by creating a not_null from the parameter |
Well, at this point making a breaking change would be quite unfortunate. A new type can be made with a different behavior if it's desirable. And honestly I don't see it as being a very big win. It's more one of those "oh it's that compiler error again. I have to put a <copy>/<paste> thing around this to make it work. fine. Ok, now it's good" and when someone changes the behavior of the function whose return type you already wrapped in an explciit_not_null(some_func()) so that it can now return a null pointer, then it gets you absolutely nothing except more typing. |
this issue can be closed, now that #659 is merged |
Maintainers' call: Closing as #659 is merged. |
It seems to me that offering a conversion from
T
tonot_null<T>
looses the potential to detect certain bugs at compile-time.if I have a function that returns a raw (potentially null) pointer, and I carelessly pass it to a function taking not_null it will compile fine, and will try report a bug at run-time when it is likely too late.
Instead, if the constructor from
T
were explicit, an inadvertent assignment:use_ptr(make_ptr());
would be impossible, and I would be forced to explicitly require a potentially unsafe conversion:
This would be a kind of the signature: by writing this cast, I am taking the responsibility for guaranteeing that the raw pointer will not be null. If it is not the case, you will know that I did it consciously.
See also CppCoreGuidelines issue: isocpp/CppCoreGuidelines#767
The text was updated successfully, but these errors were encountered: