www.digitalmars.com         C & C++   DMDScript  

digitalmars.D - [Joke] C++ and D namings

reply Q. Schroll <qs.il.paperinik gmail.com> writes:
In C++, the noexcept specifier means you cannot throw anything.
In D,   the nothrow  specifier means you cannot throw Exceptions, 
but anything else.
Jan 19
parent reply Andrei Alexandrescu <SeeWebsiteForEmail erdani.org> writes:
On 1/19/21 4:50 PM, Q. Schroll wrote:
 In C++, the noexcept specifier means you cannot throw anything.
 In D,   the nothrow  specifier means you cannot throw Exceptions, but 
 anything else.
Except that in C++, noexcept really means you can throw anything but you're not supposed to. Important distinction...
Jan 19
next sibling parent reply Meta <jared771 gmail.com> writes:
On Wednesday, 20 January 2021 at 01:04:07 UTC, Andrei 
Alexandrescu wrote:
 On 1/19/21 4:50 PM, Q. Schroll wrote:
 In C++, the noexcept specifier means you cannot throw anything.
 In D,   the nothrow  specifier means you cannot throw 
 Exceptions, but anything else.
Except that in C++, noexcept really means you can throw anything but you're not supposed to. Important distinction...
I've never understood why that is. Do you have any insight into why noexcept is so useless? Why was it designed that way?
Jan 19
next sibling parent reply "H. S. Teoh" <hsteoh quickfur.ath.cx> writes:
On Wed, Jan 20, 2021 at 01:17:36AM +0000, Meta via Digitalmars-d wrote:
 On Wednesday, 20 January 2021 at 01:04:07 UTC, Andrei Alexandrescu wrote:
 On 1/19/21 4:50 PM, Q. Schroll wrote:
 In C++, the noexcept specifier means you cannot throw anything.
 In D, the nothrow specifier means you cannot throw Exceptions,
 but anything else.
Except that in C++, noexcept really means you can throw anything but you're not supposed to. Important distinction...
:-D
 I've never understood why that is. Do you have any insight into why
 noexcept is so useless? Why was it designed that way?
I'm not the least surprised. After all, this is C++, the same language that lets you write 'const' on something, and then in the same breath write 'const_cast<...>' to pretend that you never wrote it, all the while your caller still believes that you're honoring your word on the 'const'. Nothing new under the sun. ;-) T -- The most powerful one-line C program: #include "/dev/tty" -- IOCCC
Jan 19
parent reply Ola Fosheim Grostad <ola.fosheim.grostad gmail.com> writes:
On Wednesday, 20 January 2021 at 01:30:15 UTC, H. S. Teoh wrote:
 I'm not the least surprised.  After all, this is C++, the same 
 language that lets you write 'const' on something, and then in 
 the same breath write 'const_cast<...>' to pretend that you 
 never wrote it, all the while your caller still believes that 
 you're honoring your word on the 'const'.

 Nothing new under the sun. ;-)
Modifying it after const cast is undefined behaviour according to cppreference. How would you prevent it? You can do the same in D. Noexcept in c++ makes perfect sense: noexcept(runtimewithoutexceptions)
Jan 19
parent reply Steven Schveighoffer <schveiguy gmail.com> writes:
On 1/19/21 10:59 PM, Ola Fosheim Grostad wrote:
 On Wednesday, 20 January 2021 at 01:30:15 UTC, H. S. Teoh wrote:
 I'm not the least surprised.  After all, this is C++, the same 
 language that lets you write 'const' on something, and then in the 
 same breath write 'const_cast<...>' to pretend that you never wrote 
 it, all the while your caller still believes that you're honoring your 
 word on the 'const'.

 Nothing new under the sun. ;-)
Modifying it after const cast is undefined behaviour according to cppreference. How would you prevent it? You can do the same in D.
Only if the real item is actually const. This is literally the first example on cppreference: int i = 3; // i is not declared const const int& rci = i; const_cast<int&>(rci) = 4; // OK: modifies i -Steve
Jan 19
parent reply Ola Fosheim Grostad <ola.fosheim.grostad gmail.com> writes:
On Wednesday, 20 January 2021 at 04:15:24 UTC, Steven 
Schveighoffer wrote:
 Only if the real item is actually const. This is literally the 
 first example on cppreference:

     int i = 3;                 // i is not declared const
     const int& rci = i;
     const_cast<int&>(rci) = 4; // OK: modifies i
