-
Notifications
You must be signed in to change notification settings - Fork 5.4k
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
Pointers and the C++ Core Guidelines #847
Comments
That's not true,
Well you already said that
Your proposal seems to be "remove all raw pointers". I don't think that's necessary, or realistic. When raw pointers are no longer used for the owning and array cases (as the guidelines recommend) then raw pointers do serve well for the remaining cases. |
Thanks. I guess I must have misinterpreted the standard. But this isn't really a central premise of my argument. It still doesn't make a great deal of sense for a type which is supposed to represent a "single object" to support pointer arithmetic. As the guidelines note, pointer arithmetic is tricky, so why should it be supported for "single objects"?
My proposal isn't to remove all raw pointers; it's to provide strongly typed, recommended alternatives that do a much better job. Raw pointers will still exist in low-level and legacy code, and I mention later in the proposal that I do recommend that a bare EDIT I have corrected the incorrect information about pointer arithmetic, and added a disclaimer about the aim of the proposal. |
Our strategy in the core guidelines is to limit raw pointers to situations where they are harmless or unavoidable (e.g., string literals). We see no hope of eliminating all raw pointers in the billions of lines of C++ "out there". We do hope that we can provide a path for gradual elimination of unsafe and/or tricky uses. We know that at best such elimination will take many years. |
Do you aim to draw a distinction between what is "acceptable" and what is recommended? For example, the If the guidelines are focusing on making old C++ code safer rather than on best practices for new code, maybe I need to propose these things for standardization instead? |
Thanks for your interest and support. However, we do fundamentally believe that C did not distinguish in the type system between pointer to single objects and pointers used as array iterators, so we need to give a distinct name to each to distinguish them:
Additionally, we are actively writing a formalization of the Lifetime rules you can find in the /docs directory that does static dangling prevention. It's a general approach that is designed to work equally with dangling pointers and dangling We believe this approach is the best and most compatible for C++ code, and we're committed to following this direction. But we thank you for your interest and support; the Guidelines are definitely trying to tackle big problems, including this one. Thanks! |
Hi Herb Sutter. Thanks for taking the time to consider my suggestions and respond.
So do I. in fact, I would take this interface reduction one step further and make an un-annotated
By designating
I admit I am slightly puzzled by this mindset. What I'm hearing is, "Yes, Just to be clear, I don't think it is reasonable to expect all uses of
I hope I'm not labouring the point. It's just I feel that these are valid concerns that are being dismissed because of a failure to distinguish between best practices for new code, and pragmatic recommendations for updating old code. |
Thanks. Speaking to the first point:
I understand, and we considered that. We decided against that for several reasons:
For these and other reasons, we think that pointers should be nullable by default unless annotated otherwise.
I hope that helps reassure you that the concerns were considered deeply and aren't being dismissed, and apply both to new code and old code. Defaults are important, and should reflect the common case especially for new code, but also for old code much of which is "correct" but just expressed without enough information about the intent because the programmer didn't have the option or tool to express the intent. The key issue is to distinguish maybe-null and never-null in the type system, and both of our approaches agree on doing that. Tony Hoare called null pointers his "billion-dollar mistake," but in my opinion, and I think yours, the mistake was not maybe-null pointers (which are necessary, unavoidable, and pervasively present in every language with pointer/reference indirections, including Java, C#, C, C++, etc.), but rather in not distinguishing maybe-null and never-null pointers in the type system. You and we are both trying to do that, and so in the above I think we're largely agreeing and our discussion is narrowly just about which one should be the default. |
And in case I wasn't clear enough, I do think "nullable" is the correct default in brand-new clean code as the common case, even ignoring legacy issues. But to make it tool-enforceable, we to have enable programmers to state their intent of whether a given pointer variable is intended to be nullable or not; then we can write useful noise-free tools that ensure the code does the null check on all-and-only those pointers, which we believe can and will prevent null-deref bugs. Hence the importance of distinguishing it in the type to express the intent. |
You make a fair case for
Whether or not
Note: The naming of It is natural to provide different types for "retained" and "not retained" indirections. If you aren't retaining an indirection, chances are you only care about the value of the referenced object, so it makes sense to use The (overlapping) concerns about
There is also the concern that use of |
Thanks. I responded to it because it was your first point, and you'd put a lot of thought into it and I felt it deserved a more detailed response than "yes we thought of all those things." I didn't have cycles to respond in equal detail to everything, so I picked the first, but the other points were considered too. Thanks for summarizing your major concerns, I'll try to give one more set of responses to those:
Assuming by type-safety you mean not dereferencing null: The Lifetime rules I referred to include adding some static safety for
We agree that the
This is also covered in the Lifetime static rules.
So we prefer general rules that work for more than just pointers, and work for more than just "retain" semantics, to express non-owning lifetime safely.
Cannot compare unless you dereference to compare Even if you don't agree with our conclusions on some of these, at least please be assured that they're not being dismissed. We did consider them and are aware of these issues, as well as more general ones as we consider also things like iterator invalidation issues as well as we aim for a single consistent model. |
If I encounter a T* I don’t know if the original author meant T* in the sense of these guidelines or not, so I need to look carefully at the code and decide if it should be changed to not_null<T*> or left alone (for the next person to ask the same question). I’d rather be explicit and use maybe_null<T*> and not_null<T*>. Then when I see T*, I know it’s older code or code written by someone not following these guidelines, and I can then determine how to modernize it. |
Thanks, and I appreciate it. I didn't mean to make it sound like I didn't appreciate your response. Despite being the lesser of my concerns, I wouldn't have mentioned it if I didn't want to discuss it.
By "type-safety", I am referring to the aforementioned inability of C++ to distinguish between never-null and maybe-null pointers. But yeah, it comes down to preventing null pointer dereferencing.
I assume you meant that
What I am proposing can be checked under the lifetime rules as they stand.
I cannot use
Note that I am proposing the addition of
Thanks. I'm glad you are considering these things. However, we clearly don't see eye to eye. My view is that |
I'm not sure about the naming everything, but I see a lot of sense in using specific types for everything. Then, as elronayellin noted, |
Can someone explain what is not_null and maybe null? |
Using the not_null Template for Pointers That Must Never Be Null |
Where can I find an implementation? |
@pold500 read the link in the previous comment. |
|
First of all, thank you to everyone involved in the development of the C++ Core Guidelines and the GSL. Your work is invaluable and will undoubtedly be appreciated by generations of C++ programmers to come. With that in mind, I am concerned about the advice in the guidelines regarding the use of pointers, and have written a document outlining my thoughts, which can be summarised as:
T*
to represent "single objects" in high-level C++ code is less than idealowner<T>
This document has been some time in the works, and has undergone many revisions, but it is now in a state that I am happy to share here. I would very much appreciate your consideration of my ideas, and welcome any comments or feedback. I believe it to be of utmost importance that the advice laid out in the guidelines is the best it can be. Please follow the link below to find the document with accompanying source code and unit tests.
[GitHub] Pointers and the C++ Core Guidelines
Joseph
The text was updated successfully, but these errors were encountered: