Re: How to make project with main application and cli application in the same folder?

2024-04-21 Thread Mike Parker via Digitalmars-d-learn

On Sunday, 21 April 2024 at 08:44:38 UTC, alex wrote:
Hi guys. Trying to play with vibe-d and want to create separate 
web app, and cli app which can add admin users. When I just 
keep both files app.d and cli.d in source folder, I get an 
error that I can't have more then 1 main function.




You can do this using configurations. Whichever you list first 
will be the default. Then you can use `-c configName` or 
`--config=configName` to build the other one.


You'll want to exclude one of the main functions when building 
the configuration to which it doesn't belong. You can do that 
with version specifications (e.g., add a `cli` version in the cli 
configuration, then `vesrion(cli) void main {...}` in the code). 
Alternatively, if the files the main functions are in are 
self-contained, then you can just exclude the one you don't need 
in each configuration with the `excludeSourceFiles` directive.


Configurations:
https://dub.pm/dub-guide/recipe/#configurations


Re: Best way to use large C library in D as of 2024

2024-03-30 Thread Mike Parker via Digitalmars-d-learn

On Saturday, 30 March 2024 at 05:01:32 UTC, harakim wrote:



@D Language Foundation - This is a HUGE selling point. I had to 
use cups the other day and I just copied some code from a d 
file and linked the library. It was so easy I was suspicious 
but it worked. Using C from D is pretty much as easy as using C 
from C and I think you should advertise that better!


Though I appreciate the sentiment, it's much more effective and 
efficient for people actually using the feature, and who 
appreciate it, to write up a blog post about it somewhere and 
share that on Twitter/Reddit/HN, etc.


Just a handful of people doing that would potentially reach a 
wider audience, they'd be able to show the feature in use in 
actual code, and their words will probably carry more weight as a 
language user than someone from the DLF. There's a world of 
difference between showing it in use in a real-world project vs. 
showing examples of how it can be used, which is all that I'd be 
able to do if I were to write about it.


And that goes for anything that makes you think "the DLF should 
advertise this". I mean, when I had time to prioritize the blog, 
I was regularly writing articles about cool D features, and 
sometimes getting others to write guest posts about their 
projects or whatever. But that's pretty much like one person 
standing on a hilltop with a megaphone, periodically handing it 
off to someone else.


How many other people from the D community were adding their 
voices? Now and then, someone would write something up somewhere, 
but it wasn't happening regularly or often.


Anyone happy using D, who wants to see it continue to grow and 
improve, can help toward that end by telling the world about it.


That said, if there's anyone out there who would like to take on 
management of the blog and make it more active, I'd love to hear 
from you.


Re: DIP 1036e not on the DIPs list?

2024-02-23 Thread Mike Parker via Digitalmars-d-learn

On Friday, 23 February 2024 at 23:30:26 UTC, kdevel wrote:

The DIP 1036e is not listed in

   https://github.com/dlang/DIPs/tree/master/DIPs

is this intentional?


The DIP process has been closed for a while now. Atila did write 
a proposal for Adam's implementation, and I'll add it to the repo 
after I open up the DIP process again (reopening very soon). It 
won't be 1036e, though.


Re: pragma lib doesn't support static libraries?

2023-07-29 Thread Mike Parker via Digitalmars-d-learn

On Sunday, 30 July 2023 at 05:28:32 UTC, ryuukk_ wrote:

I should have explained exactly what i am doing..

Looks like it doesn't work when i compile in 2 step

- compile with: ``dmd -c of=bin/game.o``
- link with: ``dmd bin/game.o``

When doing it this way, then it doesn't work

However, when compiling/linking in one ``dmd`` invocation 
(without ``-c``), then it all works


So it looks like the pragma is not passed on the linked when it 
was compiled with ``-c``


Is this a bug? should i report it?, or is that the expected 
behavior?


It's expected behavior. There's no link step in the first 
command, so the pragma is meaningless there. And I'm unaware of 
any mechanism for embedding static library names in an object 
file for a linker to read later.


Re: Designated initializers to function argument

2023-07-28 Thread Mike Parker via Digitalmars-d-learn

On Friday, 28 July 2023 at 21:07:47 UTC, bachmeier wrote:

On Friday, 28 July 2023 at 17:07:37 UTC, IchorDev wrote:




No shit, it felt like an eternity. But it's still not in the 
spec...?


I'd expect it to appear in the spec after there's a real 
release. This is the first I've heard of it being supported, 
and it sounds like it's incomplete.


https://github.com/orgs/dlang/projects/19

Dennis has been working on this in pieces rather than all at 
once, as it required modification to multiple parts of the 
compiler.


Re: GDC Compilation wtih Directory Present

2023-06-16 Thread Mike Parker via Digitalmars-d-learn

On Friday, 16 June 2023 at 06:38:17 UTC, Murloc wrote:



Thanks! That works well. I thought that `module pack.file1` is 
implicitly there by default :')


The compiler will use the file name as a default module name if 
you don't provide one, but that's *just* the module name. It 
doesn't take into account any directories for package names.


Re: GetInterfaceInfo function of win32 api

2023-06-08 Thread Mike Parker via Digitalmars-d-learn

On Thursday, 8 June 2023 at 07:01:44 UTC, Benny wrote:


I got something! thank you.
now I need to understand how can I get the properties of the 
GetInterfaceInfo


```
import core.sys.windows.iphlpapi;
import std.stdio;
import core.stdc.stdlib;

void main()
{
uint* i;
i = cast(uint*) malloc(10);
auto h = GetInterfaceInfo(null, i);
writefln("%s", h);
writeln("Hello, World!");
}

```

this got me 122


Alright. I've never used this function, so I referenced the 
documentation here:


https://learn.microsoft.com/en-us/windows/win32/api/iphlpapi/nf-iphlpapi-getinterfaceinfo

First, you don't need to allocate i with malloc. Just declare it 
as a uint and give the function a pointer to it.


Second, the function is intended to be called twice. The first 
time with null for the first parameter as you've done here. After 
that call, the value in i should be the size of the memory you 
need to allocate for the first parameter on the second call. In 
the second call, the data you want will be stored in that pointer.


Third, the first parameter is of type PIP_INTERACE_INFO, which in 
Windows lingo means "pointer to IP_INTERFACE_INFO". That's 
declared in the ipexport module.


Here's a working example. I chose to use the GC rather than 
malloc.


```d
import core.sys.windows.windows,  // For the error codes
   core.sys.windows.iphlpapi,
   core.sys.windows.ipexport;

import std.stdio,
   std.string;

void main()
{

IP_INTERFACE_INFO* pinfo;
uint buflen;

// Get the size needed to alloc pinfo
uint ret = GetInterfaceInfo(null, );
if(ret == ERROR_INSUFFICIENT_BUFFER) {
// Allocate pinfo, but let's not use malloc
ubyte[] buf = new ubyte[](buflen);
pinfo = cast(IP_INTERFACE_INFO*)buf.ptr;
}

// Call the function a second time to get the data
ret = GetInterfaceInfo(pinfo, );
if(ret == NO_ERROR) {
writeln("Number of adapters: ", pinfo.NumAdapters);
for(size_t i = 0; iwritefln("Adapter Index[%s]: %s", i, 
pinfo.Adapter[i].Index);
writefln("Adapter Index[%s]: %s", i, 
fromStringz(pinfo.Adapter[i].Name));

}
}
else if(ret == ERROR_NO_DATA) {
writeln("No network adapters found");
}
else {
writeln("GetInterfaceInfo failure: ", ret);
}
}
```







Re: GetInterfaceInfo function of win32 api

2023-06-08 Thread Mike Parker via Digitalmars-d-learn

On Thursday, 8 June 2023 at 05:52:43 UTC, Benny wrote:


```
```
app.obj : error LNK2019: unresolved external symbol 
GetInterfaceInfo referenced in function _Dmain

app.exe : fatal error LNK1120: 1 unresolved externals
Error: linker exited with status 1120
```


That's a linker error telling you that you aren't linking 
anything that contains the symbol for `GetInterfaceInfo`. You 
need to link `Iphlpapi.lib`.




Re: unittest under betterC

2023-06-05 Thread Mike Parker via Digitalmars-d-learn
On Monday, 5 June 2023 at 14:29:35 UTC, Richard (Rikki) Andrew 
Cattermole wrote:

On 06/06/2023 2:25 AM, Mike Parker wrote:

On Monday, 5 June 2023 at 14:16:39 UTC, ryuukk_ wrote:

In my book this is broken and needs to be fixed, as a user i 
don't care about under the hood things, it's a you problem, 
user should be able to unit test


The docs say it should work:

https://dlang.org/spec/betterc.html#unittests

So either the docs are wrong or the implementation is bugged. 
If there's no issue yet, could you please file one?


Yes that is what I recommended earlier in the thread. But 
automatic running requires druntime.


Ah, I see now. It's working as expected then.


Re: unittest under betterC

2023-06-05 Thread Mike Parker via Digitalmars-d-learn

On Monday, 5 June 2023 at 14:16:39 UTC, ryuukk_ wrote:

In my book this is broken and needs to be fixed, as a user i 
don't care about under the hood things, it's a you problem, 
user should be able to unit test


The docs say it should work:

https://dlang.org/spec/betterc.html#unittests

So either the docs are wrong or the implementation is bugged. If 
there's no issue yet, could you please file one?


Re: How does D’s ‘import’ work?

2023-06-03 Thread Mike Parker via Digitalmars-d-learn

On Saturday, 3 June 2023 at 09:04:35 UTC, Dom DiSc wrote:


You can replace your whole makefile by calling the compiler 
with -I (not always, but if you don't do funny things in your 
makefile).


That would be `-i`.

- This ability of the D compiler was just recently discovered 
(after -I was implemented for other reasons), but it relies on 
the fact that we have imports.


Jonathan Marler implemented it in 2017 after a discussion in the 
forums.


https://github.com/dlang/dmd/pull/7099


Re: How static link dll msvcr120.dll?

2023-06-01 Thread Mike Parker via Digitalmars-d-learn

On Thursday, 1 June 2023 at 15:05:40 UTC, Marcone wrote:



I linked msvcr120.lib, but the executable still ask for 
msvcr120.dll not found.


msvcr120.lib is a "link library", not a static library. On other 
systems, you pass shared libraries directly to the linker and it 
will pull the information it needs from there to set up the 
exectuable with what it needs for the system loader to load the 
shared library at runtime. Windows works differently. The 
compiler puts all that information in a link library when it 
creates the DLL, and you pass that to the linker instead of the 
DLL.


Windows system libraries are not distributed as static libraries 
as far as I know.


Re: A Programmer's Dilema: juggling with C, BetterC, D, Macros and Cross Compiling, etc.

2023-05-01 Thread Mike Parker via Digitalmars-d-learn

On Monday, 1 May 2023 at 09:17:14 UTC, Eric P626 wrote:

This is a false dilemma: D has full C compatibility.


From what I understand, D can use C, but C cannot use D? It's 
like C++: C++ can call C but C cannot call C++.


50% or more of my code will be put in re-usabled libraries. If 
I want people to use those libs, I would need to compile them 
in C or better C. Because betterC seems to create C libraries. 
If D can make C libraries, then indeed, I could do everything 
in D.




D is ABI-compatible with C. BetterC has nothing to do with it. 
And if you're using BetterC just because you're linking with a C 
library, you're crippling your D code. That's not really a good 
use case for it.


Any D function marked as `extern(C)` can be called from C. As 
long as you have a C header file defining the functions and the 
appropriate C declarations any custom types you have, the C code 
will have no idea it's calling into a D library.


In your D library:
```D
// This function can be called from C
extern(C) void functionForTheCAPI(const(char)* str) {
import std.conv : to;
doSomething(to!string(str));
}

// This is a D function that cannot be called from C
void doSomething(string s) { ... }
```

In the corresponding C header:
```C
extern void functionForTheCAPI(const char* str);
```

Just `#include` the C header in your C code, link with the D 
library, and you're good to go. Make sure to include a function 
somewhere in your D library's C API to initialize DRuntime:


```D
import core.runtime;

extern(C) int initialize() { return Runtime.initialize(); }
```

Add the declaration to a C header and you're good to go.




Re: A Programmer's Dilema: juggling with C, BetterC, D, Macros and Cross Compiling, etc.

2023-05-01 Thread Mike Parker via Digitalmars-d-learn

On Monday, 1 May 2023 at 09:35:59 UTC, Dukc wrote:
hard. Seems the C-linked functions in 
[core.runtime](https://dlang.org/phobos/core_runtime.html#.Runtime.initialize) ought to do the trick.


If you're referring to `rt_init` and `rt_term` are the 
`extern(C)` functions in `core.runtime`. It's not necessary to 
call those from C. A D library with a C interface can provide an 
`extern(C)` initialization function that internally calls 
`Runtime.initialize`.


Re: Making a D library for a C executable

2023-04-27 Thread Mike Parker via Digitalmars-d-learn

On Thursday, 27 April 2023 at 20:32:24 UTC, Jan Allersma wrote:


```
Apparently foo isn't found from the CPP source file. Anyone 
some ideas on how to solve this? :)


That's a compilation error, not a linker problem. You need to 
tell the compiler about the function with a prototype:


```C++
#include 

int foo();

int main() {
  std::cout << "deede" << foo() << std::endl;
}
```




Re: Cannot get this C++ example migrated to D

2023-04-16 Thread Mike Parker via Digitalmars-d-learn

On Sunday, 16 April 2023 at 07:46:53 UTC, Skippy wrote:



I wish D had value type classes as well.


I like the distinction between class and struct in D. It 
encourages you to think harder about how you intend to use your 
types. In C++, there may as well only be one or the other; the 
distinction is so small as to be meaningless.


Re: Cannot get this C++ example migrated to D

2023-04-16 Thread Mike Parker via Digitalmars-d-learn

On Sunday, 16 April 2023 at 05:58:39 UTC, Skippy wrote:

These lines aren't necessary:


// ??
int counter;

// ??
static this()
{
counter = test.objCnt;
}



`t1` is default-initialized, so it's null.

test t1, t2 = new test();


Ditto for t3. Classes are reference objects, not value objects, 
so you must explicitly instantiate instances if you want them to 
be non-null.

test t3;


The modified code:

```d
class test
{
  private:
int objNo;
static int objCnt;

  public:
this()
{
objNo = ++objCnt;
}

~this()
{
--objCnt;
}

void printObjNumber()
{
writefln("object number : %s", objNo);
}

static void printObjCount()
{
writefln("count: %s", objCnt);
}
}


int main()
{
test t1 = new test(), t2 = new test();

test.printObjCount();

test t3 = new test;
test.printObjCount();

t1.printObjNumber();
t2.printObjNumber();
t3.printObjNumber();

return 0;
}
```


Re: Unresolvable dependencies to package

2023-04-14 Thread Mike Parker via Digitalmars-d-learn

On Saturday, 15 April 2023 at 00:42:17 UTC, Mike Parker wrote:

I also suggest you visit the issues page for bindbc-imgui and 
file an issue there:


I meant to delete this line. I've filed the issue:

https://github.com/BindBC/bindbc-imgui/issues/1


Re: Unresolvable dependencies to package

2023-04-14 Thread Mike Parker via Digitalmars-d-learn

On Friday, 14 April 2023 at 20:30:56 UTC, el machine code wrote:
so my question why am i'm getting this error and how do i fix 
this?


The two listed packages depend on bindbc-sdl, and they do so in a 
way that is incompatible with each other.


On your end, you can edit `dub.selections.json` in your project's 
root directory alongside your `dub.json` and specify the version 
of bindbc-sdl that dub should choose. In this case, it should be 
the same as inochi-creator since that's the latest version:


```json
"dependencies": {
"bindbc-sdl": "~>1.1.2"
},
```

That should resolve the conflict. This approach can cause issues 
when the conflicting versions of a library are incompatible 
(e.g., missing symbols), but in this case you should be fine. As 
far as I'm aware, there should be no incompatibilities betwen 
binbc-sdl 0.x and 1.x.


I also suggest you visit the issues page for bindbc-imgui and 
file an issue there:


https://github.com/BindBC/bindbc-imgui/issues

The BindBC maintainer recently took over binbc-imgui and added it 
to the BindBC group (it was originally maintained independently 
of the BindBC group). The version of `dub.sdl` in master depends 
on bindbc-sdl 1.1.2, but that version has not been tagged as a 
new release. I'll file an issue there to prompt a new release, 
and I'll also file an issue with inochi-creator to use the new 
release once it's tagged.


But for now, `dub.selections.json` should get your immediate 
problem sorted.


Re: How to setup D with SFML? (using bindbc-sfml)

2023-04-09 Thread Mike Parker via Digitalmars-d-learn

On Sunday, 9 April 2023 at 09:54:26 UTC, Ki Rill wrote:



Why can't it find these libraries? I tell where to look for 
them:

```D
version(Windows) {
import bindbc.loader;
setCustomLoaderSearchPath("libs"); // tried using absolute 
path as well

}
```

That is strange...


I've tried your project out two ways, one that succeeds and one 
that fails. I'm guessing you've put your 'libs' directory is 
'bin/libs'. Am I right? If so, then the following should help you.


When dub runs the exectuable, it sets the current working 
directory to the project's root directory by default. 
`setCustomLoaderPath` passes whatever you give it directly to the 
system API unmodified. You've passed a relative path. By default, 
the system API associates relative paths with the current working 
directory.


So given a project root directory of `$ROOT`, and your executable 
in `$ROOT/bin`, the system is looking for the libraries in 
`$ROOT/libs` and *not* in `$ROOT/bin/libs`. If the libs are in 
the former, everything loads. If they're in the latter, then it's 
going to fail.


If you cd into `bin` and run the executable manually, then libs 
in `$ROOT/bin/libs` will load, as your current working directory 
is `bin`.


The quick fix for this is to add `"workingDirectory" : "bin"` to 
your dub.json. Then your relative paths will be relative to 
`$ROOT/bin/`.


Bear in mind that when using relative paths like this, any file 
reading is bound to break if someone runs your executable from 
outside its directory. You can test this by going into `$ROOT` 
from the command line and executing 
`bin/d-sfml-project-template`. Then you'll be doing the same 
thing dub does, i.e., your working directory will be `$ROOT`.


The way to guarantee your relative paths are always relative to 
the executable are to either set the current working directory to 
the executable's path, or to prepend all relative paths with the 
executable's path before handing them off to the system.


There are two ways you can get the full path to the executable in 
Phobos/DRuntime: via `std.file.thisExePath`, or 
`core.runtime.Runtime.args[0]`. (The former is failing to compile 
for me on Windows right now due to a bug in the Phobos Win32 API 
bindings. I'll look into it.)


Strip the file name from the returned path, then you can use it 
as required.









Re: How to setup D with SFML? (using bindbc-sfml)

2023-04-08 Thread Mike Parker via Digitalmars-d-learn

On Saturday, 8 April 2023 at 11:31:40 UTC, Ki Rill wrote:
How do I set up a D and SFML project using the `bindbc-sfml` 
package?


I tried following the instructions, it builds successfully, but 
fails to load the SFML library at runtime.


In particular, `loadSFML, loadSFMLGraphics, loadSFMLXXX` fails. 
Here is 
[link](https://github.com/rillki/d-sfml-project-template) to 
the repo. I plan to create another how-to video, but I cannot 
find what's causing it to fail.


Do you have any ideas?


Not without error messages. The first thing you should do is use 
the error API in bindbc.loader to print them out. That should 
tell you what the problem is.


Re: #define-like behavior

2023-03-14 Thread Mike Parker via Digitalmars-d-learn

On Tuesday, 14 March 2023 at 05:47:35 UTC, Jeremy wrote:
Hi, in C and C++ you can use #define to substitute a value in 
place of an identifier while preprocessing. If you initialize a 
new string and don't change its value after that, will the 
compiler substitute the string identifier with its value, like 
#define in C, or will it make a string in memory and refer to 
that?


Manifest constants in D have a similar effect as #defined values, 
e.g.:


```d
enum someVal = 10;

writeln(someVal);
```

Here, the effect is the same as if you'd written `writeln(10)`. 
The difference is that with the preprocessor, it's a text 
replacement on the source before the compiler gets ahold of it, 
but in D the compiler handles the substitution internally.


The same is true for string literals:

```d
enum str = "Hello";
writeln(str);
```

String literals get special treatment from the compiler in that 
they are "interned".


```d
auto s1 = "What's up?";
auto s2 = "What's up?";
```

The literal "What's up?" *should* be stored in the binary only 
once, so both s1 and s2 will point to the same location. 
Substitute a manifest constant and the effect should be the same:


```d
enum greeting = "What's up?";
auto s1 = greeting;
auto s2 = greeting;
```

Just be aware that there's a consequence for array literals:

```d
enum vals = [1, 2, 3];

auto a1 = vals;
auto a2 = vals;
```

This allocates two dynamic arrays, not one. Everywhere you use 
`vals` it's just like using the literal directly, which usually 
means an allocation.





Re: Code organization, dub, etc.

2023-03-13 Thread Mike Parker via Digitalmars-d-learn

On Monday, 13 March 2023 at 13:20:21 UTC, Joe wrote:

Yeah, it seems like it's *only* for libraries (and a few 
single-exe utilities).  Looking at code.dlang.org, under 
"Stand-alone applications/Server software", the top rated item 
is "handy-httpd" which according to its dub.json builds a 
library! And the second place "voxelman" is builds three 
libraries and one executable, which appears to be a "launcher" 
to access the libraries as plugins.


The package registry is full of libraries, yes. That's what it's 
primarily for. There aren't a lot of executables uploaded there 
because they're usually better distributed in other ways. But 
plenty of people are using dub to build them.


One way to handle multiple executables is to write a simple 
script that makes multiple calls to dub with the configurations 
you need.


And I haven't looked into it yet, but it may be possible to use 
`preBuildCommands` to do the same thing. E.g., add a default with 
a `preBuildCommands` entry calling dub on multiple configurations.


Re: Directly compiling a D program with other libraries

2023-03-13 Thread Mike Parker via Digitalmars-d-learn

On Monday, 13 March 2023 at 05:05:27 UTC, Jeremy wrote:

Hello, I am new to this forum and to D.

I am trying to compile a basic D program with libraries 
(`requests` which requires `cachetools` and `automem`) without 
using dub. I have never used dub before, only a compiler.


The folders containing the libraries are in the same folder as 
main.d, the file I am trying to compile, and the command I am 
using to compile is `ldc2 -I. main.d`.


When I compile my program, I just get linker errors such as:
```
/usr/lib/gcc/x86_64-pc-linux-gnu/12/../../../../x86_64-pc-linux-gnu/bin/ld: 
main.o: in function `_Dmain':
main.d:(.text._Dmain+0x2f): undefined reference to 
`_D8requests10getContentFNcAyaZSQBd7streams__T6BufferThZQk'

```

Does anyone have any advice on how to solve my problem?


That's a linker error, meaning the missing symbol isn't available 
to link into the executable. You need to compile the source of 
all the libraries you use and make sure the resultant binaries 
are available for the linker to link into the executable.


The -I switch you've passed tells the compiler where to find 
imported modules. The compiler needs parse them to know which 
symbols are available for you to use when it's compiling your 
code. (The current working directory is the default anyway, so 
you don't need to pass `-I.` for that.)


By default, the compiler does not compile imported modules. If 
you add `-i` to the command line, then it will compile all of the 
modules you import (as long as they're in the `-I` path), 
excluding the DRuntime and Phobos modules. It will then also pass 
all of the compiled object files to the linker, so then your 
linker error should go away.


However, when you choose not to use dub, you need to also ensure 
that you are accounting for any special compiler flags the 
libraries you use may require (for example, specific `-version` 
values). If they're configured to compile as static or shared 
libraries, it may be easier just to store the source for each of 
them outside of your project's source tree, use dub to build each 
of them, and then pass the compiled libraries to the compiler 
when you build your program. In that case, you wouldn't use `-i`. 
Just make sure that `-I` is correctly configured in that case.


Re: @nogc and Phobos

2023-03-11 Thread Mike Parker via Digitalmars-d-learn

On Saturday, 11 March 2023 at 12:04:25 UTC, bomat wrote:


So my question is:
Is Phobos essentially incompatible to `@nogc`?
Or is there a trick for mixing GC code with non-GC code that I 
don't know?


I'm assuming the second, for if the first was true I'd say that 
D would be pretty much useless when combined with non-D libs...


Any function annotated with `@nogc` can only call other `@nogc` 
functions, but they can be called by *any* function. So it won't 
affect your use of the GC or Phobos in that regard.


Or is there a specific problem you've encountered?


Re: How to build a static lib properly?

2023-03-05 Thread Mike Parker via Digitalmars-d-learn

On Monday, 6 March 2023 at 02:09:23 UTC, ryuukk_ wrote:




dub should build a static library for the project i build, that 
includes each library it uses that are referenced as "library" 
since the default is "staticLibrary" according to rikki


What you're asking for is a different use case. `staticLibrary` 
is for compiling a specific dub package as a static library. It 
does not imply that all of that package's dependencies should 
also be compiled into a single static library. Nor should it.


You're asking for a package and its dependencies to be bundled 
for use outside of the dub ecosystem as a single static library. 
I won't say it's not a legitimate use case, it's just not one 
that dub currently supports, nor was it originally intended to (I 
wouldn't expect it to be a common one either, but then again 
common expectations are always changing).


As a potential dub enhancement, e.g., `staticLibraryBundle`, I do 
agree it's worth exploring. I don't believe you can expect every 
package to "just work" in that environment. As Steve mentioned, 
there will always be link-time dependencies to any shared 
libraries on which those bundled libraries depend. And some 
packages may be set up in a way that causes issues, as Rikki 
noted when he said he had to make some tweaks on his successful 
build.


But for the time being, dealing with static libraries in D is 
just the same as dealing with them in the C and C++ world. They 
always have been a PITA to deal with, and that's why the trend in 
recent years has been to move away from them. Build tools like 
dub hide them from you when used as intended. It's when you mix 
build systems that you run into trouble.


Still, I suggest you send an email to soc...@dlang.org as part of 
the Gripes and Wishes campaign so that this gets added into the 
dataset. Anything that enhances dub's usability should be looked 
at.





Re: How to build a static lib properly?

2023-03-05 Thread Mike Parker via Digitalmars-d-learn

On Monday, 6 March 2023 at 01:52:06 UTC, ryuukk_ wrote:
6B71D90\dparse.lib -g

```


Are you saying dub doesn't build a static dcd.lib?

What to do to make it so i get a static dcd.lib file that 
contains all the code it needs?


This comfort me in my desire to no longer use dub ever


This is not dub's fault. When building a shared library, there's 
a link step, so any external dependencies are linked into the 
shared library just as they are with an executable. There is no 
link step with a static library. That means when you build your 
executable, you need to also link the static library's 
dependencies along with it.


Most of the symbols in your list appear to come from the packages 
listed in the dependencies section of DCD's dub.json:


https://github.com/dlang-community/DCD/blob/master/dub.json

So if you want to do this manually, with DCD as a static library, 
then you also need to build all of those dependencies and link 
them with your executable.


Re: Non-ugly ways to implement a 'static' class or namespace?

2023-02-19 Thread Mike Parker via Digitalmars-d-learn
On Monday, 20 February 2023 at 06:26:34 UTC, FeepingCreature 
wrote:




There have now been three pages produced by three people all 
agreeing with each other.


At what point does it start being spam?


Yes, it's all just noise now. Let's end it here. Further posts in 
this thread will be deleted.


Re: Dub is not finding the dynamic link library MSVCR120.dll...

2023-02-19 Thread Mike Parker via Digitalmars-d-learn

On Sunday, 19 February 2023 at 21:05:33 UTC, WhatMeWorry wrote:


and is abending with an error saying exactly this.  How do I 
specify the path to this library?  Can I use one of the 
environment variables in sc.ini, one of the Windows env 
variables, or one of the dub options?


Btw, I'm bypassing on purpose the official D installation.


Any error about a missing DLL is a run-time error that's 
unrelated to dub or the compiler.


Normally, for end users, a missing MSVC runtime DLL means you 
have to install the MSVC Redistributable package. This version of 
the DLL you're missing is from MSVC 2013, so that's the version 
of the package you'd need.


However, I wonder what's causing the problem in the first place. 
Do you have Visual Studio installed, or are you using the 
out-of-the-box libraries and linker that ship with DMD?




Re: Non-ugly ways to implement a 'static' class or namespace?

2023-02-15 Thread Mike Parker via Digitalmars-d-learn

On Thursday, 16 February 2023 at 02:26:44 UTC, Mike Parker wrote:


Wrong. I'm arguing  things:


Geez. "I'm arguing 2 things:"


Re: Non-ugly ways to implement a 'static' class or namespace?

2023-02-15 Thread Mike Parker via Digitalmars-d-learn
On Wednesday, 15 February 2023 at 20:10:31 UTC, ProtectAndHide 
wrote:




What Mike is arguing, is that I don't need a 'data hiding' 
mechanism for a user-defined type, because that is already 
provided to me by the 'data hiding' mechanism of the module.


That is his argument.

My argument is that I want 'data hiding' mechanism at the 
user-defined type level as well.


Again, his argument is that i don't need it.. because...




Wrong. I'm arguing  things:

1. D has encapsulation (you say it doesn't).
2. We don't need a new protection attribute or a redefinition of 
private because D already provides the mechanism to give you what 
you want.


Re: Non-ugly ways to implement a 'static' class or namespace?

2023-02-15 Thread Mike Parker via Digitalmars-d-learn

On Wednesday, 15 February 2023 at 09:51:41 UTC, zjh wrote:



What if two classes in the module that are several meters apart 
make `mistakes` that change the privite variable of `another 
class`?


No one can guarantee that after `a few months`, even if you are 
the author, you will not make mistakes, so as to misuse private 
variable, while `class level` private can be completely avoided 
it!


There is no maintainability, because two `out-of-class` 
functions may quietly change your private `variables`.


I referenced that in my post. The exact same problem exists 
*inside* the class when your class file is very long. You can 
easily manipulate the private member even when it's only supposed 
to be accessed by a specific function. A common recommendation in 
Java used to be (and probably still is) to always accessing 
private members by their setters even inside the class. And after 
all these years they haven't had a need to lock down 
single-method access to private members. It's the *exact* same 
thing in D: the private implementation is in the source file. The 
fact that the source file represents a module rather than a 
single class is irrelevant.


We keep repeating the same arguments over and over and over again 
on this. I still haven't seen any convincing argument for 
changing things when it's already possible to do what you want to 
do. I repeat for the umpteenth time: if you care so much about 
who can touch your private parts, then put your classes and 
structs in their own modules and use D's package facilities to 
provide the public interface you want.


Re: Non-ugly ways to implement a 'static' class or namespace?

2023-02-15 Thread Mike Parker via Digitalmars-d-learn

On Wednesday, 15 February 2023 at 08:56:00 UTC, Mike Parker wrote:

If private were restricted to the class/struct, it would add 
anything more for encapsulation in D.


I meant to say, it "wouldn't add more".


Re: Non-ugly ways to implement a 'static' class or namespace?

2023-02-15 Thread Mike Parker via Digitalmars-d-learn
On Wednesday, 15 February 2023 at 07:23:39 UTC, thebluepandabear 
wrote:




Why is the unit of encapsulation the module though? Makes no 
sense.


What is the purpose of encapsulation? To keep the implementation 
details hidden behind the public API, such that changing the 
implementation doesn't change the API.


Consider this:

```d
module gfx;
struct Point {
private int x, y;
this(int x, int y)
{
this.x = x;
this.y = y;
}

void move(Point to) {
x = to.x;
y = to.y;
}
}
```
Here, `move` is part of the public API. `x` and `y` are part of 
the implementation. Nothing outside the module can touch them.


Now this:

```d
module gfx;
struct Point {
private int x, y;
this(int x, int y)
{
this.x = x;
this.y = y;
}
}

void move(ref Point from, Point to) {
from.x = to.x;
from.y = to.y;
}
```

From the perspective of the public API, nothing has changed. The 
following works in both cases:


```d
Point p;
p.move(Point(10, 20));
writeln(p);
```

In both cases, the implementation is hidden behind the same 
public API.


If private were restricted to the class/struct, it would add 
anything more for encapsulation in D. In practical terms, if you 
are editing the `gfx` module, you also have access to the 
implementation details of `Point`.


Sure, if you have e.g., a special setter that does some extra 
work when a member variable is set, you want to ensure that only 
that setter is used to change the member variable. But that's 
true *inside the class/struct* as well.


I mean, just consider this:

```d
class C {
private enum minX = -100;
private int _x;

void setX(int newX) { _x = newX > minX ? newX : minX }

void doSomething(State s) { setX(_x + s.val); }
}
```

vs. this:

```d
class C {
private enum minX = -100;
private int _x;

void setX(int newX) { _x = newX > minX ? newX : minX }
}

void doSomething(C c, State s) { c.setX(c._x + s.val); }
```

Ideologically, they are not the same. In practical terms, they 
are. Whether the closing brace of the class declaration is before 
or after `doSomething` matters not one bit. Yes, things can go 
wonky in a module that's many lines long and someone sets `_x` 
from outside of the class. So what? The same is true for a class 
that's many lines long when someone adds a new method that 
directly sets `_x` rather than going through the setter.


D's modules are intended to be used for grouping related 
constructs. Everything in the module is part of the same private 
implementation. If the constructs aren't related, then put them 
in separate modules. And there's still a solution for anyone with 
a strict ideological preference regarding related constructs: 
they can put their classes and structs in individual modules 
under a common package. `package` protection can be used for 
cross-module access inside the package, and the entire set can be 
presented to the outside world as a single module with 
`package.d`.


Our friend of many forum handles misses no opportunity to return 
to this putrid horse corpse to beat it some more, but the meaning 
of private isn't going to change. This is D's approach to 
encapsulation.




Re: Non-ugly ways to implement a 'static' class or namespace?

2023-02-14 Thread Mike Parker via Digitalmars-d-learn
On Wednesday, 15 February 2023 at 01:16:00 UTC, thebluepandabear 
wrote:




I think what you could say is that D lacks _encapsulation_ 
which is also an OOP concept. So D is partially OOP but not 
fully OOP due to there being no encapsulation in the language.


D does not lack encapsulation, it's just that the unit of 
encapsulation is the module. Everything private in a module is 
encapsulated from the perspective of the public API.


If you really want to prevent anything inside a module from 
accessing the private parts of a class, you can put the class in 
its own module.


Must we continue beating this horse?


Re: Non-ugly ways to implement a 'static' class or namespace?

2023-01-22 Thread Mike Parker via Digitalmars-d-learn
On Monday, 23 January 2023 at 00:36:36 UTC, thebluepandabear 
wrote:




I haven't been programming for a long time, but most of the 
other languages I used had such a namespace feature. Kotlin has 
something called an `object` which is essentially a namespace 
and it is great. The benefits of adding a namespace-like 
feature outweigh its costs, imo.


If you really want to, you can mostly force a namespace use like 
this:


```
// mylib/package.d
module mylib;
public static import mylib.impl.funcs;

// mylib/impl/funcs.d
module mylib.impl.funcs;

void foo() { }
```

Now when users import mylib, the public static import means hey 
call mylib.foo. Just don't bother documenting the impl subpackage 
and only those who look at the source will even know it exists.


I went through this same process when I first came to D years 
ago. D's modules *are* namespaces, and I wanted a way to force 
them. Eventually, I got over it. There's no reason to force a 
namespace. Namespaces are intended to disambiguate conflicting 
symbols. So let the users use them that way. There's no need to 
force them to type out the namespace all the time. It's certainly 
not an OOP vs. procedural issue, as namespaces have nothing to do 
with OOP.


Re: Non-ugly ways to implement a 'static' class or namespace?

2023-01-22 Thread Mike Parker via Digitalmars-d-learn
On Monday, 23 January 2023 at 00:11:17 UTC, thebluepandabear 
wrote:




Sorry don't like that solution specifically. That's because it 
is a procedural implementation, not an OOP-style one. I don't 
know how much of the D community writes procedurally but I'm 
personally an OOP-type of guy.


A class full of static methods is not OOP either.


Re: (Noob question) Should subclasses be defined in separate modules?

2023-01-12 Thread Mike Parker via Digitalmars-d-learn
On Friday, 13 January 2023 at 05:17:59 UTC, thebluepandabear 
wrote:

(Sorry if this is a duplicate.)

If I have the following code inside of a module:

```D
class Obj {
private {
string name = "Hi";
}
}

class ObjDerived : Obj {

}
```

Is it best practice to define `ObjDerived` inside another 
module, since `ObjDerived` can still access the members of 
`Obj` (since `private` is only applied to modules), or does 
this go against the intended use of the language?


As a beginner, I am having an extremely tough time 
understanding why you would want to place these two classes in 
the same module or even have this intended behavior of 
`private`. I am coming from Java/Kotlin which are both strictly 
OO language and have different ways of encapsulation.


The short answer: just think of a module as a way of grouping 
related objects and functions. If it makes sense to you for 
`ObjDerived` to have access to the internals of `Obj`, then keep 
them in the same module. If it doesn't, then put it somewhere 
else.


The long answer: there's no one-size-fits all here. For a short 
program, a script let's say, just dump everything in one module 
and be done with it. For a program you're writing for your own 
use, do whatever you feel comfortable with, even if you plan to 
open source it.


For something you're writing for others to use, like a library, 
then the first priority is to think about what the public facing 
API should look like. From that perspective, does `ObDerived` 
belong in the same module, or is it unrelated enough to go into a 
different one?


If it does fit in the same module, then that can be enough. It is 
for me. I'd stop there. But some people want to go one step 
further and ensure that `ObjDerived` can't access the internals 
of `Obj`. So in that case, you can put them in two separate 
modules and make a `package.d` file to act as the common module 
name for both. I think there are good reasons to do that, but 
most of the time it's just a matter of preference.





Re: Compile time vs run time -- what is the difference?

2022-12-27 Thread Mike Parker via Digitalmars-d-learn
On Wednesday, 28 December 2022 at 02:31:45 UTC, thebluepandabear 
wrote:





In Java and some other languages, during compile time the code 
gets executed into Java bytecode. This also happens for C#. I 
don't know if there is an equivalent 'intermediate' language 
for D that your code gets translated to.


With statically compiled languages like D, C, and C++, the 
compiler ultimately translates your source code to what's 
referred to as "machine code". Compilers output object files, 
which are in turn linked into an executable file by a linker.


Static compilers can use intermediate representations like Java 
bytecode. For example, compilation could consist of two steps 
handled by two different programs, one that translates the source 
to bytecode, and one that translates the bytecode to an object 
file.


This is how LLVM-based compilers like Clang and LDC work. Clang 
translates C source to LLVM IR (Intermediate Representation). LDC 
translated C source to LLVM IR. Both pass the generated IR to the 
LLVM compiler, which outputs the object files that are then given 
to a linker. Static Java compilers do the same thing with Java 
bytecode. Java JIT compilers built into Java VMs translate Java 
bytecode to machine code while the program is running.


So compilation is just the act of translating from one source 
format to another (e.g., raw source code to machine code, or raw 
source code to bytecode, or bytecode to machine code).




In general, I have a very vague understanding of these 
concept.s I don't understand the basics of how compile time and 
run time works in D language, it wasn't really explained in the 
book so when I see terms like 'compile time' and 'run time' I 
only have a very vague idea of what these things mean and how 
the process works for D language when compared to other high 
level languages.




Anything that happens at compile time means it happens while the 
compiler is translating the source. Anything that happens at run 
time happens while the compiled program is running.


So take this example:

```d
uint fourcc(char a, char b, char c, char d)
{
return (a << 0) | (b << 8) | (c << 16) | (d << 24);
}

// Here, fourcc is evaluated at compile time
enum nv12 = fourcc('N', 'V', '1', '2');

void main()
{
writeln(nv12);

// Here, fourcc is evaluated at runtime
writeln(fourcc('Y', 'V', '1', '2'));
}
```

When the compiler is processing this source code, it encounters 
the declaration of `nv12`. Since this is an `enum`, it's a 
compile-time constant that cannot be changed at run time.  That 
means that any value used to initialize it must also be known at 
compile time. One way to do that would be to use a literal, but 
in this case it's initialized with a call to the `fourcc` 
function. So the compiler evaluates the fourcc function and uses 
the result as the initializer of `nv12`.


In other words, the end result is just the same as if I had 
written `enum nv12 = 842094158`.


The second call to `fourcc` in the main function is not in a 
compile-time context, so it does not happen at compile time. It 
happens at run time, i.e., when you double click the executable 
that the compiler and linker generated (or type its name on the 
command line).


The general rule is: if a function call is in a context such that 
it *must* be evaluated at compile time, then the compiler will 
evaluate it. Otherwise, it's a normal run-time evaluation.






Re: Is there such concept of a list in D?

2022-12-19 Thread Mike Parker via Digitalmars-d-learn
On Monday, 19 December 2022 at 22:22:11 UTC, thebluepandabear 
wrote:


No worries, hopefully a mod will explain why. I don't like when 
posts get removed for no reason :|


I received a report of a possible troll in the forums. Looking at 
the posts collectively, I agreed, so deleted all of them. 
Whenever we delete a post, we delete subsequent posts that quote 
them as well.


Please take any further discussion on moderation policies to a 
new thread in the General forum and let's take this thread back 
on topic. Thanks!


Re: Is defining get/set methods for every field overkill?

2022-11-23 Thread Mike Parker via Digitalmars-d-learn

On Thursday, 24 November 2022 at 03:49:16 UTC, []() {}() wrote:



I broke a forum rule by critically analysing your blog?

Wow.


Criticize my blog posts all you want. Just stop please stop 
derailing threads. I'm going to delete further off topic posts in 
this thread.


Re: Is defining get/set methods for every field overkill?

2022-11-23 Thread Mike Parker via Digitalmars-d-learn
On Wednesday, 23 November 2022 at 23:35:59 UTC, thebluepandabear 
wrote:




Please stop, we get it... I'm not a moderator so I cannot 
enforce rules but there is NO need to continue this debate 
here. This software 'religiousness' is too much.


I am a moderator and I can enforce the rules. So yes, let's 
please drop this tired old debate about private and get back on 
topic. Or just let the thread die. Thanks.


Re: Actual lifetime of static array slices?

2022-11-14 Thread Mike Parker via Digitalmars-d-learn

On Tuesday, 15 November 2022 at 02:49:55 UTC, Mike Parker wrote:

It's not the scope that matters here. It's the stack. Memory 
allocated in the inner scope uses the function stack, so it's 
all valid until the function exits.


And that was just so, so wrong. Of course destructors get called 
when scopes exit, etc.


Re: Actual lifetime of static array slices?

2022-11-14 Thread Mike Parker via Digitalmars-d-learn

On Tuesday, 15 November 2022 at 02:26:41 UTC, Elfstone wrote:
I failed to find any documentation, except dynamic array slices 
will be taken care of by GC, but I assume it's not the case 
with static arrays.


A slice is a view on the existing memory owned by the original 
array. No allocations are made for the slice. The GC will track 
all references to the memory allocated for a dynamic array, so as 
long as any slices remain alive, so will the original memory.


Static arrays are allocated on the stack and become invalid when 
they leave a function scope. In turn, so would any slices or 
other pointers that reference that stack memory.




But the code bellow doesn't behave as I expected.

int[] foo()
{
int[1024] static_array;
	// return static_array[]; // Error: returning 
`static_array[]` escapes a reference to local variable 
`static_array`

return null;
}

class A
{
this(int[] inData)
{
data = inData;
}

int[] data;
}

void main()
{
int[] arr;
A a;
{
int[1024] static_array;
arr = aSlice; // OK
a = new A(aSlice); // OK
arr = foo();
//arr = foo();

}
}

By assigning aSlice to arr or a, it seemingly escapes the 
scope, I thought there'd be errors, but the code compiles just 
fine.


Is it really safe though?


It's not the scope that matters here. It's the stack. Memory 
allocated in the inner scope uses the function stack, so it's all 
valid until the function exits.





Re: Using glibc headers with ImportC

2022-11-13 Thread Mike Parker via Digitalmars-d-learn

On Sunday, 13 November 2022 at 09:15:39 UTC, qua wrote:

I agree it was unexpected that it didn't, at least for 
newcomers.


Almost everyone is a newcomer when it comes to ImportC.


Re: ImportC linking issue

2022-11-12 Thread Mike Parker via Digitalmars-d-learn

On Saturday, 12 November 2022 at 10:02:12 UTC, confuzzled wrote:
On Saturday, 12 November 2022 at 08:43:13 UTC, Mike Parker 
wrote:
On Saturday, 12 November 2022 at 02:45:52 UTC, confuzzled 
wrote:


The linker doesn't care if the libraries are C or D, and the 
compiler is only involved in that you can pass flags to the 
linker via the compiler command line.




Mike, first of all, thanks for the in depth response. That all 
makes sense. The issue I'm having is this: having made sure the 
two dependencies are available and building the 
libxlsxio_reader.a from the source without errors, why would I 
need to hunt down all the dependencies from that library to 
include them in my program?


I figured that importing the header and passing 
libxlsxio_read.a on the command line would be enough? Why would 
I have to search for libcrypto, libminizip, libexpat, and more 
that I haven't even figured out what library they are? I 
thought those dependencies would already be linked into 
libxlsxio_read.a which is a statically linked library.




Static library dependencies are resolved at link time. Anything 
they need to link with, your binary must link with. It's shared 
libraries that have their static dependencies all baked in.




Re: ImportC linking issue

2022-11-12 Thread Mike Parker via Digitalmars-d-learn

On Saturday, 12 November 2022 at 02:45:52 UTC, confuzzled wrote:



It seems that every time I resolve one of these undefined 
symbols issues, the compiler finds more. So I keep copying lib 
files from locations that are a path, to my working directory 
and linking them to my script. Is that the norm? Do I need to 
configure DMD somehow to recognize C libraries that are already 
in the path?




The linker doesn't care if the libraries are C or D, and the 
compiler is only involved in that you can pass flags to the 
linker via the compiler command line.


These two things need to be true:

* any link-time dependencies (object files, static libraries, 
shared libraries (link libraries on Windows)) need to be passed 
to the linker
* the linker needs to know where to find libraries not on the 
default search path


The only thing the compiler passes along automatically are the 
object files generated from the source and the standard library 
it's building a binary. Anything else (including separately 
compiled object files), you have to pass along explicitly.


If you aren't explicitly passing any libraries along, then the 
linker won't know anything about them. The compiler doesn't know 
about them either, so can't pass them along for you.


If you are passing them along but they aren't on the default lib 
path, then the linker won't be able to find them.


Based on your description, it sounds like the last case is true 
for you. If so, if your libraries are in a common location, you 
can pass that path to the linker through dmd via 
`-L`. E.g., on Linux, `-L-L/path/to/libs`. 
On Windows, it depends on which linker you're using. For the 
Microsoft linker, it's `-L/LIBPATH path\\to\\libs`.


You can also just pass the full path to each library.


Re: dmd as a library

2022-11-07 Thread Mike Parker via Digitalmars-d-learn

On Tuesday, 8 November 2022 at 06:21:11 UTC, vushu wrote:



So I do feel, that I am in need for some learning materials or 
guidance.


You might find Lucian Danescu's DConf '22 presentation helpful:

https://youtu.be/JYkb3PjIn4c



Re: What's the correct way of creating an instance of class in D?

2022-11-03 Thread Mike Parker via Digitalmars-d-learn

On Thursday, 3 November 2022 at 06:02:13 UTC, Mike Parker wrote:


are in C++. D enforces the distinction that C++



...that C++ programmers often follow by convention.


Re: What's the correct way of creating an instance of class in D?

2022-11-03 Thread Mike Parker via Digitalmars-d-learn
On Thursday, 3 November 2022 at 05:41:06 UTC, Siarhei Siamashka 
wrote:


Thanks for the link and also thanks for confirming that you 
have no clue what's going on. I think that what actually


That's not necessary. He does know what's going on and pointed 
you to the correct place. The second paragraph on the page says:



Class objects are instantiated by reference only.


Then further down the page:

https://dlang.org/spec/class.html#class-instantiation


Instances of class objects are created with a NewExpression:




happens is that the D code

```D
  A a2;
  a2.foo();
```

is roughly equivalent to C++

```C++
  A *a2 = NULL;
  a2->foo();
```



That's correct. Classes in D are like Java classes. `a2` is a 
reference. Structs, on the other hand, are value types as they 
are in C++. D enforces the distinction that C++



I see two problems here. First, the D language documentation is 
incomplete and does not cover this particular syntax. And


I think that it does. But given that you missed it, then it could 
potentially be improved. Perhaps a new entry in the instantiation 
section that makes clear a declaration without an initialization 
is default initialized to null.


The documentation is maintained by the community. You can post 
about issues you find here in the forums, or better, report them 
at issues.dlang.org (we're moving our bug tracking to GitHub 
soon).


second, D language is designed (intentionally or accidentally) 
to be hostile to the C++ developers trying to learn it. This 
particular issue is known as 
https://en.wikipedia.org/wiki/False_friend


 D is not C++. Nor is it Java, nor C, nor C#, nor Python, etc. 
There are similarities and differences. Any time you try out a 
language, you will view it through the lens of the language(s) 
you know, and you are going to encounter problems like this. I 
wouldn't call that hostility, intentional or accidental.


But when you do encounter those differences in D, people here are 
willing to help you, so all you have to do is ask.


Re: Importing modules under DUB on Windows

2022-10-27 Thread Mike Parker via Digitalmars-d-learn

On Thursday, 27 October 2022 at 16:40:20 UTC, DLearner wrote:



I'm not getting on with DUB.
Maybe fewer people use it under Windows, so Windows constructs 
don't get exercised so much.


Is there a non-DUB way of arranging that
`import arsd.terminal;`
will use that module as held on GitHub?
(DUB name: "arsd-official:terminal": "~>10.9.4").

OS: Windows 10. Compiler: DMD.



This has nothing to do with Windows. The source path error you 
encountered is an assertion failure that tells you what's wrong: 
dub does not allow you to add absolute paths to the source path. 
I don't know why. If you disagree, then you can file an issue in 
the dub github repository.


In the meantime, you'll need to work around the limitation. You 
could


1. Add the file to your source tree
2. Use a relative path in `sourcePaths`
2. Add arsd-official as a dub dependency

All of these would solve the problem. If you aren't going to do 
any of these things, then you'll need a fourth option.


The compiler (not dub) needs to know where to find imports, and 
the linker needs an object file to resolve symbols. So you should:


1. Compile /arsd/terminal.d as a static library with ldc (named 
e.g., "arsd-terminal.lib") and output the library to the path 
where you want it (e.g., C:\libs)
2. Add the parent directory of the arsd folder to your 
`importPaths` in dub.
3. Add linker flags to your dub project to tell the compiler 
where to find the library


You have two options for #3. If this is the only external libs 
you're working with, then you can just add the full path to the 
library in an `libs` entry:


```json
"libs": ["C:\\libs\\arsd-terminal"]
```

Note that you do not add the ".lib" extension here. Dub will do 
that for you.


If you have multiple external libs, then it's better to add the 
library path like so:


```json
"lflags": ["/LIBPATH:C:\\libs"],
"libs": ["lib1", "lib2", "lib3"]
```

Note that `/LIBPATH` is specific to the Microsoft linker, which I 
assume LDC uses on Windows:


https://learn.microsoft.com/en-us/cpp/build/reference/libpath-additional-libpath?view=msvc-170

If it's using the LLVM linker, then you'll need the appropriate 
flag for that.


If you aren't planning to build on other platforms, then you'll 
want to make these dub directives platform specific, e.g., 
`libs-windows` rather than `libs`.




Re: dub ldc2 static linking

2022-10-27 Thread Mike Parker via Digitalmars-d-learn

On Friday, 28 October 2022 at 01:37:50 UTC, Mike Parker wrote:



This has nothing to do with dub and is not a D issue 
specifically. Enter your error message in Google and you'll get 
a long list of results. Maybe one of them can help you.


Or do what kinke suggests :-)