How is this different from D? How does this lead to different code gen?
Jan 19
next sibling parent reply Steven Schveighoffer <schveiguy gmail.com> writes:
On 1/19/21 11:21 PM, Ola Fosheim Grostad wrote:
 On Wednesday, 20 January 2021 at 04:15:24 UTC, Steven Schveighoffer wrote:
 Only if the real item is actually const. This is literally the first 
 example on cppreference:

     int i = 3;                 // i is not declared const
     const int& rci = i;
     const_cast<int&>(rci) = 4; // OK: modifies i
How is this different from D? How does this lead to different code gen?
This is undefined behavior in D. How does it lead to different code Gen? This code could pass in D, but the equivalent C++ would have to fail since it's not UB: int i = 3; const int *j = &i; *(cast(int *)j) = 4; assert(i == 3); -Steve
Jan 19
parent reply Ola Fosheim Grostad <ola.fosheim.grostad gmail.com> writes:
On Wednesday, 20 January 2021 at 05:04:44 UTC, Steven 
Schveighoffer wrote:
 On 1/19/21 11:21 PM, Ola Fosheim Grostad wrote:
 This is undefined behavior in D. How does it lead to different 
 code Gen? This code could pass in D, but the equivalent C++ 
 would have to fail since it's not UB:

 int i = 3;
 const int *j = &i;
 *(cast(int *)j) = 4;
 assert(i == 3);
Wasnt D supposed to eliminate UB? How about this? union t {int x; const int y;};
Jan 19
next sibling parent reply Ola Fosheim Grostad <ola.fosheim.grostad gmail.com> writes:
On Wednesday, 20 January 2021 at 05:12:15 UTC, Ola Fosheim 
Grostad wrote:
 Wasnt D supposed to eliminate UB?

 How about this?

 union t {int x; const int y;};
Or worse: import std.stdio; union t {int x; immutable int y;}; void main() { t a; a.x=3; writeln(a.y); a.x=4; writeln(a.y); }
Jan 19
parent reply Paul Backus <snarwin gmail.com> writes:
On Wednesday, 20 January 2021 at 05:48:28 UTC, Ola Fosheim 
Grostad wrote:
 Or worse:
 import std.stdio;
 union t {int x; immutable int y;};
 void main()
 {

     t a;
     a.x=3;
     writeln(a.y);
     a.x=4;
     writeln(a.y);
 }
This seems like a bug to me. Especially since the compiler even allows this: t b = { y: 4 }; a = b; Changing "union" to "struct" produces the expected error message: Error: cannot modify struct instance `a` of type `t` because it contains `const` or `immutable` members
Jan 20
parent Ola Fosheim Grostad <ola.fosheim.grostad gmail.com> writes:
On Wednesday, 20 January 2021 at 12:37:41 UTC, Paul Backus wrote:
 This seems like a bug to me. Especially since the compiler even
Using a pointer to the immutable would indeed be unsound... Best fix is tagged union.
Jan 20
prev sibling parent reply Steven Schveighoffer <schveiguy gmail.com> writes:
On 1/20/21 12:12 AM, Ola Fosheim Grostad wrote:
 On Wednesday, 20 January 2021 at 05:04:44 UTC, Steven Schveighoffer wrote:
 On 1/19/21 11:21 PM, Ola Fosheim Grostad wrote:
 This is undefined behavior in D. How does it lead to different code 
 Gen? This code could pass in D, but the equivalent C++ would have to 
 fail since it's not UB:

 int i = 3;
 const int *j = &i;
 *(cast(int *)j) = 4;
 assert(i == 3);
Wasnt D supposed to eliminate UB?
No.
 
 How about this?
 
 union t {int x; const int y;};
 
 
