Re: Is there a place I can learn LLD inline assembly with GCC syntax?

2021-12-15 Thread rempas via Digitalmars-d-learn

On Wednesday, 15 December 2021 at 21:57:39 UTC, Johan wrote:


The wiki page you linked to describes LDC's own inline assembly 
syntax, which supports all targets but is no longer recommended.
If you want GCC-style inline assembly, it's probably best to 
have a look at GCC's documentation:

https://gcc.gnu.org/onlinedocs/gcc/Extended-Asm.html
and examples here in LDC source:
https://github.com/ldc-developers/druntime/pull/171/files

cheers,
  Johan


Oh!! We can use pure GCC syntax? That's sweet as there will be a 
lot more sources and people knowing how to use it! I already test 
it and it works!!! Thanks a lot for your help!!!


Re: How to pass a class by (const) reference to C++

2021-12-15 Thread Jan via Digitalmars-d-learn

On Wednesday, 15 December 2021 at 22:50:38 UTC, Tim wrote:

On Wednesday, 15 December 2021 at 22:46:01 UTC, Jan wrote:
Btw. should I report this issue somewhere? Is far as I see 
this isn't logged yet:




Yes, it should be reported.


https://issues.dlang.org/show_bug.cgi?id=22603


Re: How to pass a class by (const) reference to C++

2021-12-15 Thread Tim via Digitalmars-d-learn

On Wednesday, 15 December 2021 at 22:46:01 UTC, Jan wrote:
Btw. should I report this issue somewhere? Is far as I see this 
isn't logged yet:




Yes, it should be reported.


Re: How to pass a class by (const) reference to C++

2021-12-15 Thread Jan via Digitalmars-d-learn

On Wednesday, 15 December 2021 at 22:33:15 UTC, Tim wrote:
I agree that __gshared should imply static. That's probably a 
bug in the compiler.


Using `extern` without `export` would only work with static 
linking (on Windows). `export` without `extern` would be 
exporting the variable for others, like `__declspec(dllexport)` 
in C++. `export` and `extern` combined imports the variable, 
like `__declspec(dllimport)`.


That's all very helpful, thanks for the explanations guys.

Btw. should I report this issue somewhere? Is far as I see this 
isn't logged yet:




Re: How to pass a class by (const) reference to C++

2021-12-15 Thread Tim via Digitalmars-d-learn

On Wednesday, 15 December 2021 at 22:01:19 UTC, Jan wrote:

Ha, it works indeed!

```cpp
extern export __gshared static int var;
```

That's a declaration worthy of C++ ! Fewer keywords would be 
too usable :D


Joking aside, I understood the docs such that `__gshared` 
actually *is* `static` in D, no? Also why the `export` when 
it's an extern variable?


I agree that __gshared should imply static. That's probably a bug 
in the compiler.


Using `extern` without `export` would only work with static 
linking (on Windows). `export` without `extern` would be 
exporting the variable for others, like `__declspec(dllexport)` 
in C++. `export` and `extern` combined imports the variable, like 
`__declspec(dllimport)`.


Re: How to pass a class by (const) reference to C++

2021-12-15 Thread Adam Ruppe via Digitalmars-d-learn

On Wednesday, 15 December 2021 at 22:24:42 UTC, H. S. Teoh wrote:
`__gshared` is needed to coax the compiler into making the 
variable global in the C/C++ sense, i.e., only 1 instance 
across all threads.



it is just normally __gshared implies static automatically. it 
does in like every other context but i guess not in the mangler 
or whatever.


Re: How to pass a class by (const) reference to C++

2021-12-15 Thread H. S. Teoh via Digitalmars-d-learn
On Wed, Dec 15, 2021 at 10:01:19PM +, Jan via Digitalmars-d-learn wrote:
> On Wednesday, 15 December 2021 at 21:30:47 UTC, Tim wrote:
[...]
> ```cpp
> extern export __gshared static int var;
> ```
[...]
> Joking aside, I understood the docs such that `__gshared` actually
> *is* `static` in D, no?

No. `static` in this case means the lifetime is the lifetime of the
module. By default, a static variable would be in TLS and would have the
lifetime of the thread that it was instantiated in (and there would be
one instance per thread).

`__gshared` is needed to coax the compiler into making the variable
global in the C/C++ sense, i.e., only 1 instance across all threads.

tl;dr: C static == D __gshared.


T

-- 
Marketing: the art of convincing people to pay for what they didn't need before 
which you fail to deliver after.