Re: dub ldc2 static linking

2022-10-27 Thread Mike Parker via Digitalmars-d-learn

On Thursday, 27 October 2022 at 08:08:38 UTC, Yura wrote:



curl.d:(.text._D3std3net4curl7CurlAPI7loadAPIFZPv+0xd): 
warning: Using 'dlopen' in statically linked applications 
requires at runtime the shared libraries from the glibc version 
used for linking


and many other warnings like this.

What am I doing wrong? Any way to fix it?


This has nothing to do with dub and is not a D issue 
specifically. Enter your error message in Google and you'll get a 
long list of results. Maybe one of them can help you.


Re: Can someone tell me what the compiler thought I was trying to do?

2022-10-18 Thread Mike Parker via Digitalmars-d-learn

On Wednesday, 19 October 2022 at 03:10:29 UTC, Mike Parker wrote:



It's right there in the summary of the Final Review of the DIP 
that I linked above:


https://github.com/dlang/DIPs/blob/master/DIPs/accepted/DIP1038.md#final-review


I meant to say the summary of the formal assessment. One of the 
conditions of acceptance was this one:


develop rules for handling covariance and contravariance when 
applied to functions.


Paul opted instead to do just have it apply to types for now. A 
future enhancement can take on extending it to functions. As he 
noted above, that's the approach Rust took as well.