What's wrong with that? const is allowed to refer to mutable data. But it's not usable in safe code (which IS supposed to eliminate UB). But technically, you can set one union member and as long as you don't use the other, it's never UB. In this case, however, it would seem fine. Your immutable case would ALWAYS be UB, but only if you accessed the member you didn't set. And again, disallowed in safe code. -Steve
Jan 20
next sibling parent reply Ola Fosheim Grostad <ola.fosheim.grostad gmail.com> writes:
On Wednesday, 20 January 2021 at 14:33:11 UTC, Steven 
Schveighoffer wrote:
 But technically, you can set one union member and as long as 
 you don't use the other, it's never UB. In this case, however, 
 it would seem fine.

 Your immutable case would ALWAYS be UB, but only if you 
 accessed the member you didn't set.
Where does the spec say that unions cannot be used for type punning?
Jan 20
parent reply Steven Schveighoffer <schveiguy gmail.com> writes:
On 1/20/21 9:48 AM, Ola Fosheim Grostad wrote:
 On Wednesday, 20 January 2021 at 14:33:11 UTC, Steven Schveighoffer wrote:
 But technically, you can set one union member and as long as you don't 
 use the other, it's never UB. In this case, however, it would seem fine.

 Your immutable case would ALWAYS be UB, but only if you accessed the 
 member you didn't set.
Where does the spec say that unions cannot be used for type punning?
I should say, it's undefined behavior if you ever use the immutable value and then mutate the value (just like if you cast it). -Steve
Jan 20
parent Ola Fosheim =?UTF-8?B?R3LDuHN0YWQ=?= <ola.fosheim.grostad gmail.com> writes:
On Wednesday, 20 January 2021 at 15:10:09 UTC, Steven 
Schveighoffer wrote:
 I should say, it's undefined behavior if you ever use the 
 immutable value and then mutate the value (just like if you 
 cast it).
It would be worth mentioning these issues on the page that describes union. I am hoping for an overhaul of union. I specifically don't want to see traced pointers in a union unless it is type-info compatible. This is currently blocking precise collection and destruction...
Jan 21
prev sibling parent reply Paul Backus <snarwin gmail.com> writes:
On Wednesday, 20 January 2021 at 14:33:11 UTC, Steven 
Schveighoffer wrote:
 Your immutable case would ALWAYS be UB, but only if you 
 accessed the member you didn't set.

 And again, disallowed in  safe code.
