July 09, 2017 Re: Automatic invariant generation | ||||
---|---|---|---|---|
| ||||
Posted in reply to Nicholas Wilson | On 7/7/2017 7:31 AM, Nicholas Wilson wrote:
> asserts that the this pointer is not null, apparently which is annoying because you'd crash anyway. I suppose you might get a nicer error message but it doesn't add much.
If I recall correctly, the nicer message was the reason. (It was a long time ago.)
This kind of thing has been asked for, a lot. The current thread entitled:
"All asserts need to have messages attached! Explicit as possible!"
is representative.
|
July 09, 2017 Re: Automatic invariant generation | ||||
---|---|---|---|---|
| ||||
Posted in reply to Walter Bright | On 7/9/17 5:14 AM, Walter Bright wrote:
> On 7/7/2017 7:31 AM, Nicholas Wilson wrote:
>> asserts that the this pointer is not null, apparently which is annoying because you'd crash anyway. I suppose you might get a nicer error message but it doesn't add much.
>
> If I recall correctly, the nicer message was the reason. (It was a long time ago.)
>
> This kind of thing has been asked for, a lot. The current thread entitled:
>
> "All asserts need to have messages attached! Explicit as possible!"
>
> is representative.
Wait, you have stated many many times, a segfault is good enough, it's not worth the added cost to do null pointer exceptions (a position I'm completely in agreement with). Yet, here is an example of where we have effectively added a null pointer exception. At the very least, this should be eliminated on Linux and just use the signal handling null pointer error mechanism!
Note that there is a significant difference between this situation (where you are *adding* an extra check), and the argument to add messages to asserts (where you are *already* asserting). For the record, I also don't agree that all asserts need messages.
Also noted, even if you inline, the assert is still there. Those who want to keep asserts (particularly for safety reasons), will pay this penalty.
In things like smart pointer wrappers or converters, many things are properties. inlining these is supposed to boil down to simply accessing the right field, with zero added cost. That is also a lie.
Or factoring out pieces of a function into more modular member functions. Now you are compounding the asserts. When calling another member function from within one, there is no reason to re-assert `this !is null`.
We need to get rid of this feature, or at least make it optional (and by optional, I mean opt-in). And no, having -release remove all asserts is not the same as having the ability to eliminate asserts I never wrote or wanted. At least the assert shouldn't appear in virtual functions (which will never fail because the vlookup will segfault before it ever gets there).
I've been using D for 10 years, and have never triggered this assert. But I've apparently paid for it that entire time.
-Steve
|
July 09, 2017 Re: Automatic invariant generation | ||||
---|---|---|---|---|
| ||||
Posted in reply to Steven Schveighoffer | On Sunday, 9 July 2017 at 10:37:53 UTC, Steven Schveighoffer wrote:
> On 7/9/17 5:14 AM, Walter Bright wrote:
>> On 7/7/2017 7:31 AM, Nicholas Wilson wrote:
>>> asserts that the this pointer is not null, apparently which is annoying because you'd crash anyway. I suppose you might get a nicer error message but it doesn't add much.
>>
>> If I recall correctly, the nicer message was the reason. (It was a long time ago.)
>>
>> This kind of thing has been asked for, a lot. The current thread entitled:
>>
>> "All asserts need to have messages attached! Explicit as possible!"
>>
>> is representative.
>
> Wait, you have stated many many times, a segfault is good enough, it's not worth the added cost to do null pointer exceptions (a position I'm completely in agreement with). Yet, here is an example of where we have effectively added a null pointer exception. At the very least, this should be eliminated on Linux and just use the signal handling null pointer error mechanism!
>
> Note that there is a significant difference between this situation (where you are *adding* an extra check), and the argument to add messages to asserts (where you are *already* asserting). For the record, I also don't agree that all asserts need messages.
>
> Also noted, even if you inline, the assert is still there. Those who want to keep asserts (particularly for safety reasons), will pay this penalty.
>
> In things like smart pointer wrappers or converters, many things are properties. inlining these is supposed to boil down to simply accessing the right field, with zero added cost. That is also a lie.
>
> Or factoring out pieces of a function into more modular member functions. Now you are compounding the asserts. When calling another member function from within one, there is no reason to re-assert `this !is null`.
>
> We need to get rid of this feature, or at least make it optional (and by optional, I mean opt-in). And no, having -release remove all asserts is not the same as having the ability to eliminate asserts I never wrote or wanted. At least the assert shouldn't appear in virtual functions (which will never fail because the vlookup will segfault before it ever gets there).
>
> I've been using D for 10 years, and have never triggered this assert. But I've apparently paid for it that entire time.
>
> -Steve
In C++, but I recently ran across this problem debugging LLVM and wasted a good while trying to figure out what was causing the crash. This would have been a useful feature (actually if i had been comping in debug mode I would have hit that informative assert but I was too stubborn to recompile), so it does have its place but I think on by default is not it and certainly if it is not under my control.
The most annoying part is that the struct will _never_ be passed by pointer, its a struct that contains a struct that contains a pointer, POD if ever there was. In the older models of OpenCL you can't have pointers to pointers _at all_ so by definition the assert will never be triggered.
|
July 09, 2017 Re: Automatic invariant generation | ||||
---|---|---|---|---|
| ||||
Posted in reply to Steven Schveighoffer | On 7/9/2017 3:37 AM, Steven Schveighoffer wrote: > Wait, you have stated many many times, a segfault is good enough, it's not worth the added cost to do null pointer exceptions (a position I'm completely in agreement with). That's right. > Yet, here is an example of where we have effectively added a null pointer exception. > At the very least, this should be eliminated on Linux > and just use the signal handling null pointer error mechanism! You're a few years late, as pretty much nobody agreed with me that the operating system handling of it was plenty. > Note that there is a significant difference between this situation (where you are *adding* an extra check), and the argument to add messages to asserts (where you are *already* asserting). It's not really different. It's the desire for ever more messages. I've long advocated that a file/line is quite sufficient, but I seem to be in a tiny minority of 1. Now 2. :-) > Also noted, even if you inline, the assert is still there. Those who want to keep asserts (particularly for safety reasons), will pay this penalty. Yup. Though at one point I advocated an option to replace the assert fails with a HLT instruction. > I've been using D for 10 years, and have never triggered this assert. But I've apparently paid for it that entire time. It's always worth looking at the assembler output now and then. --- The thing is, the bloat from all these messages and checks has caused DMD to be compiled with -release. Oops, that let through a few bugs. |
July 09, 2017 Re: Automatic invariant generation | ||||
---|---|---|---|---|
| ||||
Posted in reply to Steven Schveighoffer | On 7/7/2017 7:26 AM, Steven Schveighoffer wrote: > And since when did we care about null pointers causing segfaults? Remember Tony Hoare's "The Billion Dollar Mistake"? That added a lot of fuel to the fire that a null pointer seg fault is supposed to be avoided at all costs, leading to wanting a softer, friendlier assert message instead. I strongly disagree with Hoare - the billion dollar C mistake is having arrays relentlessly decay to pointers, leading to endless buffer overflow bugs. Seg faults aren't malware vectors. > Can anyone vouch for this feature? I'm sure if you're willing to spend a while searching this n.g. database, you'll find a lot. |
July 09, 2017 Re: Automatic invariant generation | ||||
---|---|---|---|---|
| ||||
Posted in reply to Nicholas Wilson | On 7/7/2017 7:08 AM, Nicholas Wilson wrote:
> It is certainly unacceptable in the long run to demand that if users wish to use DCompute that they can't have asserts _in the code running in the host_.
One thing you can do is replace:
assert(i > 3);
with:
if (!(i > 3)) assert(0);
which won't be removed with -release, and the only bloat will be a lovely HLT instruction.
|
July 09, 2017 Re: Automatic invariant generation | ||||
---|---|---|---|---|
| ||||
Posted in reply to Walter Bright | On Sunday, 9 July 2017 at 11:13:02 UTC, Walter Bright wrote:
> On 7/7/2017 7:08 AM, Nicholas Wilson wrote:
>> It is certainly unacceptable in the long run to demand that if users wish to use DCompute that they can't have asserts _in the code running in the host_.
>
> One thing you can do is replace:
>
> assert(i > 3);
>
> with:
>
> if (!(i > 3)) assert(0);
>
> which won't be removed with -release, and the only bloat will be a lovely HLT instruction.
Of course I could do that for _my_ code , but I am not every end user, and even if I was doing the above is not a good use of my time.
And this wouldn't be so bad if it were code that I or someone else had written, but the fact that the compiler inserts it and I didn't ask for it and, save from hacking the compiler, I can't make it do otherwise.
|
July 09, 2017 Re: Automatic invariant generation | ||||
---|---|---|---|---|
| ||||
Posted in reply to Walter Bright | On 7/9/17 7:00 AM, Walter Bright wrote: > On 7/9/2017 3:37 AM, Steven Schveighoffer wrote: >> Yet, here is an example of where we have effectively added a null pointer exception. > At the very least, this should be eliminated on Linux >> and just use the signal handling null pointer error mechanism! > > You're a few years late, as pretty much nobody agreed with me that the operating system handling of it was plenty. I think you misunderstand, we have etc.linux.memoryerror that can actually throw an error on a null pointer using the signal handler. I have a suggestion: eliminate this feature, and add a -npe switch to the compiler that errors on any null pointer usage. Asserts will be sprinkled in everywhere, but may be useful to someone debugging a nasty null pointer segfault somewhere. -Steve |
July 09, 2017 Re: Automatic invariant generation | ||||
---|---|---|---|---|
| ||||
Posted in reply to Steven Schveighoffer | On Sunday, 9 July 2017 at 11:37:55 UTC, Steven Schveighoffer wrote:
> On 7/9/17 7:00 AM, Walter Bright wrote:
>> On 7/9/2017 3:37 AM, Steven Schveighoffer wrote:
>
>>> Yet, here is an example of where we have effectively added a null pointer exception. > At the very least, this should be eliminated on Linux
>>> and just use the signal handling null pointer error mechanism!
>>
>> You're a few years late, as pretty much nobody agreed with me that the operating system handling of it was plenty.
>
> I think you misunderstand, we have etc.linux.memoryerror that can actually throw an error on a null pointer using the signal handler.
>
> I have a suggestion: eliminate this feature, and add a -npe switch to the compiler that errors on any null pointer usage. Asserts will be sprinkled in everywhere, but may be useful to someone debugging a nasty null pointer segfault somewhere.
>
> -Steve
I think the generated assert(this !is null) has its place, it is useful to catch a null this as early as possible but not by default. Perhaps debug mode (as in the compiler switch) or a switch of its own.
|
July 09, 2017 Re: Automatic invariant generation | ||||
---|---|---|---|---|
| ||||
Posted in reply to Walter Bright | On 7/9/17 7:10 AM, Walter Bright wrote: > On 7/7/2017 7:26 AM, Steven Schveighoffer wrote: >> And since when did we care about null pointers causing segfaults? > > Remember Tony Hoare's "The Billion Dollar Mistake"? That added a lot of fuel to the fire that a null pointer seg fault is supposed to be avoided at all costs, leading to wanting a softer, friendlier assert message instead. > > I strongly disagree with Hoare - the billion dollar C mistake is having arrays relentlessly decay to pointers, leading to endless buffer overflow bugs. Seg faults aren't malware vectors. But this isn't that. This is asserting a certain type of pointer (the this pointer), which is almost NEVER null, isn't null. It's so ineffective, I've never seen it trigger in 10 years. It's basically the worst possible place to deviate from the rule of "we don't do null pointer exceptions". >> Can anyone vouch for this feature? > > I'm sure if you're willing to spend a while searching this n.g. database, you'll find a lot. I've seen a lot of people argue on the n.g. that null pointer checks should be added for every pointer dereference. I've NEVER seen anyone argue that upon every member function call, the compiler should verify `this` isn't null. Of course, why would they? it's already there :P I'm seeing a large swath of well-known people arguing in this thread that it shouldn't work this way, and 0 people defending it. -Steve |
Copyright © 1999-2021 by the D Language Foundation