Re: Can someone tell me what the compiler thought I was trying to do?

2022-10-18 Thread Mike Parker via Digitalmars-d-learn

On Wednesday, 19 October 2022 at 01:34:54 UTC, mw wrote:

On Wednesday, 19 October 2022 at 01:30:23 UTC, H. S. Teoh wrote:

On Wed, Oct 19, 2022 at 01:15:37AM +, Adam D Ruppe via


it only applies to types, not to functions.


Wat... so what's the use of it then?  So it's not possible to 
mark the return value of an int function @mustUse without 
making, in theory, *all* ints @mustUse?


I must confess I'm baffled as to the purpose of this strange 
design.




Same, can't believe it.

Is there any (design) doc about this?


It's right there in the summary of the Final Review of the DIP 
that I linked above:


https://github.com/dlang/DIPs/blob/master/DIPs/accepted/DIP1038.md#final-review


Re: How do I correctly install packages for use with Visual Studio?

2022-10-16 Thread Mike Parker via Digitalmars-d-learn

On Sunday, 16 October 2022 at 11:09:31 UTC, Decabytes wrote:



 I'm confused at what/where exactly D expect files to be for 
them to considered "installed".


D doesn't expect them to be anywhere. By default, the compiler 
will search relative to the current working directory, on any 
paths configured in dmd's config file, and on any paths you (or 
your IDE) give it via `-I` on the command line.