This version compiles even with safe: import std.stdio; union t {int x; immutable int y;}; void main() safe { t a = { x: 0 }; writeln(a.y); t b = { y: 4 }; a = b; // oops writeln(a.y); }
Jan 20
parent reply Steven Schveighoffer <schveiguy gmail.com> writes:
On 1/20/21 10:13 AM, Paul Backus wrote:
 On Wednesday, 20 January 2021 at 14:33:11 UTC, Steven Schveighoffer wrote:
 Your immutable case would ALWAYS be UB, but only if you accessed the 
 member you didn't set.

 And again, disallowed in  safe code.
This version compiles even with safe: import std.stdio; union t {int x; immutable int y;}; void main() safe {     t a = { x: 0 };     writeln(a.y);     t b = { y: 4 };     a = b; // oops     writeln(a.y); }
That seems like a bug. Writing the x directly fails in safe code. -Steve
Jan 20
next sibling parent reply Paul Backus <snarwin gmail.com> writes:
On Wednesday, 20 January 2021 at 15:17:09 UTC, Steven 
Schveighoffer wrote:
 On 1/20/21 10:13 AM, Paul Backus wrote:
 
 This version compiles even with  safe:
 
 import std.stdio;
 union t {int x; immutable int y;};
 void main()  safe
 {
 
      t a = { x: 0 };
      writeln(a.y);
      t b = { y: 4 };
      a = b; // oops
      writeln(a.y);
 }
That seems like a bug. Writing the x directly fails in safe code. -Steve
I agree. Though now that I take a look at the spec, it seems like the bug may actually be in the line writeln(a.y); ...since accessing immutable data that's overlapped with mutable data breaks safe aliasing [1]. [1] https://dlang.org/spec/function.html#safe-aliasing
Jan 20
next sibling parent reply Steven Schveighoffer <schveiguy gmail.com> writes:
On 1/20/21 10:31 AM, Paul Backus wrote:
 On Wednesday, 20 January 2021 at 15:17:09 UTC, Steven Schveighoffer wrote:
 On 1/20/21 10:13 AM, Paul Backus wrote:
 This version compiles even with  safe:

 import std.stdio;
 union t {int x; immutable int y;};
 void main()  safe
 {

      t a = { x: 0 };
      writeln(a.y);
      t b = { y: 4 };
      a = b; // oops
      writeln(a.y);
 }
That seems like a bug. Writing the x directly fails in safe code.
I agree. Though now that I take a look at the spec, it seems like the bug may actually be in the line     writeln(a.y); ...since accessing immutable data that's overlapped with mutable data breaks safe aliasing [1].
Thanks for that link, I wasn't aware of that list. In my Dconf online presentation, I found numerous bugs surrounding unions and safe code. For instance, a union between a pointer and a scalar is considered "safe" to access the scalar (even writing it!) -Steve
Jan 20
parent reply Imperatorn <johan_forsberg_86 hotmail.com> writes:
On Wednesday, 20 January 2021 at 16:07:26 UTC, Steven 
Schveighoffer wrote:
 On 1/20/21 10:31 AM, Paul Backus wrote:
 On Wednesday, 20 January 2021 at 15:17:09 UTC, Steven 
 Schveighoffer wrote:
 On 1/20/21 10:13 AM, Paul Backus wrote:
 [...]
That seems like a bug. Writing the x directly fails in safe code.
I agree. Though now that I take a look at the spec, it seems like the bug may actually be in the line     writeln(a.y); ...since accessing immutable data that's overlapped with mutable data breaks safe aliasing [1].
Thanks for that link, I wasn't aware of that list. In my Dconf online presentation, I found numerous bugs surrounding unions and safe code. For instance, a union between a pointer and a scalar is considered "safe" to access the scalar (even writing it!) -Steve
Are those bugs reported?
Jan 20
parent reply Steven Schveighoffer <schveiguy gmail.com> writes:
On 1/20/21 12:08 PM, Imperatorn wrote:
 On Wednesday, 20 January 2021 at 16:07:26 UTC, Steven Schveighoffer wrote:
 On 1/20/21 10:31 AM, Paul Backus wrote:
 On Wednesday, 20 January 2021 at 15:17:09 UTC, Steven Schveighoffer 
 wrote:
 On 1/20/21 10:13 AM, Paul Backus wrote:
 [...]
That seems like a bug. Writing the x directly fails in safe code.
I agree. Though now that I take a look at the spec, it seems like the bug may actually be in the line      writeln(a.y); ...since accessing immutable data that's overlapped with mutable data breaks safe aliasing [1].
Thanks for that link, I wasn't aware of that list. In my Dconf online presentation, I found numerous bugs surrounding unions and safe code. For instance, a union between a pointer and a scalar is considered "safe" to access the scalar (even writing it!)
Are those bugs reported?
I don't know if I reported mine. I assumed at the time that it was just the expected behavior, but the spec seems to suggest otherwise. I'll report it. Looks like Paul did his. -Steve
Jan 20
parent Steven Schveighoffer <schveiguy gmail.com> writes:
On 1/20/21 2:20 PM, Steven Schveighoffer wrote:
 I'll report it.
https://issues.dlang.org/show_bug.cgi?id=21565 -Steve
Jan 20
prev sibling parent Paul Backus <snarwin gmail.com> writes:
On Wednesday, 20 January 2021 at 15:31:30 UTC, Paul Backus wrote:
 I agree. Though now that I take a look at the spec, it seems 
 like the bug may actually be in the line

     writeln(a.y);

 ...since accessing immutable data that's overlapped with 
 mutable data breaks safe aliasing [1].

 [1] https://dlang.org/spec/function.html#safe-aliasing
https://issues.dlang.org/show_bug.cgi?id=21561
Jan 20
prev sibling parent Walter Bright <newshound2 digitalmars.com> writes:
On 1/20/2021 7:17 AM, Steven Schveighoffer wrote:
 That seems like a bug. Writing the x directly fails in  safe code.
It's a bug. Please file a bug report.
Jan 21
prev sibling parent reply Dukc <ajieskola gmail.com> writes:
 How is this different from D? How does this lead to different 
 code gen?
Consider a function with a `const int[]` argument. In D, when generating code for the caller, it is allowed to assume that the callee won't change the contents of the array, unless it is in global space or passed via another argument. The difference to C++ is that the above applies even if the array contains mutable values from the caller perspective: ``` long sum (const int[] arg); void foo { auto arr = [1,2,3]; auto sum = arr.sum; //codegen can assume that `arr` won't change } ```
Jan 20
parent reply Ola Fosheim Grostad <ola.fosheim.grostad gmail.com> writes:
On Wednesday, 20 January 2021 at 09:25:51 UTC, Dukc wrote:
 long sum (const int[] arg);
 void foo
 {  auto arr = [1,2,3];
    auto sum = arr.sum; //codegen can assume that `arr` won't 
 change
 }
The called function has to be pure, as the slice could reference a global...
Jan 20
parent reply Dukc <ajieskola gmail.com> writes:
On Wednesday, 20 January 2021 at 09:53:34 UTC, Ola Fosheim 
Grostad wrote:
 On Wednesday, 20 January 2021 at 09:25:51 UTC, Dukc wrote:
 long sum (const int[] arg);
 void foo
 {  auto arr = [1,2,3];
    auto sum = arr.sum; //codegen can assume that `arr` won't 
 change
 }
The called function has to be pure, as the slice could reference a global...
Not in this case, as the caller knows `arr` is a only referenced locally. Had `foo` received `arr` as argument, then `sum` would have to be `pure` for the optimization.
Jan 20
parent Ola Fosheim Grostad <ola.fosheim.grostad gmail.com> writes:
On Wednesday, 20 January 2021 at 10:00:01 UTC, Dukc wrote:
 On Wednesday, 20 January 2021 at 09:53:34 UTC, Ola Fosheim 
 Grostad wrote:
 Not in this case, as the caller knows `arr` is a only 
 referenced locally. Had `foo` received `arr` as argument, then 
 `sum` would have to be `pure` for the optimization.
Yes, sure. I was thinking in terms of optimizing utility functions. You still also have to deal with aliasing when you have multiple in params.
Jan 20
prev sibling parent reply Ola Fosheim Grostad <ola.fosheim.grostad gmail.com> writes:
On Wednesday, 20 January 2021 at 01:17:36 UTC, Meta wrote:
 On Wednesday, 20 January 2021 at 01:04:07 UTC, Andrei 
 Alexandrescu wrote:
 On 1/19/21 4:50 PM, Q. Schroll wrote:
 In C++, the noexcept specifier means you cannot throw 
 anything.
 In D,   the nothrow  specifier means you cannot throw 
 Exceptions, but anything else.
Except that in C++, noexcept really means you can throw anything but you're not supposed to. Important distinction...
I've never understood why that is. Do you have any insight into why noexcept is so useless? Why was it designed that way?
Why do you think a call to terminate() is useless?
Jan 19
parent reply Meta <jared771 gmail.com> writes:
On Wednesday, 20 January 2021 at 03:26:42 UTC, Ola Fosheim 
Grostad wrote:
 On Wednesday, 20 January 2021 at 01:17:36 UTC, Meta wrote:
 On Wednesday, 20 January 2021 at 01:04:07 UTC, Andrei 
 Alexandrescu wrote:
 On 1/19/21 4:50 PM, Q. Schroll wrote:
 In C++, the noexcept specifier means you cannot throw 
 anything.
 In D,   the nothrow  specifier means you cannot throw 
 Exceptions, but anything else.
Except that in C++, noexcept really means you can throw anything but you're not supposed to. Important distinction...
I've never understood why that is. Do you have any insight into why noexcept is so useless? Why was it designed that way?
Why do you think a call to terminate() is useless?
Okay, useless in terms of static guarantees, and definitely compared to nothrow (or even Java's exception specifications IMO). It's not *completely* useless, just mostly useless.
Jan 19
parent Ola Fosheim Grostad <ola.fosheim.grostad gmail.com> writes:
On Wednesday, 20 January 2021 at 03:56:24 UTC, Meta wrote:
 Okay, useless in terms of static guarantees, and definitely 
 compared to nothrow (or even Java's exception specifications 
 IMO). It's not *completely* useless, just mostly useless.
In c++ most things are related to performance, and then you leave expensive static analysis to optional external tools. Noexecpt tells the codegen to emit more efficient code.
Jan 19
prev sibling next sibling parent reply claptrap <clap trap.com> writes:
On Wednesday, 20 January 2021 at 01:04:07 UTC, Andrei 
Alexandrescu wrote:
 On 1/19/21 4:50 PM, Q. Schroll wrote:
 In C++, the noexcept specifier means you cannot throw anything.
 In D,   the nothrow  specifier means you cannot throw 
 Exceptions, but anything else.
Except that in C++, noexcept really means you can throw anything but you're not supposed to. Important distinction...
nothrow is still a terrible name for something that can still throw.
Jan 20
parent reply Walter Bright <newshound2 digitalmars.com> writes:
On 1/20/2021 2:51 AM, claptrap wrote:
 nothrow is still a terrible name for something that can still throw.
I tend to agree. My thinking has evolved over the years, and I now think that Error should never be thrown, ever. If you have a non-recoverable error, you should just exit or call a user specified function. Not attempt to unwind the stack. If someone wants to put a DIP out for that, I'd be favorably inclined.
Jan 21
parent reply John Colvin <john.loughran.colvin gmail.com> writes:
On Thursday, 21 January 2021 at 09:49:40 UTC, Walter Bright wrote:
 On 1/20/2021 2:51 AM, claptrap wrote:
 nothrow is still a terrible name for something that can still 
 throw.
I tend to agree. My thinking has evolved over the years, and I now think that Error should never be thrown, ever. If you have a non-recoverable error, you should just exit or call a user specified function. Not attempt to unwind the stack. If someone wants to put a DIP out for that, I'd be favorably inclined.
We already have a compiler switch that is almost that. -checkaction=[D|C|halt|context] behavior on assert/boundscheck/finalswitch failure now if we had a version of that switch that could apply to all `throw x` where `is(typeof(x) : Error)) then that'd be great. It's worth saying that we do depend on being able to catch Errors at Symmetry*, our situation is a little unusual though. * "we are happy when a thrown Error is caught in some limited circumstances" not "our program is incorrect if any particular thrown Error is not caught"
Jan 21
parent reply Walter Bright <newshound2 digitalmars.com> writes:
On 1/21/2021 3:12 AM, John Colvin wrote:
 It's worth saying that we do depend on being able to catch Errors at