Re: How to pass a class by (const) reference to C++

2021-12-15 Thread Jan via Digitalmars-d-learn

On Wednesday, 15 December 2021 at 21:30:47 UTC, Tim wrote:

It seems to work if var is additionally static:


Ha, it works indeed!

```cpp
extern export __gshared static int var;
```

That's a declaration worthy of C++ ! Fewer keywords would be too 
usable :D


Joking aside, I understood the docs such that `__gshared` 
actually *is* `static` in D, no? Also why the `export` when it's 
an extern variable?





Re: Is there a place I can learn LLD inline assembly with GCC syntax?

2021-12-15 Thread Johan via Digitalmars-d-learn

On Wednesday, 15 December 2021 at 09:26:28 UTC, rempas wrote:
I want to learn how to use inline assembly for LDC with GCC 
syntax specifically so I can support all the targets (as 
[here](https://wiki.dlang.org/Compilers) it is said that DMD 
intel-like syntax only supports the "i386" and "amd64" targets) 
but I cannot find anything other 
[this](https://wiki.dlang.org/LDC_inline_assembly_expressions) 
outdated page where It seems that it doesn't work (at least not 
for the sys_write example). Any ideas?


The wiki page you linked to describes LDC's own inline assembly 
syntax, which supports all targets but is no longer recommended.
If you want GCC-style inline assembly, it's probably best to have 
a look at GCC's documentation:

https://gcc.gnu.org/onlinedocs/gcc/Extended-Asm.html
and examples here in LDC source:
https://github.com/ldc-developers/druntime/pull/171/files

cheers,
  Johan



Re: How to pass a class by (const) reference to C++

2021-12-15 Thread Tim via Digitalmars-d-learn

On Wednesday, 15 December 2021 at 19:28:44 UTC, Jan wrote:

C++
```cpp
class Test
{
public:
  __declspec(dllexport) static int var;
};

int Test::var = 42;
```

D
```cpp
extern(C++, class) struct Test
{
  extern (C++) export extern __gshared int var;
}
```

(also tried without the duplicate extern(C++) and without 
'export')


DLL compiled with Visual Studio 2019. D DLL compiled with a 3 
day old nightly build of DMD.


DMD says:
`error LNK2019: unresolved external symbol "public: static int 
Test::var" (?var@Test@@2HA)`


I've checked the .exp file of the DLL where the symbol is 
defined in, and it has the exact same name there. And yes, I 
correctly link against that DLL in general, other symbols 
located in that DLL are linked just fine by DMD.


I can reproduce your problem. It seems to work if var is 
additionally static:


extern(C++, class) struct Test
{
   extern (C++) export extern static __gshared int var;
}

It's probably a bug, that it does not work without static. The 
documentation says "__gshared may also be applied to member 
variables and local variables. In these cases, __gshared is 
equivalent to static, except that the variable is shared by all 
threads rather than being thread local." 
(https://dlang.org/spec/attribute.html#gshared)




Re: How to pass a class by (const) reference to C++

2021-12-15 Thread Jan via Digitalmars-d-learn

On Wednesday, 15 December 2021 at 17:10:51 UTC, Tim wrote:

Do you have a test case for your problem?


C++
```cpp
class Test
{
public:
  __declspec(dllexport) static int var;
};

int Test::var = 42;
```

D
```cpp
extern(C++, class) struct Test
{
  extern (C++) export extern __gshared int var;
}
```

(also tried without the duplicate extern(C++) and without 
'export')


DLL compiled with Visual Studio 2019. D DLL compiled with a 3 day 
old nightly build of DMD.


DMD says:
`error LNK2019: unresolved external symbol "public: static int 
Test::var" (?var@Test@@2HA)`


I've checked the .exp file of the DLL where the symbol is defined 
in, and it has the exact same name there. And yes, I correctly 
link against that DLL in general, other symbols located in that 
DLL are linked just fine by DMD.





Re: How to pass a class by (const) reference to C++

2021-12-15 Thread Tim via Digitalmars-d-learn

On Wednesday, 15 December 2021 at 15:20:18 UTC, Jan wrote:
As I was told linking against functions in DLLs works 
perfectly, because it is identical to static linking. Linking 
against global/static variables supposedly differs and that's 
not handled correctly for DLLs. As I said, I talked to someone 
who worked on fixing lots of those issues a while ago and he 
immediately knew about this limitation.


I have used global variables from DLLs successfully. DMD now also 
has a test for C++ DLLs: 
https://github.com/dlang/dmd/blob/master/test/dshell/extra-files/dll_cxx/testdll.d


The variable should be declared like this in C++:
__declspec(dllexport) int value;

It can then be accessed from D with this:
extern (C++) export extern __gshared int value;

Do you have a test case for your problem?


Re: How to pass a class by (const) reference to C++

2021-12-15 Thread Jan via Digitalmars-d-learn

On Wednesday, 15 December 2021 at 12:36:49 UTC, evilrat wrote:
You probably know this but just in case - unlike C++ in D 
variables by default have thread local storage, to link with 
C++ global variable you need to use __gshared storage modifier 
in D, it is similar to 'shared' variable that unlike 'shared' 
tells the compiler "I know how to synchronize it myself".


```d
module a;

struct Foo {}

extern(C++)
__gshared Foo globalFoo;
```


Yeah, did that. As I said the mangled name that DMD chose is 
correct.


As I was told linking against functions in DLLs works perfectly, 
because it is identical to static linking. Linking against 
global/static variables supposedly differs and that's not handled 
correctly for DLLs. As I said, I talked to someone who worked on 
fixing lots of those issues a while ago and he immediately knew 
about this limitation.


Re: How to define property type to Array!struct?

2021-12-15 Thread Steven Schveighoffer via Digitalmars-d-learn

On 12/15/21 9:41 AM, Stanislav Blinov wrote:

On Wednesday, 15 December 2021 at 11:36:41 UTC, Manfred Nowak wrote:

On Tuesday, 14 December 2021 at 08:28:01 UTC, WebFreak001 wrote:
[...]

Alternatively, remove the template `()` from your `struct Header`


What is the semantic sense of a template having no parameters?

Although the documentation declares such a template to be 
syntactically correct, not a single example suggests a meaning.


To add to other responses, certain features are only available for 
templates, such as constraints and `auto ref` parameters.


Oh yeah, that reminds too -- a templated struct will have all member 
function attributes inferred.


-Steve


Re: How to define property type to Array!struct?

2021-12-15 Thread Stanislav Blinov via Digitalmars-d-learn
On Wednesday, 15 December 2021 at 11:36:41 UTC, Manfred Nowak 
wrote:

On Tuesday, 14 December 2021 at 08:28:01 UTC, WebFreak001 wrote:
[...]
Alternatively, remove the template `()` from your `struct 
Header`


What is the semantic sense of a template having no parameters?

Although the documentation declares such a template to be 
syntactically correct, not a single example suggests a meaning.


To add to other responses, certain features are only available 
for templates, such as constraints and `auto ref` parameters.


Re: How to define property type to Array!struct?

2021-12-15 Thread Steven Schveighoffer via Digitalmars-d-learn

On 12/15/21 6:36 AM, Manfred Nowak wrote:

On Tuesday, 14 December 2021 at 08:28:01 UTC, WebFreak001 wrote:
[...]

Alternatively, remove the template `()` from your `struct Header`


What is the semantic sense of a template having no parameters?

Although the documentation declares such a template to be syntactically 
correct, not a single example suggests a meaning.


It's just a template with no parameters, like a function with no 
parameters. It provides a separate namespace for items.


A struct with empty template parameters is equivalent to:

```d
template T()
{
   struct T {}
}
```

-Steve


Re: How to pass a class by (const) reference to C++

2021-12-15 Thread Adam D Ruppe via Digitalmars-d-learn

On Wednesday, 15 December 2021 at 10:54:45 UTC, Jan wrote:
Someone with more in-depth knowledge told me, that Windows 
support in D and specifically DLL support is lacking quite a 
bit.


gdc and ldc have the same full support you'd expect coming from 
microsoft c++.


dmd doesn't though. You can make full dlls with dmd just it is 
more diy than automatic.


*Using* dlls of course is something that's been fully supported 
since day one. Either using an import lib or GetProcAddress.






Re: How to pass a class by (const) reference to C++

2021-12-15 Thread evilrat via Digitalmars-d-learn

On Wednesday, 15 December 2021 at 12:02:08 UTC, Jan wrote:
On Wednesday, 15 December 2021 at 11:03:27 UTC, rikki 
cattermole wrote:


On 15/12/2021 11:54 PM, Jan wrote:

On Wednesday, 15 December 2021 at 09:36:54 UTC, Jan wrote:
Unfortunately it's the "annoying little details" that I 
immediately bumped into.


Just another example: I just learned that linking against C++ 
DLLs is quite limited. I ran into the issue that linking in 
an external variable doesn't work (even though the mangled 
name that D chooses is correct), because DLLs work 
differently than static linking does


Are you sure that on the shared library side it was marked as 
exported?


If a symbol is not exported, there is no guarantee (nor reason 
to think) that it will be visible during runtime linking to 
said shared library/executable.


This isn't unique to D, its just how linkers work.


Yep, checked that. Even checked the .exp file and compared the 
mangled name there with the mangled name that D tries to use, 
they are the same.


You probably know this but just in case - unlike C++ in D 
variables by default have thread local storage, to link with C++ 
global variable you need to use __gshared storage modifier in D, 
it is similar to 'shared' variable that unlike 'shared' tells the 
compiler "I know how to synchronize it myself".


```d
module a;

struct Foo {}

extern(C++)
__gshared Foo globalFoo;
```



Re: How to define property type to Array!struct?

2021-12-15 Thread bauss via Digitalmars-d-learn
On Wednesday, 15 December 2021 at 11:36:41 UTC, Manfred Nowak 
wrote:

On Tuesday, 14 December 2021 at 08:28:01 UTC, WebFreak001 wrote:
[...]
Alternatively, remove the template `()` from your `struct 
Header`


What is the semantic sense of a template having no parameters?

Although the documentation declares such a template to be 
syntactically correct, not a single example suggests a meaning.


In this case, nothing.

In other cases to only compile said "object" in specific 
conditions.


Re: How to define property type to Array!struct?

2021-12-15 Thread WebFreak001 via Digitalmars-d-learn
On Wednesday, 15 December 2021 at 11:36:41 UTC, Manfred Nowak 
wrote:

On Tuesday, 14 December 2021 at 08:28:01 UTC, WebFreak001 wrote:
[...]
Alternatively, remove the template `()` from your `struct 
Header`


What is the semantic sense of a template having no parameters?

Although the documentation declares such a template to be 
syntactically correct, not a single example suggests a meaning.


For functions there is a use-case: they will not be 
compiled/included in the executable until they are actually 
instantiated once.


Additionally for functions that means for libraries they aren't 
usually compiled into the resulting library file, unless they are 
used in the library themself. (only really meaningful when you 
don't distribute the D source or when interoping with other 
languages)


For types similarly, if you have any template instantiations 
inside your templated type, they will not be instantiated or 
compiled, until that template is used at least once in code 
anywhere.


So:
```d
struct Header()
{
Appender!string name;
}
```
unless Appender!string is used anywhere else in the code, that 
Appender struct will never be initiated, thus no member functions 
will be emitted or compile time will be used, until you 
instantiate the Header struct once.


Re: How to pass a class by (const) reference to C++

2021-12-15 Thread Jan via Digitalmars-d-learn
On Wednesday, 15 December 2021 at 11:03:27 UTC, rikki cattermole 
wrote:


On 15/12/2021 11:54 PM, Jan wrote:

On Wednesday, 15 December 2021 at 09:36:54 UTC, Jan wrote:
Unfortunately it's the "annoying little details" that I 
immediately bumped into.


Just another example: I just learned that linking against C++ 
DLLs is quite limited. I ran into the issue that linking in an 
external variable doesn't work (even though the mangled name 
that D chooses is correct), because DLLs work differently than 
static linking does.
Someone with more in-depth knowledge told me, that Windows 
support in D and specifically DLL support is lacking quite a 
bit.