I strongly recommend against keeping libraries in the dmd source 
directory. You'll have to copy them over again on every new 
compiler install.


If Visual D doesn't yet support dub (I've not used it in a long 
while, so I don't know), then it's probably best to set up a 
common directory somewhere on your system. Just make sure not to 
put the package directory (e.g., in src/raylib, raylib is the 
package directory) on the import path, but the root source 
directory.


You'll probably want to keep any compiled library binaries on a 
common path, too, so that you can configure that in the IDE 
settings.


Re: How do I correctly install packages for use with Visual Studio?

2022-10-16 Thread Mike Parker via Digitalmars-d-learn

On Sunday, 16 October 2022 at 11:09:31 UTC, Decabytes wrote:


Building x64\Debug\chip8.exe...
chip8.d(4): Error: unable to read module `raylib`
chip8.d(4):Expected 'raylib.d' or 'raylib\package.d' in 
one of the following import paths:

import path[0] = C:\D\dmd2\windows\bin\..\..\src\phobos
import path[1] = C:\D\dmd2\windows\bin\..\..\src\druntime\import
import path[2] = C:\D\dmd2\windows\bin\..\..\src\gtkd
import path[3] = C:\D\dmd2\windows\bin\..\..\src\raylib
```
But I do have a package.d located in  
C:\D\dmd2\src\raylib\package.d. Does anyone know what I did 
wrong?


Your import paths are wrong. This, for example:


import path[3] = C:\D\dmd2\windows\bin\..\..\src\raylib


The path should be

C:\D\dmd2\windows\bin\..\..\src\

Ditto for gtkd looks like.


Re: Can someone tell me what the compiler thought I was trying to do?

2022-10-14 Thread Mike Parker via Digitalmars-d-learn

On Friday, 14 October 2022 at 22:17:52 UTC, H. S. Teoh wrote:

Given that this particular trap crops up regularly, perhaps 
some sort of warning ought to be added. Once the @nodiscard DIP 
is accepted & implemented this should be easy to do.




Seems like you're behind the times! The DIP was accepted and 
implemented with some changes:


https://github.com/dlang/DIPs/blob/master/DIPs/accepted/DIP1038.md#final-review

The summary in full:

---
The language maintainers accepted this DIP with a request for 
changes:


* rename `@noDiscard`, as they want to avoid adding additional 
negative attributes to the language.
* address issues that arise from the feature's interaction with 
inheritance when applied to classes.
* develop rules for handling covariance and contravariance when 
applied to functions.


The DIP author addressed these requests by renaming the attribute 
to @mustuse and allowing it only on structs and unions. His 
rationale for the latter is described in the section, Design 
Goals and Possible Alternatives.


The maintainers approved the author's changes and accepted the 
revised version of the DIP.

---


Re: Can someone tell me what the compiler thought I was trying to do?

2022-10-14 Thread Mike Parker via Digitalmars-d-learn

On Friday, 14 October 2022 at 21:51:54 UTC, WhatMeWorry wrote:


I lost about a half an hour troubleshooting some code of mine 
which as it turned out to be resolved with just one line.



// paths.remove(i);   // compiles fine but does nothing

paths = paths.remove(i);  // works - what I erroneously thought 
the previous line was doing


Is the first line nonsensical and should the compiler have at 
least issued a warning?


At the moment, no. You should have read the documentation of the 
function :-)


Note that remove does not change the length of the original 
range directly; instead, it returns the shortened range. If its 
return value is not assigned to the original range, the 
original range will retain its original length, though its 
contents will have changed:


You ignored the return value of a function you shouldn't have 
ignored. It's not practical for the compiler to warn every time 
you do that, as it currently can't know that you're *supposed* to 
use it.


`@mustuse` was added to the language in 2.100.0 as an attribute 
for `struct` or `union`, but not yet for functions, as explained 
in the DIP:


https://github.com/dlang/DIPs/blob/master/DIPs/accepted/DIP1038.md#mustuse-as-a-function-attribute

If that ever gets expanded for use as a function attribute, then 
it can be used in situations like this so that you must use the 
return result. Until then, read the documentation!


Re: Visual D doesn't work, now Visual Studio Code / D doesn't work!!!! ....

2022-10-02 Thread Mike Parker via Digitalmars-d-learn
On Sunday, 2 October 2022 at 11:00:06 UTC, Daniel Donnell, Jr 
wrote:

I thought I set everything up correctly, and now:

```
Exception thrown at 0x7FF7D6E2E230 in metamath-d.exe: 
0xC096: Privileged instruction.
Unable to open natvis file 
'c:\Users\fruit\.vscode\extensions\webfreak.code-d-0.23.2\dlang-debug\dlang_cpp.natvis'.

