Re: How to make project with main application and cli application in the same folder?
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: How to use an existing D package in Visual D?
On Tuesday, 5 April 2022 at 09:26:54 UTC, realhet wrote: Hello, I have all my D packages in the c:\D\libs\ directory. I added this path to the PropertyPages/Compiler/Additional Import Paths field. In the project source file I imported a module from my package using "import het.utils;" Also used a function from it. The syntax highlighter worked good, and the compiler was able to build main.obj file. But I can't find the het.utils.obj file nowhere. Also the linker is unable to link the things in it. My question is that how can I add an external package the right way to my project in Visual D? I'm planning to use that package from other projects too, so I want to keep it in one place on my HDD. Thank You in advance! Importing modules is only for showing the compiler which symbols are available for you to use. By default, it does not cause them to be compiled or linked. You should compile the existing package as a library, then add the library file to the linker settings in VisualD.
Re: Conversion from ANSI 1252 to unicode
On Thursday, 7 April 2022 at 07:24:03 UTC, Johann wrote: Hi all, anybody knows if there are functions (preferably) in Phobos, that translate from unicode to other encodings and vice versa? Johann https://dlang.org/phobos/std_encoding.html
Re: Nested function requires forward declaration?
On Thursday, 14 April 2022 at 08:55:25 UTC, Chris Katko wrote: I imagine this is a really odd edge case but it's piqued my interest. Consider this: ```d void main() { void foo() { initRuntimeState(i); } foo(); if(!modifyRutimeState()) return; int i = getRandomValue(); i = returnSomethingBasedOnRuntimeState(i); } ``` Which value of `i` should `foo` use? What if `modifyRuntimeState` and `returnSomethingBasedOnRuntimeState` are dependent on `initRuntimeState`? At module scope, and in class/struct declarations, only compile-time values can be used to initialize variables and assignment is illegal, so the compiler can jump around initializing things in any order it wants. It has a well-defined and limited set of rules it can work with. That just isn't the case in local scopes, where a variable's lifetime begins at the point of declaration, the scope can exit at any time, and the order of evaluation can have side effects that change the run-time state.
Re: DUB issues
On Monday, 18 April 2022 at 05:27:32 UTC, Danny Arends wrote: Any ideas how to get into contact/fix this issue ? I've emailed Sönke and pointed him to this thread.
Re: DUB issues
On Tuesday, 19 April 2022 at 08:58:02 UTC, bauss wrote: On Monday, 18 April 2022 at 13:41:04 UTC, Mike Parker wrote: On Monday, 18 April 2022 at 05:27:32 UTC, Danny Arends wrote: Any ideas how to get into contact/fix this issue ? I've emailed Sönke and pointed him to this thread. Wouldn't the appropriate thing to do be dub being officially a part of D, it's advertised as such, but it really isn't such. It would also make this a non-issue, or at least organizational issue and not a single person who's responsible for it all. I've posted several times about this in meeting summaries: the foundation is moving toward taking over management of all of the vital ecosystem services, including code.dlang.org. My most recent comments about it were in the summary from our quarterly meeting in March: https://forum.dlang.org/post/zfmkiqwkkexeaohjs...@forum.dlang.org See the section "D ecosystem services". In our monthly meeting on April 8 (I'll have a summary for that posted this week), we agreed to get together with the maintainers of some of those services this month to discuss how to move forward. Most of them have responded that they can attend (still waiting on a couple), so it looks like we're on for April 29th. I've already gathered resource requirements from most of them, and I've set up a foundation account with Namecheap to manage domain names. Seb has transferred dlang.io to us, and we have access to the account with dub.pm (Namecheap doesn't support .pm). Walter owns dlang.org, but will transfer it to the foundation before it comes time to renew it. So we'll be discussing hosting, migration, etc., at the meeting, and formulate a plan to get things moving. At the moment, I'm hoping we'll have everything migrated by the end of the year. Once this is complete, we'll have multiple admins in multiple time zones. So it's happening, but it's not going to happen overnight.
Re: Variables & kind of memory
On Saturday, 23 April 2022 at 03:41:17 UTC, Alain De Vos wrote: int [] GLV=[1,2]; int [2] GLF=[1,2]; static int [] GSLV=[1,2]; static int [2] GSLF=[1,2]; FYI, `static` has no effect at module scope.
Re: Variables & kind of memory
On Saturday, 23 April 2022 at 05:01:51 UTC, Alain De Vos wrote: On Saturday, 23 April 2022 at 04:52:39 UTC, Alain De Vos wrote: On Saturday, 23 April 2022 at 03:41:17 UTC, Alain De Vos wrote: I wrote a simple test program: ``` import std.stdio:writefln; [...] BBB: is probably the data-segment. Remains AAA ? Could AAA be the bss-segment ? Run a dump tool on the generated binary and you can see what goes where. And there are probably differences between the three D compilers.
Re: std.typecons Typedef initializers?
On Monday, 25 April 2022 at 08:54:52 UTC, Chris Katko wrote: D struct pair { float x,y; } alias sPair = Typedef!pair; // pair of xy in screen space coordinates alias vPair = Typedef!pair; // pair of xy in viewport space coordinates //etc How do you initialize a typedef'd struct? ``d vPair v1 = vPair(pair(1f, 2f)); ```
Re: How do I get the screen resolution?
On Thursday, 28 April 2022 at 11:22:15 UTC, Alexander Zhirov wrote: Are there any methods to get the screen resolution? On C/C++ from under X11, it is not possible to do this on the command line via SSH, since the display is not defined. And is it possible to do this somehow by means of D, pulling out the system resolution of the installed display? Like C++, the D standard library doesn't have anything for this. It's platform specific. There are several open source libraries out there that include that functionality, so you could just look at one of them (GLFW, SDL, SFML, etc.) and do what they do for the platforms you care about. They all have to go through the same system APIs. For example, on Windows you can use two calls to `GetSystemMetrics` (one for the width, one for the height). (https://docs.microsoft.com/en-us/windows/win32/api/winuser/nf-winuser-getsystemmetrics)
Re: How do I get the screen resolution?
On Thursday, 28 April 2022 at 11:35:46 UTC, Mike Parker wrote: go through the same system APIs. For example, on Windows you can use two calls to `GetSystemMetrics` (one for the width, one for the height). (https://docs.microsoft.com/en-us/windows/win32/api/winuser/nf-winuser-getsystemmetrics) Been a while since I've done any Win32 stuff directly. In this age of multiple monitors, it's probably better to use `EnumDisplaySettings' on Windows. https://docs.microsoft.com/en-us/windows/win32/api/winuser/nf-winuser-enumdisplaysettingsa But the best option is like I said above: see how other libraries do it.
Re: Parameters declared as the alias of a template won't accept the arguments of the same type.
On Sunday, 1 May 2022 at 12:39:08 UTC, Elfstone wrote: Great, I'm using the constraint, until it's fixed. Will it be fixed though? The DIP that Tejas linked is from 2020!!! The DIP was postponed. I can contact the author to see if he intends to pick it up again. If not, anyone interested can take it over. And anyone can submit an alternative at any time.
Re: Parameters declared as the alias of a template won't accept the arguments of the same type.
On Monday, 2 May 2022 at 00:54:40 UTC, Elfstone wrote: Thanks. This breaks a lot of things. I don't know the reason behind the postponing, but who would expect one can't declare a parameter with an alias if it's a template?! Speaking of inconsistency. At the bottom of the DIP you can find a link to the first community review round and a summary of the feedback. You'll see the DIP author decided he needed to do more work on the it. Ultimately, he decided he didn't have a deep enough understanding to complete the DIP without some research, but he was too busy to make that investment. I suggested we mark it as postponed until he could come back to it. Reviewing our conversation, he was willing to someone else taking it over. So if anyone is willing, I don't need to wait on a response from him to make that happen. I'm sure there are bigger issues out there to be solved, but it's quite disencouraging if such a significant improvement(or rather fix) stays ignored. Everyone rates issues differently. What's significant to one person won't be to another. There is much, much work to be done on shoring up holes in existing systems and solving problems the language maintainers believe to be significant, but resources are limited. So some things will inevitably be left to one side until someone picks them up. For issues that are bugs or minor enhancements, we now have Razvan Nitu and Dennis Korpel in part-time positions funded by Symmetry Investments. They manage our issues database and our pull request queues. You can always ping one of them about any particular issue that doesn't require a DIP. This has been a huge change for the better. It means issues and PRs are much less likely to stagnate. For something like your issue, which is a modification of the specification, a DIP is required. And that means either writing one or finding someone willing to write one and see it through to the end of the process. This isn't like managing bugs and pull requests. We simply don't have enough people on board to work on things like this. So it has to be done by interested parties in the community. I wouldn't expect you to take over DIP 1023 yourself since you're new to the language, but if it's important enough to you, perhaps you can find someone to champion it, given a little time. Maybe the original author would be willing to pick it up again.
Re: How to use destroy and free.
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.
Re: How to use destroy and free.
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.
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.
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 convert a LPCWSTR aka const(wchar)* to string
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: Parameters of overloaded templated function
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: Why are structs and classes so different?
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: Why are structs and classes so different?
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: Question on shapes
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: template? mixin? template mixins? for modifying a struct setup
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: UI Library
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
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: Odd construct idea. Splitting arguments inside a parameter list.
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: Dynamic Arrays Capacity
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: Dynamic Arrays Capacity
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, `&ts[0]` is the same as `&(*ts.ptr + 0)`, or simply `ts.ptr`.
Re: Dynamic Arrays Capacity
On Thursday, 2 June 2022 at 08:24:51 UTC, Mike Parker wrote: And so, `&ts[0]` is the same as `&(*ts.ptr + 0)`, or simply `ts.ptr`. That should be the same as `&(*(ts.ptr + 0))`!
Re: dlang compilers & licenses.
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: C-like static array size inference - how?
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: Why allow initializers of non-static members that allocate?
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: Why allow initializers of non-static members that allocate?
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?
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?
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?
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: Can I create a package with friendly modules
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: Can I create a package with friendly modules
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: ImportC: unresolved external symbol
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: Convering strings containing number
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: Static Initialization of Structs syntax
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: dlang bug - accessing module variable from method segfaults only when using module reference directly
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: dlang bug - accessing module variable from method segfaults only when using module reference directly
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
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: char* pointers between C and D
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: This code completely breaks the compiler:
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: How to link a msvcr120.dll in an inverse recursive way after a Windows .exe binary deployment
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: How include header file?
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 I can pass the WndProc as a parameter?
On Saturday, 10 September 2022 at 10:39:12 UTC, Injeckt wrote: And after all, I call it: KK_CreateWindowClass(WndProc); `KK_CreateWindowClass(&WndProc);`
Re: How I can pass the WndProc as a parameter?
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 `&WndProc`, since that's how we get function pointers in D.
Re: Why I get delegate when passing address of function?
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 `&this.ClientThread` 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: Why I get delegate when passing address of function?
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: D installer
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: Visual D doesn't work, now Visual Studio Code / D doesn't work!!!! ....
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: Can someone tell me what the compiler thought I was trying to do?
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: Can someone tell me what the compiler thought I was trying to do?
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: How do I correctly install packages for use with Visual Studio?
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: How do I correctly install packages for use with Visual Studio?
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: Can someone tell me what the compiler thought I was trying to do?
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: Can someone tell me what the compiler thought I was trying to do?
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: dub ldc2 static linking
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: dub ldc2 static linking
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: Importing modules under DUB on Windows
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: What's the correct way of creating an instance of class in D?
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: What's the correct way of creating an instance of class in D?
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: dmd as a library
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: ImportC linking issue
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: ImportC linking issue
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: Using glibc headers with ImportC
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: Actual lifetime of static array slices?
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: Actual lifetime of static array slices?
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: Is defining get/set methods for every field overkill?
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: Is defining get/set methods for every field overkill?
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 there such concept of a list in D?
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: Compile time vs run time -- what is the difference?
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: (Noob question) Should subclasses be defined in separate modules?
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: Non-ugly ways to implement a 'static' class or namespace?
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: Non-ugly ways to implement a 'static' class or namespace?
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?
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?
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?
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?
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?
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?
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: Dub is not finding the dynamic link library MSVCR120.dll...
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?
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: How to build a static lib properly?
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: How to build a static lib properly?
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: @nogc and Phobos
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: Directly compiling a D program with other libraries
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: Code organization, dub, etc.
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: #define-like behavior
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: How to setup D with SFML? (using bindbc-sfml)
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: How to setup D with SFML? (using bindbc-sfml)
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: Unresolvable dependencies to package
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: Unresolvable dependencies to package
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: Cannot get this C++ example migrated to D
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: Cannot get this C++ example migrated to D
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: Making a D library for a C executable
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: A Programmer's Dilema: juggling with C, BetterC, D, Macros and Cross Compiling, etc.
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`.