digitalmars.D - safety: null checks
- Dibyendu Majumdar (17/17) Nov 22 2020 import core.stdc.stdio : printf;
- Q. Schroll (6/8) Nov 22 2020 Nullpointer exceptions aren't a safety issue since the program
- Dibyendu Majumdar (2/10) Nov 22 2020 Right. A crash isn't a bad consequence, of course.
- Paul Backus (5/16) Nov 22 2020 Memory safety is concerned specifically with avoiding undefined
- Ola Fosheim Grostad (3/6) Nov 22 2020 I understand what you mean, but at high optimization levels
- Paul Backus (5/11) Nov 22 2020 Then that's a bug in the compiler. A @safe D program is allowed
- Ola Fosheim Grostad (3/6) Nov 22 2020 Where does it say that? This won't work on embedded platforms.
- Paul Backus (12/22) Nov 22 2020 Ok, technically, a spec-confirming D implementation must either
- Dibyendu Majumdar (3/15) Nov 22 2020 Hmm, null values are not the same as dereferncing null values.
- Paul Backus (9/11) Nov 22 2020 @safe code is allowed to dereference pointers, and there's no way
- Ola Fosheim Grostad (10/22) Nov 22 2020 Well, the spec said that the value should be valid, which null by
- Paul Backus (9/29) Nov 22 2020 Please show me the definition of null that requires it to be
- Ola Fosheim Grostad (9/16) Nov 22 2020 null points to nothing, that is not a valid value for the
- Patrick Schluter (16/32) Nov 23 2020 No. null is not a trap representation as a C standard would call
- Ola Fosheim =?UTF-8?B?R3LDuHN0YWQ=?= (13/26) Nov 23 2020 A trap is an interrupt at the hardware level. It has nothing to
- Patrick Schluter (10/17) Nov 23 2020 Read the C standard, they explain what a trap representation is.
- Ola Fosheim Grostad (5/13) Nov 23 2020 When I intoduced the word "trap" in this discussion I used the
- Patrick Schluter (12/26) Nov 24 2020 I introduced the expression "trap representation" from the C
- Ola Fosheim =?UTF-8?B?R3LDuHN0YWQ=?= (7/9) Nov 24 2020 I don't know what you are problem is here.
- Ola Fosheim =?UTF-8?B?R3LDuHN0YWQ=?= (15/21) Nov 24 2020 Another note, please stop assuming what people are trying to
- ag0aep6g (10/20) Nov 22 2020 I wrote that part of the spec. My intent was to define null as a
- Paul Backus (2/5) Nov 22 2020 https://github.com/dlang/dlang.org/pull/2884
- Ola Fosheim Grostad (6/9) Nov 22 2020 It traps null dereferencing unless the object is very large.
- ag0aep6g (16/25) Nov 22 2020 What I meant is that DMD allows dereferencing null in @safe code.
- Ola Fosheim =?UTF-8?B?R3LDuHN0YWQ=?= (17/31) Nov 23 2020 Yes, the implementation dereferences null and traps it, but the
- Dibyendu Majumdar (2/5) Nov 22 2020 what spec? :)
- Johan Engelen (17/23) Nov 23 2020 I'll reiterate what I've been saying many times already: in LDC,
- Paul Backus (2/15) Nov 23 2020 Then LDC allows memory corruption in @safe code, which is a bug.
- Johan Engelen (6/16) Nov 23 2020 Correct. And so do all other D compilers. Completely independent
- Paul Backus (4/12) Nov 23 2020 Maybe it is for LDC. I suspect Walter puts a high enough priority
- Dibyendu Majumdar (11/27) Nov 23 2020 Hi,
- Max Haughton (12/29) Nov 22 2020 Keep in mind that to find a null pointer, you must first invent
- Adam D. Ruppe (15/17) Nov 22 2020 Try this just for laughs:
import core.stdc.stdio : printf; extern (C++) abstract class A { void sayHello(); } extern (C++) class B : A { override void sayHello() { printf("hello\n"); } } extern (C) void main() { //scope b = new B; B b; assert(b); b.sayHello(); } Above fails because b is null. But why doesn't the compiler say so? It seems like a very basic safety check.
Nov 22 2020
On Sunday, 22 November 2020 at 11:52:13 UTC, Dibyendu Majumdar wrote:Above fails because b is null. But why doesn't the compiler say so? It seems like a very basic safety check.Nullpointer exceptions aren't a safety issue since the program crashes. For it to be a safety issue, it would need to have "bad consequences" e.g. writes to memory at locations the program isn't supposed to.
Nov 22 2020
On Sunday, 22 November 2020 at 15:25:48 UTC, Q. Schroll wrote:On Sunday, 22 November 2020 at 11:52:13 UTC, Dibyendu Majumdar wrote:Right. A crash isn't a bad consequence, of course.Above fails because b is null. But why doesn't the compiler say so? It seems like a very basic safety check.Nullpointer exceptions aren't a safety issue since the program crashes. For it to be a safety issue, it would need to have "bad consequences" e.g. writes to memory at locations the program isn't supposed to.
Nov 22 2020
On Sunday, 22 November 2020 at 22:16:11 UTC, Dibyendu Majumdar wrote:On Sunday, 22 November 2020 at 15:25:48 UTC, Q. Schroll wrote:Memory safety is concerned specifically with avoiding undefined behavior. Crashing the program isn't undefined behavior, so it's allowed in safe code.On Sunday, 22 November 2020 at 11:52:13 UTC, Dibyendu Majumdar wrote:Right. A crash isn't a bad consequence, of course.Above fails because b is null. But why doesn't the compiler say so? It seems like a very basic safety check.Nullpointer exceptions aren't a safety issue since the program crashes. For it to be a safety issue, it would need to have "bad consequences" e.g. writes to memory at locations the program isn't supposed to.
Nov 22 2020
On Sunday, 22 November 2020 at 22:36:40 UTC, Paul Backus wrote:Memory safety is concerned specifically with avoiding undefined behavior. Crashing the program isn't undefined behavior, so it's allowed in safe code.I understand what you mean, but at high optimization levels dereferencing a null pointer can trigger undefined behaviour.
Nov 22 2020
On Sunday, 22 November 2020 at 23:00:25 UTC, Ola Fosheim Grostad wrote:On Sunday, 22 November 2020 at 22:36:40 UTC, Paul Backus wrote:Then that's a bug in the compiler. A safe D program is allowed to dereference null, so a spec-conformant D compiler *must* ensure that dereferencing null has defined behavior.Memory safety is concerned specifically with avoiding undefined behavior. Crashing the program isn't undefined behavior, so it's allowed in safe code.I understand what you mean, but at high optimization levels dereferencing a null pointer can trigger undefined behaviour.
Nov 22 2020
On Sunday, 22 November 2020 at 23:28:26 UTC, Paul Backus wrote:Then that's a bug in the compiler. A safe D program is allowed to dereference null, so a spec-conformant D compiler *must* ensure that dereferencing null has defined behavior.Where does it say that? This won't work on embedded platforms. Not being allowed to reject buggy code would be bad...
Nov 22 2020
On Sunday, 22 November 2020 at 23:46:23 UTC, Ola Fosheim Grostad wrote:On Sunday, 22 November 2020 at 23:28:26 UTC, Paul Backus wrote:Ok, technically, a spec-confirming D implementation must either guarantee that dereferencing null has defined behavior, *or* forbid default initialization of pointers in safe code. The relevant part of the spec is the one on "safe values" [1]:Then that's a bug in the compiler. A safe D program is allowed to dereference null, so a spec-conformant D compiler *must* ensure that dereferencing null has defined behavior.Where does it say that? This won't work on embedded platforms. Not being allowed to reject buggy code would be bad...A pointer is safe when: 1. it can be dereferenced validly [i.e. with defined behavior], and 2. the value of the pointee is safe.If null is a safe value, then dereferencing it must be defined behavior. If null is an unsafe value, then it must not be allowed to appear in safe code. Either way, a compiler that allows null in safe code but treats a null dereference as undefined behavior is buggy. [1] https://dlang.org/spec/function.html#safe-values
Nov 22 2020
On Monday, 23 November 2020 at 00:17:12 UTC, Paul Backus wrote:The relevant part of the spec is the one on "safe values" [1]:Hmm, null values are not the same as dereferncing null values. A null in itself is okay, but dereferencing null cannot be.A pointer is safe when: 1. it can be dereferenced validly [i.e. with defined behavior], and 2. the value of the pointee is safe.If null is a safe value, then dereferencing it must be defined behavior. If null is an unsafe value, then it must not be allowed to appear in safe code. Either way, a compiler that allows null in safe code but treats a null dereference as undefined behavior is buggy. [1] https://dlang.org/spec/function.html#safe-values
Nov 22 2020
On Monday, 23 November 2020 at 00:26:26 UTC, Dibyendu Majumdar wrote:Hmm, null values are not the same as dereferncing null values. A null in itself is okay, but dereferencing null cannot be.safe code is allowed to dereference pointers, and there's no way for the compiler to know at compile time which pointers are null and which aren't. So, either safe code must be forbidden from creating null pointers in the first place, or it must be allowed to dereference them. Remember, safe doesn't just mean "code that's memory safe", it means "code that the compiler can *prove* is memory safe."
Nov 22 2020
On Monday, 23 November 2020 at 00:33:35 UTC, Paul Backus wrote:On Monday, 23 November 2020 at 00:26:26 UTC, Dibyendu Majumdar wrote:Well, the spec said that the value should be valid, which null by definition should not have, then the example comment mentioned a well defined crash which is a contradiction in terms. So the spec is unsound. What you would require from a high level language is that dereferencing null pointers is caught either at compile time or at runtime. But that is slow on some platforms. So this is just an example of the implementation being the spec, and actual document does not make sense in a general setting.Hmm, null values are not the same as dereferncing null values. A null in itself is okay, but dereferencing null cannot be.safe code is allowed to dereference pointers, and there's no way for the compiler to know at compile time which pointers are null and which aren't. So, either safe code must be forbidden from creating null pointers in the first place, or it must be allowed to dereference them. Remember, safe doesn't just mean "code that's memory safe", it means "code that the compiler can *prove* is memory safe."
Nov 22 2020
On Monday, 23 November 2020 at 00:50:03 UTC, Ola Fosheim Grostad wrote:On Monday, 23 November 2020 at 00:33:35 UTC, Paul Backus wrote:Please show me the definition of null that requires it to be invalid.safe code is allowed to dereference pointers, and there's no way for the compiler to know at compile time which pointers are null and which aren't. So, either safe code must be forbidden from creating null pointers in the first place, or it must be allowed to dereference them. Remember, safe doesn't just mean "code that's memory safe", it means "code that the compiler can *prove* is memory safe."Well, the spec said that the value should be valid, which null by definition should not have,then the example comment mentioned a well defined crash which is a contradiction in terms. So the spec is unsound.Please show me the relevant definitions of these terms and explain how they contradict.What you would require from a high level language is that dereferencing null pointers is caught either at compile time or at runtime. But that is slow on some platforms. So this is just an example of the implementation being the spec, and actual document does not make sense in a general setting.The implementation allows undefined behavior in safe code. That means the implementation is incorrect, period. Neither of the possible interpretations of the spec allow this.
Nov 22 2020
On Monday, 23 November 2020 at 01:04:38 UTC, Paul Backus wrote:Please show me the definition of null that requires it to be invalid.null points to nothing, that is not a valid value for the referenced type. Trivially invalid.Please show me the relevant definitions of these terms and explain how they contradict.What do mean? A crash is by definition undefined behaviour. The spec does not provide adequate definitions and requirements, which is what makes it unsound.The implementation allows undefined behavior in safe code. That means the implementation is incorrect, period. Neither of the possible interpretations of the spec allow this.The spec isn't well defined or consistent just because people claim things in the forum.
Nov 22 2020
On Monday, 23 November 2020 at 01:29:12 UTC, Ola Fosheim Grostad wrote:On Monday, 23 November 2020 at 01:04:38 UTC, Paul Backus wrote:No. null is not a trap representation as a C standard would call it. It is a valid value for a pointer. Dereferencing it is an entirely other thing.Please show me the definition of null that requires it to be invalid.null points to nothing, that is not a valid value for the referenced type.Trivially invalid.Nope.Nope. In the case of D. The error generated by dereferencing a null pointer is a defined behaviour. As defined as is calling abort() in a C program. Catching the error and continuing processing that would be undefined behaviour.Please show me the relevant definitions of these terms and explain how they contradict.What do mean? A crash is by definition undefined behaviour.The spec does not provide adequate definitions and requirements, which is what makes it unsound.The issue with null pointer dereferencing has nothing to do with its definition but with its implementation as the defined behaviour of aborting the program is not guaranteed in all circumstances (null pointer + offset big enough to hit a real page).The implementation allows undefined behavior in safe code. That means the implementation is incorrect, period. Neither of the possible interpretations of the spec allow this.The spec isn't well defined or consistent just because people claim things in the forum.
Nov 23 2020
On Monday, 23 November 2020 at 12:28:39 UTC, Patrick Schluter wrote:No. null is not a trap representation as a C standard would call it. It is a valid value for a pointer. Dereferencing it is an entirely other thing.A trap is an interrupt at the hardware level. It has nothing to do with C.Yes. "nothing" in not a valid value for "int". That is trivially invalid. Try to think of null as an empty set.Trivially invalid.Nope.Nope. In the case of D. The error generated by dereferencing a null pointer is a defined behaviour. As defined as is calling abort() in a C program.You are speaking of DMD, not the spec?The issue with null pointer dereferencing has nothing to do with its definition but with its implementation as the defined behaviour of aborting the program is not guaranteed in all circumstances (null pointer + offset big enough to hit a real page).My argument is based on the spec and what is required to get to something that is consistent/sound and portable. Also, as it has been pointed out, it does not work this way in shipping compilers so the spec should provide implemtation notes on what actually happens in shipping compilers.
Nov 23 2020
On Monday, 23 November 2020 at 12:39:05 UTC, Ola Fosheim Grøstad wrote:On Monday, 23 November 2020 at 12:28:39 UTC, Patrick Schluter wrote:Read the C standard, they explain what a trap representation is. It has nothing to do with an interrupt. I refer to the C standard because they make the difference between allowed pointer values and unallowed values even if never dereferenced. Read the selected answer on this stackoverflow [1] page, he explains it better than me. [1]: https://stackoverflow.com/questions/6725809/trap-representationNo. null is not a trap representation as a C standard would call it. It is a valid value for a pointer. Dereferencing it is an entirely other thing.A trap is an interrupt at the hardware level. It has nothing to do with C.
Nov 23 2020
On Monday, 23 November 2020 at 20:00:29 UTC, Patrick Schluter wrote:On Monday, 23 November 2020 at 12:39:05 UTC, Ola Fosheim Grøstad wrote:When I intoduced the word "trap" in this discussion I used the traditional hardware terminology as used in Motorola 68K reference manuals. Has nothing to do with C whatsoever.A trap is an interrupt at the hardware level. It has nothing to do with C.Read the C standard, they explain what a trap representation is. It has nothing to do with an interrupt. I refer to the C standard because they make the difference between allowed pointer values and unallowed values even if never dereferenced.
Nov 23 2020
On Tuesday, 24 November 2020 at 00:08:57 UTC, Ola Fosheim Grostad wrote:On Monday, 23 November 2020 at 20:00:29 UTC, Patrick Schluter wrote:I introduced the expression "trap representation" from the C standard (and I specified explicitly the context I said "null is not a trap representation as a C standard would call it."). only be done either in bad faith, either from stupidity*. Choose your case. Bye, no further involvement from my part. * I know it's a false dichotomy, there's a third possibility but it is not positive for you either (you misunderstood and are too proud to admit it).On Monday, 23 November 2020 at 12:39:05 UTC, Ola Fosheim Grøstad wrote:When I intoduced the word "trap" in this discussion I used the traditional hardware terminology as used in Motorola 68K reference manuals. Has nothing to do with C whatsoever.A trap is an interrupt at the hardware level. It has nothing to do with C.Read the C standard, they explain what a trap representation is. It has nothing to do with an interrupt. I refer to the C standard because they make the difference between allowed pointer values and unallowed values even if never dereferenced.
Nov 24 2020
On Tuesday, 24 November 2020 at 08:47:03 UTC, Patrick Schluter wrote:only be done either in bad faith, either from stupidity*.I don't know what you are problem is here. Motorola terminology: trap Intel terminology: exception Both mean interrupt. I chose to use the term "trap" to avoid confusion.
Nov 24 2020
On Tuesday, 24 November 2020 at 08:47:03 UTC, Patrick Schluter wrote:I introduced the expression "trap representation" from the C standard (and I specified explicitly the context I said "null is not a trap representation as a C standard would call it."). only be done either in bad faith, either from stupidity*. Choose your case.Another note, please stop assuming what people are trying to cause harm to you. It is not productive. In case there is any doubt: I wrote "trap" with then intent of referring to a hardware exception. You seemed to read that in a more general sense and brought in the C standard, which is not relevant. So I can only assume that my intent was not conveyed as clearly as I wanted therefore I tried to make it clear. I apologize if you take offense by my attempt to make my intent clear. The C standard terminology is actually of no relevance when discussing the wording of the D spec: The pointee (object) is not valid for a null pointer, so it is indeed invalid (the pointee is).
Nov 24 2020
On Monday, 23 November 2020 at 00:50:03 UTC, Ola Fosheim Grostad wrote:Well, the spec said that the value should be valid, which null by definition should not have, then the example comment mentioned a well defined crash which is a contradiction in terms. So the spec is unsound.I wrote that part of the spec. My intent was to define null as a safe value. For other pointer-like types I wrote: "A [thing] is safe when it is `null` or [whatever]". Please feel free to add that phrase for pointers, too, or adjust the text in any other way that makes it more clear that null is a safe value.What you would require from a high level language is that dereferencing null pointers is caught either at compile time or at runtime. But that is slow on some platforms. So this is just an example of the implementation being the spec, and actual document does not make sense in a general setting.The reference implementation treats null as a safe value. Yes, that can imply additional checks at run time. That's what Walter chose, for better or worse.
Nov 22 2020
On Monday, 23 November 2020 at 01:26:15 UTC, ag0aep6g wrote:Please feel free to add that phrase for pointers, too, or adjust the text in any other way that makes it more clear that null is a safe value.https://github.com/dlang/dlang.org/pull/2884
Nov 22 2020
On Monday, 23 November 2020 at 01:26:15 UTC, ag0aep6g wrote:The reference implementation treats null as a safe value. Yes, that can imply additional checks at run time. That's what Walter chose, for better or worse.It traps null dereferencing unless the object is very large. I think it should state clearly whether that is portable or specific for Posix-like systems. Does it require explicit null check conditionals on platforms that do not provide traps? That is what has to be clarified.
Nov 22 2020
On Monday, 23 November 2020 at 01:36:38 UTC, Ola Fosheim Grostad wrote:On Monday, 23 November 2020 at 01:26:15 UTC, ag0aep6g wrote:What I meant is that DMD allows dereferencing null in safe code. Since safe code must not corrupt memory, it must then take the necessary steps to make that safe. I'm pretty sure that DMD doesn't actually take the necessary steps (as you say, it ignores large objects). And I'm not sure if Walter has fully considered the implications, but he has made it clear that null is supposed to be a safe value. And that can be made to work fairly easily, at the cost of run-time checks. Maybe treating null as unsafe could also work, but that would need a lot more design work.The reference implementation treats null as a safe value. Yes, that can imply additional checks at run time. That's what Walter chose, for better or worse.It traps null dereferencing unless the object is very large.I think it should state clearly whether that is portable or specific for Posix-like systems. Does it require explicit null check conditionals on platforms that do not provide traps? That is what has to be clarified.I think that's an implementation detail. An implementation must ensure that null is safe (at least in safe code). We don't really care how it does that, but adding checks before every dereference is the obvious solution.
Nov 22 2020
On Monday, 23 November 2020 at 02:21:20 UTC, ag0aep6g wrote:What I meant is that DMD allows dereferencing null in safe code. Since safe code must not corrupt memory, it must then take the necessary steps to make that safe.Yes, the implementation dereferences null and traps it, but the in terms of the language it prevents dereferencing of null and terminates (as the dereferencing is supposed to be without other side effects than termination).I'm pretty sure that DMD doesn't actually take the necessary steps (as you say, it ignores large objects). And I'm not sure if Walter has fully considered the implications, but he has made it clear that null is supposed to be a safe value. And that can be made to work fairly easily, at the cost of run-time checks. Maybe treating null as unsafe could also work, but that would need a lot more design work.Yes, that does pose problems with objects of variable size. So then you either have to put a limit of how large objects nullable pointers are allowed to point to or add runtime checks. This is a good reason to add nonnullable pointers to the language. That would reduce the number of places where you need dynamic checks.I think that's an implementation detail. An implementation must ensure that null is safe (at least in safe code). We don't really care how it does that, but adding checks before every dereference is the obvious solution.Indeed. Although specifications sometimes add implementation notes to clarify how things are supposed to work (so that an embedded compiler doesn't ignore runtime checks altogether). In the case of D, it would be interesting and useful to have implementation notes referring to what the different D compilers do.
Nov 23 2020
On Sunday, 22 November 2020 at 23:28:26 UTC, Paul Backus wrote:Then that's a bug in the compiler. A safe D program is allowed to dereference null, so a spec-conformant D compiler *must* ensure that dereferencing null has defined behavior.what spec? :)
Nov 22 2020
On Sunday, 22 November 2020 at 23:00:25 UTC, Ola Fosheim Grostad wrote:On Sunday, 22 November 2020 at 22:36:40 UTC, Paul Backus wrote:I'll reiterate what I've been saying many times already: in LDC, null dereference in Undefined Behavior. What follows is that code should _actively_ check for null to be safe. Checking for null is not included by the compiler in safe code. - Note that accessing memory location 0x0 will probably crash your program on most systems, but definitely not all. For example with WebAssembly, 0 is a validly accessibly memory location. - "Dereferencing a null pointer" in D language context does _not_ mean accessing memory address 0 on system level. -- Calling a class method a.foo() when a==null is technically dereferencing `a`, even if the `foo` call is devirtualized, does not access any member variables, etc. -- Accessing struct member that is not at offset 0 will also lead to accesses to other locations than 0. -JohanMemory safety is concerned specifically with avoiding undefined behavior. Crashing the program isn't undefined behavior, so it's allowed in safe code.I understand what you mean, but at high optimization levels dereferencing a null pointer can trigger undefined behaviour.
Nov 23 2020
On Monday, 23 November 2020 at 12:01:08 UTC, Johan Engelen wrote:On Sunday, 22 November 2020 at 23:00:25 UTC, Ola Fosheim Grostad wrote:Then LDC allows memory corruption in safe code, which is a bug.On Sunday, 22 November 2020 at 22:36:40 UTC, Paul Backus wrote:I'll reiterate what I've been saying many times already: in LDC, null dereference in Undefined Behavior. What follows is that code should _actively_ check for null to be safe. Checking for null is not included by the compiler in safe code.Memory safety is concerned specifically with avoiding undefined behavior. Crashing the program isn't undefined behavior, so it's allowed in safe code.I understand what you mean, but at high optimization levels dereferencing a null pointer can trigger undefined behaviour.
Nov 23 2020
On Monday, 23 November 2020 at 12:03:49 UTC, Paul Backus wrote:On Monday, 23 November 2020 at 12:01:08 UTC, Johan Engelen wrote:Correct. And so do all other D compilers. Completely independent of optimization level.I'll reiterate what I've been saying many times already: in LDC, null dereference in Undefined Behavior. What follows is that code should _actively_ check for null to be safe. Checking for null is not included by the compiler in safe code.Then LDC allows memory corruption in safe code,which is a bug.Without explicit null pointer checking, this is effectively a "won't fix". -Johan
Nov 23 2020
On Monday, 23 November 2020 at 16:50:44 UTC, Johan Engelen wrote:On Monday, 23 November 2020 at 12:03:49 UTC, Paul Backus wrote:Maybe it is for LDC. I suspect Walter puts a high enough priority on memory-safety that he would accept a fix for this issue into DMD.Then LDC allows memory corruption in safe code,Correct. And so do all other D compilers. Completely independent of optimization level.which is a bug.Without explicit null pointer checking, this is effectively a "won't fix".
Nov 23 2020
On Monday, 23 November 2020 at 17:17:26 UTC, Paul Backus wrote:On Monday, 23 November 2020 at 16:50:44 UTC, Johan Engelen wrote:Hi, I think it is not fixable without introducing severe penalty in performance I suspect. Some languages are adding features to help the compiler / user specicify where nulls can be expected. Maybe D needs this too. My original issue was that it failed to check an obvious case. It seems that DMD does detect that case when -O is used. But that is perhaps not great. Other languages - even C or C+= these days, will immediately warn you about possible NULL de-reference when it is very obvious.On Monday, 23 November 2020 at 12:03:49 UTC, Paul Backus wrote:Maybe it is for LDC. I suspect Walter puts a high enough priority on memory-safety that he would accept a fix for this issue into DMD.Then LDC allows memory corruption in safe code,Correct. And so do all other D compilers. Completely independent of optimization level.which is a bug.Without explicit null pointer checking, this is effectively a "won't fix".
Nov 23 2020
On Sunday, 22 November 2020 at 11:52:13 UTC, Dibyendu Majumdar wrote:import core.stdc.stdio : printf; extern (C++) abstract class A { void sayHello(); } extern (C++) class B : A { override void sayHello() { printf("hello\n"); } } extern (C) void main() { //scope b = new B; B b; assert(b); b.sayHello(); } Above fails because b is null. But why doesn't the compiler say so? It seems like a very basic safety check.Keep in mind that to find a null pointer, you must first invent the universe. This isn't a point about the halting problem, but rather than doing static analysis properly is complicated and dmd is already not particularly well structured. You can use constant folding to find simple bugs like this, however, to do it in a clean manner requires a fair amount of thought to get right. Ideally you'd want to use some kind of complete design like abstract interpretation, but in reality you'll end up with safe (minus the ownership aspects) where certain special cases are allowed.
Nov 22 2020
On Sunday, 22 November 2020 at 11:52:13 UTC, Dibyendu Majumdar wrote:Above fails because b is null. But why doesn't the compiler say so? It seems like a very basic safety check.Try this just for laughs: remove the assert then add the -O switch. $ dmd -betterC lole -O lole.d(16): Error: null dereference in function main (the assert actually disables this because the optimizer sees that and then figures the function must not be null.) It just amuses me that dmd's *optimizer* actually catches this, but the debug build doesn't. Walter explained it is because the optimizer is analyzing the data flow anyway so it was a free check at that point, whereas on a normal or debug build it is a bunch of extra work for the implementation. Or something like that, don't trust my memory completely. But yeah it makes me lol.
Nov 22 2020