```

So what the hell do you D developers use to code with if A) 
Visual D doesn't work - it just ate my app.obj file and can't 
find it anymore no matter if I clean or re-order the executable 
paths in settings.


B) VS Code doesn't work out-of-the-box.

Every. Single. Time I get around to using D, there's always 
something that pops up and doesn't work right.  And it never 
gets fixed.   How the heck do you expect me to debug without a 
proper debugging IDE :|


Plenty of people are using Visual D and VS Code with D. Whatever 
the source of your problem, it's surely fixable. Though if no one 
has encountered this particular issue, then it may take some 
doing to figure out the problem.


I've emailed Rainer, the maintainer of Visual D, to notify him of 
this thread. He might have an idea of what's wrong, or at least 
will be in a position to ask more informed questions than I or 
others to help you solve the problem.


In the future, when you encounter Visual D issues, please post in 
the IDEs forum. Rainer checks in there more regularly and will be 
more likely to see your posts.


https://forum.dlang.org/group/ide


Re: D installer

2022-10-02 Thread Mike Parker via Digitalmars-d-learn

On Sunday, 2 October 2022 at 11:33:47 UTC, Imperatorn wrote:
I only have Visual Studio 2022. Will the installer be updated 
to support that or am I missing some components?


![Installer](https://i.ibb.co/sCZRFRf/installer.jpg)



You should be fine. Select the bottom option since you already 
have it installed.




Re: Why I get delegate when passing address of function?

2022-09-11 Thread Mike Parker via Digitalmars-d-learn

On Sunday, 11 September 2022 at 09:15:11 UTC, Mike Parker wrote:

Pointers to non-static member functions always produce a 
delegate. Otherwise, you wouldn't be able to access the class 
instance's members.


Reference:

https://dlang.org/spec/function.html#closures


Re: Why I get delegate when passing address of function?

2022-09-11 Thread Mike Parker via Digitalmars-d-learn

On Sunday, 11 September 2022 at 09:02:31 UTC, Injeckt wrote:
I have a one class and two modificators, where in "public" 
function I'm calling CreateThread with address of the 
ClientThread function which stored in same class, but in 
"private" modificator.


And i get this error:
Error: cannot pass argument `` of type 
`extern (Windows) uint delegate(void* param)` to parameter 
`extern (Windows) uint function(void*) @system`.




Pointers to non-static member functions always produce a 
delegate. Otherwise, you wouldn't be able to access the class 
instance's members.


Re: How I can pass the WndProc as a parameter?

2022-09-10 Thread Mike Parker via Digitalmars-d-learn

On Saturday, 10 September 2022 at 10:39:12 UTC, Injeckt wrote:

To elaborate on why you need the above...


But I get these bugs:


WndProc is a function, and you can't pass a function as a runtime 
function parameter, only pointers to functions. The first two 
errors tell you exactly what the problem is.


server.d(29): Error: function `server.WndProc(void* hwnd, uint 
message, uint wParam, int lParam)` is not callable using 
argument types `()`


Note the bit that says "not callable using argument types `()`". 
In D, functions that have an empty parameter list can be called 
without an argument list, i.e., `void foo()` can be called as 
`foo`, the compiler rewrites it to `foo()`.


This error by itself tells you what's wrong. The compiler knows 
`WndProc` is a function, so it's trying to call `WndProc()` when 
it sees the `WndProc` in your argument list in the function call 
to `KK.CreateWindowClass` at line 29 of server.d.



server.d(29): too few arguments, expected `4`, got `0`


And this reinforces that: the `WndProc` function takes 4 
arguments, but none were provided.


When doing Win32 programming in D, it sometimes helps to search 
online for problematic types. Microsoft's Win32 API documentation 
is really good. For functions, that's the only reference you 
need. But for other types and aliases, it sometimes helps to go 
one step further: use the MS docs to find out which header the 
type is defined in, then go the DRuntime source to find the 
corresponding binding.


In this case, searching for `WNDPROC` would turn up this page:

https://docs.microsoft.com/en-us/windows/win32/api/winuser/nc-winuser-wndproc

At the bottom of which we see that it's defined in `winuser.h`. 
So then you can go to the DRuntime sorce directory (it's 
installed with the compiler) and open `core/sys/winuser.d`, in 
which a search for `WNDPROC` eventually leads to this:


`alias LRESULT function(HWND, UINT, WPARAM, LPARAM)   WNDPROC;`

That tells you it's a function pointer, meaning your function 
call needs ``, since that's how we get function pointers 
in D.





Re: How I can pass the WndProc as a parameter?

2022-09-10 Thread Mike Parker via Digitalmars-d-learn

On Saturday, 10 September 2022 at 10:39:12 UTC, Injeckt wrote:


And after all, I call it:

KK_CreateWindowClass(WndProc);



`KK_CreateWindowClass();`


Re: How include header file?

2022-09-07 Thread Mike Parker via Digitalmars-d-learn

On Wednesday, 7 September 2022 at 20:23:03 UTC, Injeckt wrote:


Convert it to D:

	extern(C) const(char)* inet_ntop(int af, const(void)* src, 
char* dst, socklen_t size);


Win32 API functions need to be `extern(Windows)`.



You probably also need:

alias socklen_t = ...;


https://github.com/dlang/dmd/blob/master/druntime/src/core/sys/windows/winsock2.d#L17

`alias socklen_t = int`




It doesn't work. "Reference to an unresolved external symbol 
_inet_ntop".


That's a linker error. You need to link with `ws2_32.lib`.


Re: How to link a msvcr120.dll in an inverse recursive way after a Windows .exe binary deployment

2022-09-05 Thread Mike Parker via Digitalmars-d-learn

On Tuesday, 6 September 2022 at 04:36:55 UTC, ShadoLight wrote:



True. In that case just distribute the DLL (taken from the DMD 
bin folder) alongside the HelloWorld EXE so that both reside in 
the same folder on the target computer.


The proper way to do this is to ship the correct version of the 
Visual C++ redistributable installer and run it as part of the 
application install process:


https://docs.microsoft.com/en-us/cpp/windows/latest-supported-vc-redist?view=msvc-170


Re: This code completely breaks the compiler:

2022-08-18 Thread Mike Parker via Digitalmars-d-learn
On Friday, 19 August 2022 at 04:25:25 UTC, Ruby The Roobster 
wrote:


So that's why it compiled.  Still, I believe that stuff like 
this ought to be detected at compile time, as supposed to in a 
unittest or, if someone forgot to write the tests, in 
production.


If the template is never instantiated, it never makes it into the 
executable. It doesn't matter if it's in production or not, and 
has nothing to do with tests. It doesn't exist. How could the 
compiler catch any problems if it has no idea what `Mtypes` is?


This is true for any template parameter. Consider this:

```d
import std.stdio;

T derp(T)(T val) {
val += 10;
return val;
}

void main()
{
writeln("Hello D");
}
```

`derp` obviously isn't going to work with every type. But this 
code compiles because `derp` is never instantiated. The compiler 
can't check if the code in `derp` is valid because it has no idea 
what `T` might be. If it's `int`, then no problem. If it's 
`string` then no way:


```d
void main()
{
writeln(derp!string("No way"));
}
```

Now you'll get this:

```
onlineapp.d(4): Error: slice `val` is not mutable
onlineapp.d(10): Error: template instance `onlineapp.derp!string` 
error instantiating

```




Re: char* pointers between C and D

2022-07-25 Thread Mike Parker via Digitalmars-d-learn

On Monday, 25 July 2022 at 09:04:29 UTC, pascal111 wrote:
I have small C program that uses a pointer to change the start 
address of a string, and when I tried to do the same code but 
with D, the D code printed the address of the string after I 
increased it one step instead of printing the string the 
pointer pointing to. Is there a difference between "char *" 
pointers between C and D.


No, no difference. Pointers are the same in both languages. 
What's different is the behavior of `%s` in `writeln` vs 
`printf`. See the documentation on format strings at:


https://dlang.org/phobos/std_format.html

Essentially, `%s` tells the formatter to output something 
appropriate for the given type. For an actual D string, you see 
the text. For an integral or floating point type, you see the 
number. For a pointer, you see the the address. And so on.


Do in your case, to get `writefln` to print the text instead of 
the pointer address, you could import `std.string` and use 
`fromStringz`:`fromStringz(p)`.


This will give you a D string without allocating any memory. 
Basically an immutable slice of the memory pointed at by `p`. 
That's fine for this use case, but if you wanted to hang on to 
the string beyond the lifetime of the pointer, you'd have to use 
`std.conv.to` instead (e.g., `to!string(p)`).





Re: dlang bug - accessing module variable from method segfaults only when using module reference directly

2022-07-01 Thread Mike Parker via Digitalmars-d-learn

On Friday, 1 July 2022 at 13:44:20 UTC, Chris Katko wrote:

It appears module access to a class is broken until the 
constructor finishes.


No, it has nothing to do with the module. It's the reference 
itself.


Until the constructor returns, the reference through which you're 
constructing the instance is null. It doesn't matter if it's at 
module scope, function scope, or wherever. If the constructor 
fails to complete (segfault, thrown exception, assertion failure, 
etc.), then the reference remains null.


The reference is not the *instance*. It's a pointer to the 
instance. The instance is valid when the constructor is called, 
because the `this` reference has to be valid. Think of it in 
terms of a normal function call:


```D
T newT() {
T t = allocT();
t.construct(t);
return t;
}

T g = newT();
```

If `t.construct` throws or crashes, then `return t` is never 
executed, and `g` is never initialized.




Re: dlang bug - accessing module variable from method segfaults only when using module reference directly

2022-07-01 Thread Mike Parker via Digitalmars-d-learn

On Friday, 1 July 2022 at 13:20:15 UTC, Mike Parker wrote:
r.


And that also looks like the source of your original segfault. 
You've got a circular reference going on in the constructors. 
In other words, you're constructing a global world instance, 
which in turn constructs an elf instance, which in turn 
accesses the global world reference whose constructor hasn't 
yet completed, so the global world reference is still null.




Here's what it looks like in code:

```d
import std.stdio : writeln;

class Foo {
Bar b;
this() { b = new Bar; }
void sayMyName() { writeln("I am Foo."); }
}

class Bar {
this() { f.sayMyName(); }
}

Foo f;

void main()
{
f = new Foo;
}
```


Re: dlang bug - accessing module variable from method segfaults only when using module reference directly

2022-07-01 Thread Mike Parker via Digitalmars-d-learn

On Friday, 1 July 2022 at 13:01:30 UTC, Chris Katko wrote:
Forgot the last line. That's important because world MUST exist 
by time elf is called... because world... created and called 
elf.


So it's not a memory issue, but some sort of linkage issue.


world is null because the constructor didn't complete. The 
segfault happens inside its constructor.


And that also looks like the source of your original segfault. 
You've got a circular reference going on in the constructors. In 
other words, you're constructing a global world instance, which 
in turn constructs an elf instance, which in turn accesses the 
global world reference whose constructor hasn't yet completed, so 
the global world reference is still null.


If the objects world is constructing absolutely need to access 
it, then you could:


1. Initialize world with a do-nothing destructor, then call a 
`setup` method on it to do what its constructor currently is 
doing;
2. Pass `this` along to all the constructors that need it from 
inside the world constructor.


Re: Static Initialization of Structs syntax

2022-06-22 Thread Mike Parker via Digitalmars-d-learn

On Wednesday, 22 June 2022 at 11:19:59 UTC, Antonio wrote:



I see now:  DIP 1033 will solve this (i.e., using named 
arguments in struct constructor...  similar to how dart/flutter 
works)


That would be DIP 1030:

https://github.com/dlang/DIPs/blob/master/DIPs/accepted/DIP1030.md

Max Haughton was working on an implementation of it, but ran into 
trouble with template parameters, IIRC.


Re: Convering strings containing number

2022-06-14 Thread Mike Parker via Digitalmars-d-learn

On Wednesday, 15 June 2022 at 04:26:44 UTC, Salih Dincer wrote:

Hi,

I've been interested in conversion possibilities for a while.  
I tried to convert a string containing numbers but with no 
success in single digits.  The only solution I found is to 
subtract 48 from the result:


```d
import std;
void main()
{
    string str = "abc123";
    str[3..$].to!int.writeln; // 123
    auto bar = str[3].to!int;
    assert(bar == 49); // 49 is value for ASCII.
    writeln(bar - 48); // 1
}
```


By indexing `str`, you're getting a `char`. So `to` is operating 
on that rather than on a string. Slicing will give you what you 
want, since then you'd have a `"1"` rather than a `'1'`:


```d
str[3..4].to!int;
```


Re: ImportC: unresolved external symbol

2022-06-14 Thread Mike Parker via Digitalmars-d-learn

On Tuesday, 14 June 2022 at 14:32:50 UTC, ryuukk_ wrote:



```
nk.obj : error LNK2019: unresolved external symbol test 
referenced in function _Dmain