Having *only* link compatibility is totally fine, D currently 
just doesn't fulfill that promise, especially not on Windows 
and especially not with DLLs.


Are you sure that on the shared library side it was marked as 
exported?


If a symbol is not exported, there is no guarantee (nor reason 
to think) that it will be visible during runtime linking to 
said shared library/executable.


This isn't unique to D, its just how linkers work.


Yep, checked that. Even checked the .exp file and compared the 
mangled name there with the mangled name that D tries to use, 
they are the same. I know someone who worked on improving DLL 
support for D a while back and he said he had to fix this in D 
but didn't get that merged into DMD back then (since there were 
many other things as well) and now he doesn't have time to work 
on it further :(


Re: How to define property type to Array!struct?

2021-12-15 Thread Manfred Nowak via Digitalmars-d-learn

On Tuesday, 14 December 2021 at 08:28:01 UTC, WebFreak001 wrote:
[...]
Alternatively, remove the template `()` from your `struct 
Header`


What is the semantic sense of a template having no parameters?

Although the documentation declares such a template to be 
syntactically correct, not a single example suggests a meaning.


Re: How to pass a class by (const) reference to C++

2021-12-15 Thread rikki cattermole via Digitalmars-d-learn



On 15/12/2021 11:54 PM, Jan wrote:

On Wednesday, 15 December 2021 at 09:36:54 UTC, Jan wrote:
Unfortunately it's the "annoying little details" that I immediately 
bumped into.


Just another example: I just learned that linking against C++ DLLs is 
quite limited. I ran into the issue that linking in an external variable 
doesn't work (even though the mangled name that D chooses is correct), 
because DLLs work differently than static linking does.
Someone with more in-depth knowledge told me, that Windows support in D 
and specifically DLL support is lacking quite a bit.


Having *only* link compatibility is totally fine, D currently just 
doesn't fulfill that promise, especially not on Windows and especially 
not with DLLs.


Are you sure that on the shared library side it was marked as exported?

If a symbol is not exported, there is no guarantee (nor reason to think) 
that it will be visible during runtime linking to said shared 
library/executable.


This isn't unique to D, its just how linkers work.


Re: How to pass a class by (const) reference to C++

2021-12-15 Thread Jan via Digitalmars-d-learn

On Wednesday, 15 December 2021 at 09:36:54 UTC, Jan wrote:
Unfortunately it's the "annoying little details" that I 
immediately bumped into.


Just another example: I just learned that linking against C++ 
DLLs is quite limited. I ran into the issue that linking in an 
external variable doesn't work (even though the mangled name that 
D chooses is correct), because DLLs work differently than static 
linking does.
Someone with more in-depth knowledge told me, that Windows 
support in D and specifically DLL support is lacking quite a bit.


