Re: Should an 'extern(C++, "ns"):' override previous ones in the same scope?

2019-09-08 Thread Exil via Digitalmars-d-learn
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?

2019-09-07 Thread Exil via Digitalmars-d-learn
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?

2019-09-07 Thread Exil via Digitalmars-d-learn
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?

2019-07-22 Thread Exil via Digitalmars-d-learn

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?

2019-07-22 Thread Exil via Digitalmars-d-learn

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

2019-07-22 Thread Exil via Digitalmars-d-learn

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?

2019-07-09 Thread Exil via Digitalmars-d-learn

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

2019-05-29 Thread Exil via Digitalmars-d-learn

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 );
}
}