Symmetry*, 
 our situation is a little unusual though.
 
 * "we are happy when a thrown Error is caught in some limited circumstances"
not 
 "our program is incorrect if any particular thrown Error is not caught"
I recommend considering replacing it with Exception.
Jan 22
parent reply John Colvin <john.loughran.colvin gmail.com> writes:
On Friday, 22 January 2021 at 09:28:47 UTC, Walter Bright wrote:
 On 1/21/2021 3:12 AM, John Colvin wrote:
 It's worth saying that we do depend on being able to catch 
 Errors at Symmetry*, our situation is a little unusual though.
 
 * "we are happy when a thrown Error is caught in some limited 
 circumstances" not "our program is incorrect if any particular 
 thrown Error is not caught"
I recommend considering replacing it with Exception.
The purpose is to catch unexpected Errors from any source, including accidental bounds violations, code deep in 3rd party dependencies etc. It doesn't matter if we miss some, but it's nice to catch them when we can.
Jan 22
parent reply Walter Bright <newshound2 digitalmars.com> writes:
On 1/22/2021 7:08 AM, John Colvin wrote:
 On Friday, 22 January 2021 at 09:28:47 UTC, Walter Bright wrote:
 On 1/21/2021 3:12 AM, John Colvin wrote:
 It's worth saying that we do depend on being able to catch Errors at 
 Symmetry*, our situation is a little unusual though.

 * "we are happy when a thrown Error is caught in some limited circumstances" 
 not "our program is incorrect if any particular thrown Error is not caught"
