Re: Should an 'extern(C++, "ns"):' override previous ones in the same scope?
On Saturday, 7 September 2019 at 22:19:48 UTC, Jonathan M Davis wrote: On Saturday, September 7, 2019 3:40:58 PM MDT Exil via Digitalmars-d-learn wrote: On Saturday, 7 September 2019 at 17:22:07 UTC, Jonathan M Davis wrote: > @safe: > @system: > > then @system overrides @safe. Just to add onto this, you can't do: @safe @system void foo(); // error but you can do: extern(C++, ns1) extern(C++, ns2) void foo(); // ok It makes no sense to apply multiple namespaces to the same symbol. I expect that this behavior is due to a lack of testing (the same with the out of order weirdness in the other post). It's the sort of thing that you test when you're trying to make sure that the feature does the right thing when people use it incorrectly, not the sort of thing when you're trying to make sure that the feature works as intended, so it's easy to forget. My guess is that this behavior leaked its way in due to the fact that you need to be able to put multiple extern(C++) declarations on a symbol when you use extern(C++, struct) or extern(C++, class) in addition to the extern(C++) for the namespace. - Jonathan M Davis You don't need to make guesses or assumptions. It most definitely was intentional. https://github.com/dlang/dmd/commit/4b2578e208f2af9a02159fc2d8d87fb17b09005e#diff-62dcb5f0ffc3089b7565897d8beb3322R617 By the looks of it, this feature was also implemented before extern(C++, struct/class).
Re: Should an 'extern(C++, "ns"):' override previous ones in the same scope?
On Saturday, 7 September 2019 at 17:22:07 UTC, Jonathan M Davis wrote: @safe: @system: then @system overrides @safe. Just to add onto this, you can't do: @safe @system void foo(); // error but you can do: extern(C++, ns1) extern(C++, ns2) void foo(); // ok
Re: Should an 'extern(C++, "ns"):' override previous ones in the same scope?
On Saturday, 7 September 2019 at 17:22:07 UTC, Jonathan M Davis wrote: makes no sense whatsoever IMHO. IIRC, this version of extern(C++) didn't go through the DIP process and was simply added via a PR. The original extern(C++) worked the same way. Since it was implemented in v2.066.0 by the looks of it. IIRC the only thing the PR did was basically remove the code that added new objects. So it's to be expected they behave the same way. https://run.dlang.io/is/v1vFeZ extern(C++, ns1): extern(C++, ns2): void foo(); pragma(msg, foo.mangleof); void main() { } Since 2.066.0: Success with output: _ZN3ns13ns23fooEv
Re: segfault in ldc release only - looks like some kind of optimization bug?
On Tuesday, 23 July 2019 at 00:54:08 UTC, aliak wrote: On Tuesday, 23 July 2019 at 00:36:49 UTC, Exil wrote: auto ref get(T)(W!T value) { return value.front; } You're returning a reference to a temporary that gets deleted at the end of the function's scope. The "auto ref" here will be a "ref". . oh ... shit you're right. Ok so this was minimized from this: const config = Config.ghApp(ghDomain) .orElseThrow!(() => new Exception( "could not find config for domain '%s'".format(ghDomain) )); Where Config.ghApp return an Optional!GhApp, and orElseThrow checks if a range has is not empty and returns front. The front in Optional is defined as the front above... So is that an incorrect idiom to use when writing a library then? I pretty sure I've seen it in phobos too. Slapping return on the function also fixes it. Is that the correct way to write a .front? Thanks! Yes you can use "return". It basically tells the compiler that the function or method returns something that is referenced by a passed in parameter so to keep it alive. https://dlang.org/spec/function.html#return-ref-parameters Your orElseThrow() probably shouldn't be taking in a copy though. That's the catch, then you can't use it in a UFCS chain like you are using now. Using "return" is not an ideal fix, as it is still going to be calling the destructor on the object. So you might run into an issue somewhere. It just so happens to generate assembly that works though I guess when there is no destructor.
Re: segfault in ldc release only - looks like some kind of optimization bug?
auto ref get(T)(W!T value) { return value.front; } You're returning a reference to a temporary that gets deleted at the end of the function's scope. The "auto ref" here will be a "ref".
Re: Why does a switch break cause a segmentation fault
On Monday, 22 July 2019 at 22:05:17 UTC, adamgoldberg wrote: Hey, I just happened to be writing a program in D an stumbled upon a bug, that causes it to terminate after receiving a SEGV signal, nothing wierd so far but it looks everything I tried shows it is the break statement inside of a switch. It seems to have a relatively random chance of occuring, and also somewhat dependant on the compiler, and build mode used. I'm short on time so instead of rewriting my SO post I will just link it. Here! https://stackoverflow.com/questions/57153617/random-segmentation-fault-in-d-lang-on-switch-break Hope someone can help! Could be the statement in the actual switch(), which is accessing a pointer "codecpar". switch (stream.codecpar.codec_type) ^ This could be null and you aren't checking for it. I find that D sometimes doesn't have the correct line numbers for debug info, even when not doing an optimized build. So it could really be anything in that function. The root cause could be a lot of things though, some bad codegen or otherwise. Could add a check to make sure though.
Re: Why does `static foreach` lead to something calling `~=` internally?
On Sunday, 7 July 2019 at 18:45:14 UTC, 0xEAB wrote: On Sunday, 7 July 2019 at 16:51:57 UTC, 0xEAB wrote: Why does this `static foreach` lead to hidden usage of operator Further notes by Dan (aka "Wild"): I added some small printfs to the compiler, http://ix.io/1NWM It seems like it lowers it into something weird Static foreach needs a tuple. When you have a range like "0 .. 10" it has to convert that to a tuple. It does this by generating some code and running it at CTFE. Guess this was done as it was a lot simpler to do, you don't have to worry about recreating ranges as that's already done by using CTFE. What it ends up lowering to: https://github.com/dlang/dmd/blob/v2.087.0/src/dmd/cond.d#L274 * static foreach (x; { * typeof({ * foreach (x; range) return x; * }())[] __res; * foreach (x; range) __res ~= x; * return __res; * }()) { ... }
Re: Inconsistent behavior of __FILE__ within mixin template
On Wednesday, 29 May 2019 at 08:45:45 UTC, Andre Pany wrote: Hi, I have a module a.d --- struct TestClass { string name; string fileName; } TestClass[] testClasses; mixin template UnitTest() { private static string getFileName(string fileName = __FILE__) { return fileName; } private static this() { testClasses ~= TestClass(this.classinfo.name, getFileName()); } } and a module b.d --- import std.stdio; import a; class MyTest { mixin UnitTest; this() { writeln(getFileName()); } } void main() { new MyTest(); writeln(testClasses); } What I want is to have in the struct array testClasses the file name of module b to generate an xml report. But the output of this application is b.d [TestClass("b.MyTest", "a.d")] I would have thought __FILE evaluates in both cases to "b.d" as the code is mixed into module b. Is this the intended behavior? Kind regards André I imagine __FILE__ is used where the code is defined, since it is defined in "a.d" that is what is used. If you want to know the file name of where it is used then you can add it as part of the template. mixin template UnitTest(string filename = __FILE__) { private static this() { testClasses ~= TestClass(this.classinfo.name, filename ); } }