```

Am i missing something important? (that is a dub project, 
created with: dub init)


DMD: v2.100.0-dirty


This works from the command line:

```
dmd -m64 app.d nk.c
```

It's possible dub isn't passing the C file to the compiler. 
Assuming everything's configured properly (e.g., both files are 
in the same source directory, or the paths are properly set if 
they aren't), you should do a verbose build and see what the 
compiler command line looks like.


Re: Can I create a package with friendly modules

2022-06-12 Thread Mike Parker via Digitalmars-d-learn

On Sunday, 12 June 2022 at 23:29:29 UTC, forkit wrote:



I don't get it.

How does this enable one module to access the private parts of 
another module?


It doesn't. But what you were describing in your post is 
package-level access. By keeping it the cross-module access in a 
subpackage, package is "private" to that subpackage.




Isn't 'private' *always* private to the module?


Yes, which is why it doesn't allow cross-module access.



The idea I had, was to be able to spread a 'module' over more 
than one file - for the purpose of encapsulating this and that 
in different physical files, while *still* protecting the 
'private is private to the module' concept.


You can't spread modules across multiple files.



But if D has a one-to-one mapping between a module and a file, 
and if private is always private to the one module, then this 
could never work.


Not with private. But what I described is the same effect.



Re: Can I create a package with friendly modules

2022-06-11 Thread Mike Parker via Digitalmars-d-learn

On Sunday, 12 June 2022 at 05:05:46 UTC, forkit wrote:
Is it possible to create a package.d, consisting of (for 
example), two modules, where each module can access private 
declarations within each other.


In essence, declaring 'a module level friendship', or a kind of 
'extended module' if you want.


I might still want to add another module to the package, that 
is NOT part of that friendship between those other two modules, 
but is otherwise related to the solution.


- packagename
-- package.d
-- futuremodule.d
--- subpackagename
 friend1.d
 friend2.d

```
// friend1.d
module packagename.subpackagename.friend1;

package void doSomethingFriendly();

///
// friend2.d
module packagename.subpackagename.friend2;

import packagename.subpackagename.friend1;

void doSomething() { doSomethingFriendly(); }

///
// package.d
module packagename;

public import
packagename.subpackagename.friend1,
packagename.subpackagename.friend2,
packagename.futuremodule;
```


Re: Why allow initializers of non-static members that allocate?

2022-06-11 Thread Mike Parker via Digitalmars-d-learn

On Saturday, 11 June 2022 at 10:37:30 UTC, Bastiaan Veelo wrote:



So that’s why I used “why” in the title of this thread, which I 
haven’t seen an answer to yet. What is the practical case where 
that warning would be annoying? When would you actually want 
this behaviour?


After actually stopping to think about it (my earlier responses 
were reflexive), I agree with your initial assessment that it 
should be an error. It really only makes sense to allow the 
dynamic allocation if the fields are immutable and, in the case 
of arrays, the initializer is a literal.


Re: Why allow initializers of non-static members that allocate?

2022-06-10 Thread Mike Parker via Digitalmars-d-learn

On Saturday, 11 June 2022 at 01:14:06 UTC, matheus wrote:

So, in the case of "int[] arr = new int[](5)", an array of 
length 5 of type int will be instantiated and its address will 
be shared among whoever instantiates "S" and be pointed and 
accessed through arr.


In the second case, "int[2] arr2", 2 consecutive integer spaces 
in memory will be allocate independently for each 
"instantiation" of "S", so different address.


I never saw this before (I mean I never wrote the first case), 
I'm used to the "int[2] arr2;" way of declaring it, but if I 
had looked this code without knowing this, I'd be certain that 
s1.arr and s2.arr would have different addresses.


That's because static arrays are allocated as part of the 
instance:


```d
struct Foo {
int[] dyn;
}

struct Bar {
int[10] stat;
}

assert(Foo.sizeof == 16);
assert(Bar.sizeof == 40);
```



This is a bit weird (At least for a newbie like me), I really 
think the compiler should emit an warning about this.




At it's core this is just a matter of knowing how two specific 
language features behave (allocation of static vs. dynamic arrays 
coupled with member field initialization). If you aren't aware of 
it and it bites you, then you learn about it and you know it. So 
would you then really want a warning every time you initialize a 
static array field?


People getting bit by `new` in field initialization often enough 
that I think a warning would be helpful. But any such warnings 
need to be enabled by default to be useful, and must have an off 
switch for people who don't need them. So the question in each 
case would be, where's the line between helpful and annoying?


The compiler should be as helpful as it can, but it has to be 
helpful without getting in the way. There's a significant amount 
of learning by trial and error in any programming language. So I 
think there has to be a distinction between things like "easy to 
do by accident even when you know the deal"  and "once you learn 
it, you're unlikely to do it again".


Re: Why allow initializers of non-static members that allocate?

2022-06-10 Thread Mike Parker via Digitalmars-d-learn
On Friday, 10 June 2022 at 14:56:24 UTC, Steven Schveighoffer 
wrote:


Discovered circa 2009: 
https://issues.dlang.org/show_bug.cgi?id=2947


It should be illegal to declare a field this way that has 
mutable references without being `shared`. End of story.


-Steve


The docs do say that:

The default initializers may not contain references to mutable 
data.


Re: Why allow initializers of non-static members that allocate?

2022-06-10 Thread Mike Parker via Digitalmars-d-learn

On Friday, 10 June 2022 at 07:46:36 UTC, Mike Parker wrote:



I think this is a case where having a warning that's on by 
default, and which can be explicitly disabled, is useful. "Blah 
blah .init blah blah. See link-to-something-in-docs. Is this 
what you intended?"


And it *is* documented:

Struct fields are by default initialized to whatever the 
Initializer for the field is, and if none is supplied, to the 
default initializer for the field's type.

The default initializers are evaluated at compile time.


https://dlang.org/spec/struct.html#default_struct_init


Re: Why allow initializers of non-static members that allocate?

2022-06-10 Thread Mike Parker via Digitalmars-d-learn

On Friday, 10 June 2022 at 07:35:17 UTC, Bastiaan Veelo wrote:

Is there a use case where this makes sense? I would have much 
appreciated the compiler slapping me on the fingers, but it 
doesn't. I understand that it is safe and that the compiler can 
allow this, but why would anyone want that? D-scanner does not 
check for this either.


Any initialization of a member field is overriding the field's 
`.init` value for the type. If a dynamic allocation set a 
different value per instance, then you'd have inconsistent 
behavior with, e.g., `int a = 5`.





I think a helpful error message would be: "Error: The 
initializer `A(5)` allocates memory that is shared among all 
instances of `S`. If you want that, make `S.a` `static`."


I understand that it's not something that people expect, but 
making it an error can't be the answer. And making it a static 
field is not the same thing.


I think this is a case where having a warning that's on by 
default, and which can be explicitly disabled, is useful. "Blah 
blah .init blah blah. See link-to-something-in-docs. Is this what 
you intended?"


Re: C-like static array size inference - how?

2022-06-07 Thread Mike Parker via Digitalmars-d-learn

On Wednesday, 8 June 2022 at 00:43:24 UTC, Ali Çehreli wrote:



Do I remember correctly that there were syntax proposals that 
used $ or _?


  int[$] arr = [ 1, 2 ];
  int[_] arr = [ 1, 2 ];

But I can't find past discussions about that.


https://github.com/dlang/DIPs/blob/master/DIPs/other/DIP1039.md

Links to the discussion and feedback threads are in the review 
summary. The author withdrew the DIP, so anyone who would like to 
pick it up again is free to do so.


Re: dlang compilers & licenses.

2022-06-04 Thread Mike Parker via Digitalmars-d-learn

On Saturday, 4 June 2022 at 14:13:08 UTC, Alain De Vos wrote:

Do DMD , GDC , LDC have the same or different licenses in use ?


DMD
https://github.com/dlang/dmd/blob/master/LICENSE.txt

LDC
https://github.com/ldc-developers/ldc/blob/master/LICENSE

GDC
https://github.com/D-Programming-GDC/gcc/blob/ci/mainline/COPYING3
https://github.com/D-Programming-GDC/gcc/blob/ci/mainline/COPYING.RUNTIME


Re: Dynamic Arrays Capacity

2022-06-02 Thread Mike Parker via Digitalmars-d-learn

On Thursday, 2 June 2022 at 08:24:51 UTC, Mike Parker wrote:


And so, `[0]` is the same as `&(*ts.ptr + 0)`, or simply 
`ts.ptr`.


That should be the same as `&(*(ts.ptr + 0))`!


Re: Dynamic Arrays Capacity

2022-06-02 Thread Mike Parker via Digitalmars-d-learn

On Thursday, 2 June 2022 at 08:14:40 UTC, Mike Parker wrote:

More specifically, it points to the starting address of the 
allocated block of memory.


I posted too soon.

Given an instance `ts` of type `T[]`, array accesses essentially 
are this:

```d
ts[0] == *(ts.ptr + 0);
ts[1] == *(ts.ptr + 1);
ts[2] == *(ts.ptr + 2);
```

Since the size of `T` is known, each addition to the pointer adds 
`N * T.sizeof` bytes. If you converted it to a `ubyte` array, 
you'd need to handle that yourself.


And so, `[0]` is the same as `&(*ts.ptr + 0)`, or simply 
`ts.ptr`.


Re: Dynamic Arrays Capacity

2022-06-02 Thread Mike Parker via Digitalmars-d-learn

On Thursday, 2 June 2022 at 05:04:03 UTC, Salih Dincer wrote:

Hi,

Do I misunderstand? A dynamic array is allocated memory 
according to the `nextpow2()` algorithm(-1 lapse); strings, on 
the other hand, don't behave like this...


```d
  string str = "0123456789ABCDEF";
  char[] chr = str.dup;

  assert(str.length == 16);
  assert(str.capacity == 0);

  import std.math: thus = nextPow2; //.algebraic

  assert(chr.capacity == thus(str.length) - 1);
  assert(chr.capacity == 31);


You've initialized `str` with a string literal. No memory is 
allocated for these from the GC. They're stored in the binary, 
meaning they're loaded into memory from disk by the OS. So 
`str.ptr` points to a static memory location that's a fixed size, 
hence no extra capacity.


`chr` is allocated from the GC using whatever algorithm is 
implemented in the runtime. That it happens to be any given 
algorithm is an implementation detail that could change in any 
release.