I recommend considering replacing it with Exception.
The purpose is to catch unexpected Errors from any source, including accidental bounds violations, code deep in 3rd party dependencies etc. It doesn't matter if we miss some, but it's nice to catch them when we can.
You should be able to register your own handler to intercept those before an Error gets thrown.
Jan 22
next sibling parent deadalnix <deadalnix gmail.com> writes:
On Saturday, 23 January 2021 at 05:45:13 UTC, Walter Bright wrote:
 You should be able to register your own handler to intercept 
 those before an Error gets thrown.
True, but there are no more guarantee that things are in order at this point in time than there are when catching the error down the road. I don't have a solution.
Jan 23
prev sibling parent reply John Colvin <john.loughran.colvin gmail.com> writes:
On Saturday, 23 January 2021 at 05:45:13 UTC, Walter Bright wrote:
 On 1/22/2021 7:08 AM, John Colvin wrote:
 On Friday, 22 January 2021 at 09:28:47 UTC, Walter Bright 
 wrote:
 On 1/21/2021 3:12 AM, John Colvin wrote:
 [...]
I recommend considering replacing it with Exception.
The purpose is to catch unexpected Errors from any source, including accidental bounds violations, code deep in 3rd party dependencies etc. It doesn't matter if we miss some, but it's nice to catch them when we can.
You should be able to register your own handler to intercept those before an Error gets thrown.
For a bunch of cases, yes. For actual "throw new Error" there aren't many options.
Jan 26
parent Ola Fosheim =?UTF-8?B?R3LDuHN0YWQ=?= <ola.fosheim.grostad gmail.com> writes:
On Tuesday, 26 January 2021 at 09:49:01 UTC, John Colvin wrote:
 For a bunch of cases, yes. For actual "throw new Error" there 
 aren't many options.
