--
--
Chromium Developers mailing list: chromi...@chromium.org
View archives, change email options, or unsubscribe:
http://groups.google.com/a/chromium.org/group/chromium-dev
IMO, if the implementation doesn't actually dereference a null pointer, then it doesn't matter whether the incoming pointer is null.
You might as well just write your code without a pointer being passed at all. OTOH, if there is a dereference, then it's very unlikely that your code wouldn't crash.
So, I'd personally still prefer to avoid a bunch of redundant DCHECKs for non-nullness all over the codebase...
---
You received this message because you are subscribed to the Google Groups "Chromium-dev" group.
To unsubscribe from this group and stop receiving emails from it, send an email to chromium-dev...@chromium.org.
On Wed, Feb 24, 2016 at 2:50 PM, Ilya Sherman <ishe...@chromium.org> wrote:IMO, if the implementation doesn't actually dereference a null pointer, then it doesn't matter whether the incoming pointer is null.Counter-example:void Foo::AddToContainer(Container* container) {// |this| can't be nullptrcontainer->AddFoo(this);}void Container::DoSomethingOnAllFoos() {for (Foo* foo : foos_) {// |foo| can't be nullptrfoo->DoSomething();}}// foo must not be nullptrvoid RegisterFoo(Foo* foo) {// crash here if foo is nullptr, no need for DCHECK, right?foo->AddToContainer(g_container);}RegisterFoo(nullptr); // turns out this doesn't crash// [...]g_container->DoSomethingOnAllFoos(); // crash here...This would cause a crash inside Foo::DoSomething if it does use fields of Foo (or at the callsite if it's virtual). But at this point you have no clue where the nullptr foo comes from.Instead if you add the DCHECK in AddFoo then you know from the stack trace who was naughty and didn't respect the contract.This is not a contrived example. Replace Container::AddFoo by AddObserver or PostTask and you'll see how common the pattern can be in our codebase.
You might as well just write your code without a pointer being passed at all. OTOH, if there is a dereference, then it's very unlikely that your code wouldn't crash.What constitutes a dereference in the generated code (as opposed to the source code) is obviously not obvious...
To unsubscribe from this group and stop receiving emails from it, send an email to chromium-dev+unsubscribe@chromium.org.
--
--
Chromium Developers mailing list: chromi...@chromium.org
View archives, change email options, or unsubscribe:
http://groups.google.com/a/chromium.org/group/chromium-dev
---
You received this message because you are subscribed to the Google Groups "Chromium-dev" group.
To unsubscribe from this group and stop receiving emails from it, send an email to chromium-dev+unsubscribe@chromium.org.
On Wed, Feb 24, 2016 at 3:10 PM, Antoine Labour <pi...@google.com> wrote:On Wed, Feb 24, 2016 at 2:50 PM, Ilya Sherman <ishe...@chromium.org> wrote:IMO, if the implementation doesn't actually dereference a null pointer, then it doesn't matter whether the incoming pointer is null.Counter-example:void Foo::AddToContainer(Container* container) {// |this| can't be nullptrcontainer->AddFoo(this);}void Container::DoSomethingOnAllFoos() {for (Foo* foo : foos_) {// |foo| can't be nullptrfoo->DoSomething();}}// foo must not be nullptrvoid RegisterFoo(Foo* foo) {// crash here if foo is nullptr, no need for DCHECK, right?foo->AddToContainer(g_container);}RegisterFoo(nullptr); // turns out this doesn't crash// [...]g_container->DoSomethingOnAllFoos(); // crash here...This would cause a crash inside Foo::DoSomething if it does use fields of Foo (or at the callsite if it's virtual). But at this point you have no clue where the nullptr foo comes from.Instead if you add the DCHECK in AddFoo then you know from the stack trace who was naughty and didn't respect the contract.This is not a contrived example. Replace Container::AddFoo by AddObserver or PostTask and you'll see how common the pattern can be in our codebase.Agreed, and I do use DCHECKs in this sort of case, where a potentially null pointer is passed into one function, and then dereferenced later. But IMO that's pretty different than DCHECK(foo) immediately followed by a dereference of foo, as in the original example.
You might as well just write your code without a pointer being passed at all. OTOH, if there is a dereference, then it's very unlikely that your code wouldn't crash.What constitutes a dereference in the generated code (as opposed to the source code) is obviously not obvious...Sure, but does it matter? Either the generated code crashes, or the DCHECK is irrelevant.
+1. Storing a pointer in a map or vector or ObserverList etc for later use is super common.
To unsubscribe from this group and stop receiving emails from it, send an email to chromium-dev...@chromium.org.
--
--
Chromium Developers mailing list: chromi...@chromium.org
View archives, change email options, or unsubscribe:
http://groups.google.com/a/chromium.org/group/chromium-dev
---
You received this message because you are subscribed to the Google Groups "Chromium-dev" group.
To unsubscribe from this group and stop receiving emails from it, send an email to chromium-dev...@chromium.org.
The goal of the message is to clear up some misconceptions about when crashes actually happen on nullptrs. If the code is actually depending on a crash to point out invalid state (e.g. the caller incorrectly passed in nullptr), it is insufficient to simply have the code perform what looks like a dereference and call it a day.
In the code review I mentioned above, I thought I found a case where a DCHECK was redundant (pointer dereference), but it turned out the code didn't crash on a nullptr!
On Wed, Feb 24, 2016 at 4:39 PM, Robert Liao <rob...@chromium.org> wrote:The goal of the message is to clear up some misconceptions about when crashes actually happen on nullptrs. If the code is actually depending on a crash to point out invalid state (e.g. the caller incorrectly passed in nullptr), it is insufficient to simply have the code perform what looks like a dereference and call it a day.Agreed.In the code review I mentioned above, I thought I found a case where a DCHECK was redundant (pointer dereference), but it turned out the code didn't crash on a nullptr!That's sort of what I mean: DCHECKs are never redundant with pointer dereferences, because the pointer deref tells you the coder wanted the contents of that memory location, but the DCHECK tells you that a null pointer check wasn't forgotten and isn't necessary because the caller should have guaranteed this would be non-null.This is why in many places DCHECKs aren't necessary before mucking with pointers: the scope of the control flow is limited enough (e.g. helper functions within a class) that it's obvious a pointer won't be null, or the API makes no conceivable sense to use with null (e.g. View::AddChildView()). In such cases the DCHECK tells you no information you didn't already have.If you're trying to temporarily track down misuse of an API and want to crash sooner, use CHECK rather than DCHECK, and remove the CHECKs once the problem is gone. If you insert permanent DCHECKs that tell the coder nothing beyond what was already apparent, it's like inserting comments that restate the code; it decreases readability, and the potential gain of maybe catching potential misuse sooner someday is generally not worth the cost.Because this is a subjective readability issue, this will ultimately be up to author and reviewer
; but I would say, avoid DCHECKs in places where the precondition stated is already blindingly obvious. I definitely don't support rules like "always DCHECK pointers going into a container" any more than I support "never DCHECK such pointers".PK
--
On Wed, Feb 24, 2016 at 8:26 PM, Peter Kasting <pkas...@chromium.org> wrote:On Wed, Feb 24, 2016 at 4:39 PM, Robert Liao <rob...@chromium.org> wrote:The goal of the message is to clear up some misconceptions about when crashes actually happen on nullptrs. If the code is actually depending on a crash to point out invalid state (e.g. the caller incorrectly passed in nullptr), it is insufficient to simply have the code perform what looks like a dereference and call it a day.Agreed.In the code review I mentioned above, I thought I found a case where a DCHECK was redundant (pointer dereference), but it turned out the code didn't crash on a nullptr!That's sort of what I mean: DCHECKs are never redundant with pointer dereferences, because the pointer deref tells you the coder wanted the contents of that memory location, but the DCHECK tells you that a null pointer check wasn't forgotten and isn't necessary because the caller should have guaranteed this would be non-null.This is why in many places DCHECKs aren't necessary before mucking with pointers: the scope of the control flow is limited enough (e.g. helper functions within a class) that it's obvious a pointer won't be null, or the API makes no conceivable sense to use with null (e.g. View::AddChildView()). In such cases the DCHECK tells you no information you didn't already have.If you're trying to temporarily track down misuse of an API and want to crash sooner, use CHECK rather than DCHECK, and remove the CHECKs once the problem is gone. If you insert permanent DCHECKs that tell the coder nothing beyond what was already apparent, it's like inserting comments that restate the code; it decreases readability, and the potential gain of maybe catching potential misuse sooner someday is generally not worth the cost.Because this is a subjective readability issue, this will ultimately be up to author and reviewer+1, no reason to be dogmatic about this, use your best judgement.In general, calling objects on null objects is undefined behavior, which means it'll eventually be caught by an UBSan bot as long as your code has test coverage. (We don't have a working UBSan bot yet as far as I know, though). So there's no need to DCHECK every pointer in general, but if you're going to store it somewhere or something, DCHECK when you store it (or do whatever else your best judgement tells you) – but have test coverage :-)
; but I would say, avoid DCHECKs in places where the precondition stated is already blindingly obvious. I definitely don't support rules like "always DCHECK pointers going into a container" any more than I support "never DCHECK such pointers".PK--
--
Chromium Developers mailing list: chromi...@chromium.org
View archives, change email options, or unsubscribe:
http://groups.google.com/a/chromium.org/group/chromium-dev
--
--
Chromium Developers mailing list: chromi...@chromium.org
View archives, change email options, or unsubscribe:
http://groups.google.com/a/chromium.org/group/chromium-dev
Anyway, all that to say, let's not be dogmatic about "never DCHECK before a deref"
Brett
But there's a certain style of coding that I think we should be staying away from that with optional pointers all over the place. People insert null checks and assertions everywhere because they have no idea what's going on. Adding checks "just in case" because you dereference a pointer mostly adds noise, doesn't usually increase debugability, and I think encourages the general feeling of "pointers are optional."