```

Also, `.ptr` keeps the address of the most recent first 
element, right?




More specifically, it points to the starting address of the 
allocated block of memory.


Re: Odd construct idea. Splitting arguments inside a parameter list.

2022-05-23 Thread Mike Parker via Digitalmars-d-learn

On Monday, 23 May 2022 at 08:34:21 UTC, Chris Katko wrote:

D


I'm curious if you can pass a struct of values (a 'tuple'?) 
with the right subfields, as if those fields occupied a 
function signature. (As I write this and try to explain it, it 
probably sounds impossible.)


Right now you can use `.tupleof`:

```d
myFunction(taco, p.tupleof, burrito);
```



Re: template? mixin? template mixins? for modifying a struct setup

2022-05-20 Thread Mike Parker via Digitalmars-d-learn

On Friday, 20 May 2022 at 14:54:31 UTC, Christopher Katko wrote:


So wait, that means if I have a module with extra stuff like

D
colors.d

auto red =
// grey


and then in my other file
D
auto white = grey(1.0);


It won't use CTFE? Why is there a local module requirement?


I'm not sure what you mean by "local module requirement". The 
static storage class means that a variable will be around for the 
lifetime of the program (or more specifically in D's case, the 
lifetime of the thread). Module-scope variables are static by 
default.


Re: UI Library

2022-05-20 Thread Mike Parker via Digitalmars-d-learn

On Friday, 20 May 2022 at 07:05:21 UTC, Tejas wrote:


Maybe gtkd?
https://code.dlang.org/packages/gtk-d


And some corresponding tutorials:

https://gtkdcoding.com/


Re: template? mixin? template mixins? for modifying a struct setup

2022-05-19 Thread Mike Parker via Digitalmars-d-learn

On Friday, 20 May 2022 at 00:12:44 UTC, Chris Katko wrote:

Yeah that occurred to me as I was falling asleep. Though, do I 
have to a specify


```D
static auto myColor = grey(0.5);
```
to ensure it's done at compile time? It's not the end of the 
world, but ideally, these are static / hardcoded values that 
can be used thousands of times a second.


If the declarations are at module scope, `static` has no effect, 
and CTFE will be used for initialization.


Re: Question on shapes

2022-05-17 Thread Mike Parker via Digitalmars-d-learn

On Tuesday, 17 May 2022 at 05:08:30 UTC, matheus wrote:



In D there would be a better way to do such thing?



Nothing really specific to D, but for one or two properties, you 
might just add them as function parameters with default values:


```d
void draw(float scale = 1.0f);
```

If you have a number of them (scale, color, blend state, etc.), 
then you might add them as members of the `Shape` class. You 
could then expand on that with a single draw function in the 
`Shape` class that handles the actual drawing, and the subclasses 
would then call that internally after, e.g., setting up any 
vertex buffers or whatever specific to the shapes.


```d
class Shape {
   private:
  float scale;
  RGBA color;
  DrawBuffer buffer; // some API-specific vertex buffer or 
whatever


   protected:
  void drawImpl() { // get the shape on screen }

   public:
  abstract void draw();
}

class Circle {
   override void draw() {
  // set up buffer
  ...
  drawImpl();
}
```

Or you could have a `DrawProperties` struct independent of the 
`Shape` hierarchy that you can fill out and pass to every draw 
call. Or set global properties in the renderer and draw objects 
that have the same properties all at once.


There are several ways to go about it.


Re: Why are structs and classes so different?

2022-05-15 Thread Mike Parker via Digitalmars-d-learn

On Sunday, 15 May 2022 at 20:05:05 UTC, Kevin Bailey wrote:



One question is, how should we pass objects - by value or by 
reference? In C++, you can do either, of course, but you take 
your chances if you pass by value - both in safety AND 
PERFORMANCE. The bottom line is that no one passes by value, 
even for PODs (although we may return even large objects.)


Pass struct instances by ref or by value as needed, just as you 
do in C++.


For classes, you never have direct access to the instance. Your 
class reference is a handle (a pointer) that is always passed by 
value.




But I asked a different question: Why can't I put a class 
object on the stack? What's the danger?


I answered that one. You can put a class on the stack with 
`scope`. There is no danger in that.


If you're wanting direct access to the class instance, like you 
would have with a struct, you don't have that in D. Classes are 
modeled on Java, not C++.




Note that operating on that object hasn't changed. If I pass by 
reference, it's no different than if I had created a reference.


Again, you never have direct access to the object instance. You 
always access it through the handle.




One might say, Well, if D creates by value, then it has to pass 
by value. But it doesn't; it has the 'ref' keyword.


Everything is passed by value unless the `ref` keyword is present.



One might want to avoid passing by value accidentally. Ok, one 
could have D pass class objects by reference implicitly.


How do you pass by value accidentally? By forgetting the `ref` 
keyword?




I don't like things silently changing like that, so one might 
have D forbid all but pass by 'ref' or pointer for class 
objects.


I don't understand where you're coming from here. How can things 
silently change?




I hope Ali's answer isn't the real reason. I would be sad if D 
risked seg faults just to make class behavior "consistent".




Where is the risk of seg faults? Are you referring to the fact 
that class references are default initialized to null?





Re: Why are structs and classes so different?

2022-05-15 Thread Mike Parker via Digitalmars-d-learn

On Sunday, 15 May 2022 at 15:26:40 UTC, Kevin Bailey wrote:

I'm trying to understand why it is this way. I assume that 
there's some benefit for designing it this way. I'm hoping that 
it's not simply accidental, historical or easier for the 
compiler writer.


There's a problem that arises with pass-by-value subclasses 
called "object slicing". Effectively, it's possible to "slice 
off" members of superclasses. It's one of many pitfalls to be 
avoided in C++. There you typically find the convention of 
structs being used as POD (Plain Old Data) types (i.e., no 
inheritance) and classes when you want inheritance, in which case 
they are passed around to functions as references.


For reference:
https://stackoverflow.com/questions/274626/what-is-object-slicing

D basically bakes the C++ convention into the language, with a 
class system inspired by Java.




One problem that this causes is that I have to remember 
different rules when using them. This creates the additional 
load of learning and remembering which types are which from 
someone else's library.


Of all the complexity we need to remember as programmers, this is 
fairly low on the totem pole. Simple rule: if you need (or want) 
inheritance, use classes. If not, use structs.





A bigger problem is that, if I have a struct that I suddenly 
want to inherit from, I have to change all my code.


You should generally know up front if you need inheritance or 
not. In cases where you change your mind, you'll likely find that 
you have very little code to change. Variable declarations, sure. 
And if you were passing struct instances to functions, you'd want 
to change the function signatures, but that should be the lion's 
share of what you'd need to change. After all, D doesn't use the 
`->` syntax for struct pointers, so any members you access would 
be via the dot operator.


In addition to that work, in both of these cases, one could 
easily do it wrong:


// Fine with a struct, fatal with a class.
Foo foo;

At least in C++, the compiler would complain. In D, not even a 
warning.


You generally find out about that pretty quickly in development, 
though. That's a good reason to get into the habit of 
implementing and running unit tests, so if you do make changes 
and overlook something like this, then your tests will catch it 
if normal operation of the program doesn't.




Why is it this way? What is the harm of putting a class object 
on the stack?


I've answered the "why" above. As to the the second question, 
there's no harm in putting a class on the stack:


```d
import std.stdio;

class Clazz {
~this() { writeln("Bu-bye"); }
}

void clazzOnStack() {
writeln("Entered");
scope c = new Clazz;
writeln("Leaving");
}

void main()
{
clazzOnStack();
writeln("Back in main");
}
```

You'll find here that the destructor of `c` in `clazzOnStack` is 
called when the function exits, just as if it were a struct. 
`scope` in a class variable declaration will cause it to the 
class to be allocated on the stack.


Note, though, that `c` *still* a reference to the instance. You 
aren't manipulating the class instance directly. If you were to 
pass `c` to a function `doSomething` that accepts a `Clazz` 
handle, it makes no difference that the instance is allocated on 
the stack. `doSomething` would neither know nor care. `c` is a 
handle, so you aren't passing the instance directly and it 
doesn't matter where it's allocated.


There's more to the story than just reference type vs. value 
type. Structs have deterministic destruction, classes by default 
do not (`scope` can give it to you as demonstrated above). [See 
my blog post on the 
topic](https://dlang.org/blog/2021/03/04/symphony-of-destruction-structs-classes-and-the-gc-part-one/) for some info. (And I'm reminded I need to write the next article in that series; time goes by too fast).


Everyone has their own criteria for when to choose class and when 
to choose struct. For me, I default to struct. I consider 
beforehand if I need inheritance, and if yes, then I ask myself 
if I can get by without deterministic destruction. There are ways 
to simulate inheritance with structs, and ways to have more 
control over destruction with classes, so there are options 
either way.


Re: Parameters of overloaded templated function

2022-05-10 Thread Mike Parker via Digitalmars-d-learn

On Tuesday, 10 May 2022 at 12:12:13 UTC, Tejas wrote:


Using aliases as parameters doesn't work(and the DIP that 
wanted to have this behaviour was de facto rejected)


https://github.com/dlang/DIPs/blob/master/DIPs/other/DIP1023.md



No, it wasn't rejected. The author decided it needed reworking 
after one round of review, but he didn't have the time for it. So 
it was marked "Postponed". He was willing to turn it over to 
someone else, if anyone is interested.


Re: How to convert a LPCWSTR aka const(wchar)* to string

2022-05-09 Thread Mike Parker via Digitalmars-d-learn

On Tuesday, 10 May 2022 at 00:50:09 UTC, Vinod K Chandran wrote:

I want to convert this `pszUserString` to a string. How to do 
it. Thanks in advance.


```d
import std.conv : to;
string s = to!string(pszUserString);
```


Re: How to use destroy and free.

2022-05-04 Thread Mike Parker via Digitalmars-d-learn

On Wednesday, 4 May 2022 at 05:37:49 UTC, forkit wrote:

That's not at all what I said. You don't have to care about 
*when* memory is deallocated, meaning you don't have to manage 
it yourself.


In any case, I disagree that caring about when memory gets 
deallocted means you shouldn't be using GC. (or did I get that 
one wrong too??)


You can have the best of both worlds, surely (and easily).

This (example from first post):

void main(){
int[] i = new int[1];

import object: destroy;
destroy(i);
import core.memory: GC;
GC.free(GC.addrOf(cast(void *)(i.ptr)));
}



All you're doing here is putting unnecessary pressure on the GC. 
Just use `malloc` and then `free` on `scope(exit)`. Or if you 
want to append to the array without managing the memory yourself, 
then use `std.container.array` instead. That's made for 
deterministic memory management with no GC involvement.


Re: How to use destroy and free.

2022-05-03 Thread Mike Parker via Digitalmars-d-learn

On Wednesday, 4 May 2022 at 04:52:05 UTC, forkit wrote:



It is certainly *not* about you not having to care anymore 
(about memory management).




That's not at all what I said. You don't have to care about 
*when* memory is deallocated, meaning you don't have to manage it 
yourself.


Re: How to use destroy and free.

2022-05-03 Thread Mike Parker via Digitalmars-d-learn

On Tuesday, 3 May 2022 at 14:57:46 UTC, Alain De Vos wrote:
Note, It's not i'm against GC. But my preference is to use 
builtin types and libraries if possible,
But at the same time be able to be sure memory is given free 
when a variable is going out of scope.
It seems not easy to combine the two with a GC which does his 
best effort but as he likes or not.


What I described is an optional compiler optimization. The 
compiler is free to avoid the GC allocation for an array literal 
initializer if it is possible to do so. If you were to, e.g., 
return the array from the function, it would 100% for sure be 
allocated on the GC and not the stack. In practice, I don't know 
if any of the compilers actually do this.


Anyway, if you care when memory is deallocated, then the GC isn't 
the right tool for the job. The point of the GC is that you don't 
have to care.


Re: How to use destroy and free.

2022-05-03 Thread Mike Parker via Digitalmars-d-learn

On Tuesday, 3 May 2022 at 12:59:31 UTC, Alain De Vos wrote:
Error: array literal in @nogc function test.myfun may cause a 
GC allocation


@nogc void myfun(){
scope int[] i=[1,2,3];
}//myfun

May is a fuzzy word...


It means if the compiler is free to allocate on the stack if 
possible. In practice, though, you can usually assume there will 
be a GC allocation.


  1   2   3   4   5   6   7   8   9   10   >