Would a compiler config option be helpful?
Jan 26
prev sibling next sibling parent Walter Bright <newshound2 digitalmars.com> writes:
On 1/19/2021 5:04 PM, Andrei Alexandrescu wrote:
 On 1/19/21 4:50 PM, Q. Schroll wrote:
 In C++, the noexcept specifier means you cannot throw anything.
 In D,   the nothrow  specifier means you cannot throw Exceptions, but
anything 
 else.
Except that in C++, noexcept really means you can throw anything but you're not supposed to. Important distinction...
Time for throwing "soSueMe".
Jan 21
prev sibling parent reply deadalnix <deadalnix gmail.com> writes:
On Wednesday, 20 January 2021 at 01:04:07 UTC, Andrei 
Alexandrescu wrote:
 On 1/19/21 4:50 PM, Q. Schroll wrote:
 In C++, the noexcept specifier means you cannot throw anything.
 In D,   the nothrow  specifier means you cannot throw 
 Exceptions, but anything else.
Except that in C++, noexcept really means you can throw anything but you're not supposed to. Important distinction...
Yup, one things that people miss is that noexcept actually makes things more expensive because the compiler has to add checks that you aren't throwing something. These are runtime checks that happen when unwinding an exception.
Jan 21
parent Ola Fosheim =?UTF-8?B?R3LDuHN0YWQ=?= <ola.fosheim.grostad gmail.com> writes:
On Thursday, 21 January 2021 at 12:14:01 UTC, deadalnix wrote:
 Yup, one things that people miss is that noexcept actually 
 makes things more expensive because the compiler has to add 
 checks that you aren't throwing something. These are runtime 
 checks that happen when unwinding an exception.
I would assume that only applies when calling functions in other compilation units? The throws within the noexcept function should just be replace with a call to std::terminate?
Jan 21