Having *only* link compatibility is totally fine, D currently 
just doesn't fulfill that promise, especially not on Windows and 
especially not with DLLs.


Re: How to pass a class by (const) reference to C++

2021-12-15 Thread Jan via Digitalmars-d-learn

On Tuesday, 14 December 2021 at 07:50:48 UTC, evilrat wrote:
There is some missing features like above tail ref and const, 
there is minor mangling issues that requires pragma mangle 
sometimes, and other annoying little details.


As far as I can tell from my limited experience, the way D 
approaches interacting with C++ is sound and extremely useful. 
Link compatibility goes a very long way.


Unfortunately it's the "annoying little details" that I 
immediately bumped into. Things that should be no problem at all 
with just link compatibility, like incorrectly mangled functions 
(forgetting about 'const' in return types on Windows) and this 
very, very annoying issue that I can't pass a class by reference 
but only by pointer.


I can understand that passing a class by value might be out of 
scope (though it would be possible, since it works for structs 
just as well), but with pass by reference it's really just D's 
boneheadedness to try to have its own way.


D is a great language, and I want to use it, but as a stand-alone 
language it just doesn't have the ecosystem that I need 
(gamedev). Using it as an integrated scripting language is for me 
the next best thing to benefit from it in a project that is 
otherwise C++. With link compatibility and auto-generating some 
bindings, I can get there eventually, but it's still a lot of 
work with many manually crafted shims. I am currently willing to 
invest a lot of time to try to solve this, but I won't rewrite a 
huge C++ code base just because D can't pass classes by reference.


Other projects will have even more constraints and even less 
willingness to invest time into such an undertaking and just 
scrap the idea early on.


C++ link compatibility was a great idea, but if D wants to expand 
it's user base further, in my opinion it has to polish the 
interop and be willing to make a few sacrifices on it's end, 
because that can save everyone else hundreds of hours of tedious 
work (and maintenance) and thus be the deciding factor for or 
against using D in a C++ project.




Is there a place I can learn LLD inline assembly with GCC syntax?

2021-12-15 Thread rempas via Digitalmars-d-learn
I want to learn how to use inline assembly for LDC with GCC 
syntax specifically so I can support all the targets (as 
[here](https://wiki.dlang.org/Compilers) it is said that DMD 
intel-like syntax only supports the "i386" and "amd64" targets) 
but I cannot find anything other 
[this](https://wiki.dlang.org/LDC_inline_assembly_expressions) 
outdated page where It seems that it doesn't work (at least not 
for the sys_write example). Any ideas?