Re: Static struct?
On Wednesday, 24 April 2019 at 21:12:10 UTC, JN wrote: I noticed a construct I haven't seen before in D when reading the description for automem - https://github.com/atilaneves/automem static struct Point { int x; int y; } What does "static" do in this case? How does it different to a normal struct? You can access variables in the current scope when in a nested scope, static prevents this so that you don't accidentally access any of those values as it adds overhead to the struct. https://run.dlang.io/is/QNumbz void main() { import std.stdio; int x; struct A { void test() { x = 10; } } static struct B { // void test() { x = 20; } // Error } A a; B b; a.test(); // b.test(); writeln( x ); }
Re: How to pass variables to string mixins?
On Tuesday, 26 February 2019 at 00:07:54 UTC, Victor Porton wrote: I want to create a string mixin based on a supplementary variable (name2 below): Let we have something like: mixin template X(string name) { immutable string name2 = '_' ~ name; mixin("struct " ~ name2 ~ "{ int i; }"); } But it would create variable name2 inside X, which should not be created. How to solve this problem? Probably the easiest way is just to move it into another function outside so that it doesn't get mixed in with the mixin template. private string buildStructString(string name2) { return "struct " ~ name2 ~ "{ int i; }" } mixin template X(string name) { mixin(buildStructString("_" ~ name)); }
Re: Am I misusing with?
On Saturday, 19 January 2019 at 17:49:31 UTC, faissaloo wrote: This seems to work fine file = File("test.txt", "r"); with (file) { scope(exit) close(); foreach (string line; file.lines()) { line_array ~= line; } } however: file = File("test.txt", "r"); with (file) { scope(exit) close(); foreach (string line; lines()) { line_array ~= line; } } Tells me I'm attempting to read from an unopened file, what's going on here? It seems like I'm able to use lines() like this within with statements unless they're in my foreach iterator. Is this a bug or intended behaviour? If you look at the implementation, "lines" is a struct. https://github.com/dlang/phobos/blob/v2.084.0/std/stdio.d#L4330 I didn't know you could use structs with UFCS, which is why you are probably confused as well. It's a function defined in "file". If you use lines() by itself, you are constructing a new "lines" struct where the default File is an unopened file. I tend to avoid "with" altogether because of things like this. It becomes hard to tell what is actually part of the struct and what is just UFCS. If you do want to use the object with UFCS you have to explicitly use the object anyways so the point is kind of mute. UFCS if you don't know just means you can use global functions (and apparently structs) with the same syntax as if it were a member function: struct testStruct { this( int value ) { import std.stdio : writeln; writeln("testStruct - ", value); } } void test(int value) { import std.stdio : writeln; writeln( value ); } void main() { 10.test(); // prints 10 20.testStruct(); } https://run.dlang.io/is/0Xpnmt
Re: Forward declaration inside Function block, no error?
On Sunday, 6 January 2019 at 18:38:44 UTC, Benjamin Thaut wrote: Today I found a bug in my D code. import std.stdio; // Type your code here, or load an example. void grow() { writeln("grow"); } void someFunc(bool condition) { if(condition) { void grow(); } } I tried to call the grow function, but accidentially copied the return value alongside the function name. I was wondering why this code compiles without errors. the "void grow();" becomes a no-op. In my opinion this could should not compile. Am I missing something here? Kind Regards Benjamin Thaut import std.stdio; void grow() { writeln("grow"); } void someFunc(bool condition) { if(condition) { void grow(); pragma(msg, grow.mangleof); // _D3app8someFuncFbZ4growMFZv } } You can declare functions inside of functions in D. You weren't forward declare grow() in the module namespace, so much as you were forward declaring a new function grow.
Re: How to initialize a globle variable nicely and properly?
On Saturday, 15 December 2018 at 02:54:55 UTC, Heromyth wrote: We have a module including many globle variables which are needed to be initialized firstly in "shared static this() {}", see here https://github.com/huntlabs/hunt/blob/master/source/hunt/time/Init.d. The problem is that these variables are not always initialized firstly when are referenced by some others moudles in "static this() {}". Here is a demo to illustrate it. // // module A // module test.A; import std.stdio; import core.thread; import core.time; class A { __gshared int sharedField; shared static this() { writeln("running A in shared static this(), sharedField=", sharedField); Thread th = new Thread(() { }); th.start(); Thread.sleep(100.msecs); sharedField = 2; writeln("running A done in shared static this(), sharedField=", sharedField); } static this() { writeln("running A in static this(), sharedField=", sharedField); } } // // module B // module test.B; import test.A; import std.stdio; import core.thread; shared static this() { writeln("running in shared static this() from B"); } class B { shared static this() { writeln("running B in shared static this(), sharedField=", A.sharedField); } static this() { // bug is here writeln("running B in static this(), sharedField=", A.sharedField); } } // // module main // import std.stdio; import test.A; import core.thread; void main() { writeln("running in main."); } // // output // Running ./demo running A in shared static this(), sharedField=0 running A in static this(), sharedField=0 running B in static this(), sharedField=0 // bug is here running A done in shared static this(), sharedField=2 running in shared static this() from B running B in shared static this(), sharedField=2 running A in static this(), sharedField=2 running B in static this(), sharedField=2 running main. You can see the sharedField is 0 in B's static this() at first. If Thread is disabled to run in shared static this(), this problem seems to be fixed. Some related bugs: 1) https://issues.dlang.org/show_bug.cgi?id=6114 2) https://issues.dlang.org/show_bug.cgi?id=4923 The problem here is that you are creating a new thread in the `shared static this()`. shared static this() { writeln("running A in shared static this(), sharedField=", sharedField); Thread th = new Thread(() { }); // Calls `static this()` including B's `static this()` th.start(); Thread.sleep(100.msecs); sharedField = 2; writeln("running A done in shared static this(), sharedField=", sharedField); } static this() { writeln("running A in static this(), sharedField=", sharedField); } Creating a new thread causes those thread's constructor `static this()` to be called. You need to create your threads somewhere else or have the values be initialized before the threads are created.
Re: difficulties with const structs and alias this / template functions
On Sunday, 18 November 2018 at 17:30:18 UTC, Dennis wrote: I'm making a fixed point numeric type and want it to work correctly with const. First problem: ``` const q16 a = 6; a /= 2; // compiles! despite `a` being const. writeln(a); // still 6 a.toQ32 /= 2;// what's actually happening ``` My q16 type has an implicit conversion to q32 (like how int can be converted to long): ``` q32 toQ32() const { return q32(...); } alias toQ32 this; ``` How do I make it so that a const(q16) will be converted to a const(q32) instead of mutable q32? Second problem: ``` Q log2(Q)(Q num) if (is(Q : q16) || is(Q : q32)) { import std.traits: Unqual; Unqual!Q x = num; // actual code } ``` When I call this with a const(q16), Q is resolved to const(q16) so I have to unqualify Q every time. It works, but feels clumsy. Is there an easier way to automatically de-const parameters? We're working with small value types here, it should be simple. If anyone knows any other pitfalls with const, I'd love to know them. Yah most people tend to avoid const for this reason. It only really works for basic types, if you have a "const int" you can convert it to an "int" by copy. But if you have a type like Vector!(const int) that won't work, you can't even convert Vector!int to Vector!(const int) easily for example. ``` Q log2(Q)(Q num) if (is(Q : q16) || is(Q : q32)) { import std.traits: Unqual; Unqual!Q x = num; // actual code } ``` This is pretty much the only way, you can just add alias V = Unqual!Q; then use V in your function instead of Unqual!Q everywhere.
Re: UFCS syntax I never saw before.
On Monday, 21 May 2018 at 11:38:12 UTC, SrMordred wrote: After all this time I saw this: writeln = iota = 5; what?? I never saw that before! This is interesting, there is something useful that i can do with this kind of call? I probably wouldn't use that. That wasn't what it was intended for and it's not really UFCS. It's was meant for properties that are defined as functions. struct SomeStruct { void foo(int); } SomeStruct s; s.foo = 10; It's kind of horrible syntax for what it is doing, where it isn't obvious what is happening. Writeln and iota aren't setting anything, they are just function calls that happen to be able to take one parameter.
Re: C++ / const class pointer signature / unable to find correct D syntax
On Friday, 4 May 2018 at 07:57:26 UTC, Uknown wrote: On Friday, 4 May 2018 at 07:49:02 UTC, Robert M. Münch wrote: I have a static C++ and can't make it to get a correct binding for one function: DMD: public: unsigned int __cdecl b2d::Context2D::_begin(class b2d::Image & __ptr64,class b2d::Context2D::InitParams const * __ptr64 const) __ptr64 LIB: public: unsigned int __cdecl b2d::Context2D::_begin(class b2d::Image & __ptr64,class b2d::Context2D::InitParams const * __ptr64) __ptr64 So I somehow get some more const from D. This is the code I used: final uint _begin(ref Image image, const(InitParams) initParams); Which creates a const pointer to a const class signature. But it should only be a const pointer. Any idea how to solve this? The problem is that const in D is transitive. That means T * const from C++ is not expressible in D. Any reference through a const becomes const. To use it, IMO your best bet is to make a wrapper function on the C++ side like this: unsigned int __cdecl b2d::Context2D::_begin(class b2d::Image & im,class b2d::Context2D::InitParams const * const InitParams) { return //the call to the original c++ function } Alternatively you can use dpp, or dstep or some similar tool to try and let the tool create bindings. As a last ditch, you can force the mangle to match by using pragma(mangle, ...) like this: pragma(mangle, _ZactualMangleFromC++Compiler) final uint _begin(ref Image image, const(InitParams) initParams); Using pragma(mangle) isn't really a solution though, unless you only plan on using one platform/compiler. C++ doesn't have a single standard name mangling. You would need to get the name mangling for every compiler you plan to use then use a version define fore each. Which isn't really practical for how many bindings you would need to do that for. The easiest solution is to just write C bindings for the C++ library then use those instead from D.
Re: C++ / Wrong function signature generated for reference parameter
On Wednesday, 2 May 2018 at 21:55:31 UTC, Robert M. Münch wrote: I have the following C++ function signature: uint _begin(Image& image, const InitParams* initParams) and the following D code: class InitParams { } class B2D { uint _begin(ref Image image, InitParams initParams); } But this compiles to the following signature which is not found by the linker: public: virtual unsigned int __cdecl b2d::Context2D::_begin(class b2d::Image * &,class b2d::InitParams *) I don't understand why "ref Image" translates to "Image * &" and not "Image &". How can I get the C++ reference function signature written down in D? If "Image" is a class then all classes are based as pointers to their respective object. So passing a ref to a class is kind of redundant. You want to use a struct which isn't passed by pointer, but by value. Which will then give you the signature you want.
Add property-like Function to Type ?
I was wondering if I could create my own property in a way that can be used the same way as something like "T.sizeof". Right now I have the following to replace length: uint length32(T)(T[] array) { return cast(uint)array.length; } I want something similar to be able to do the following: uint size = T.sizeof32; The closest I can think of is doing: uint size = sizeof32!T That's the best I can do, which is fine but I was wondering if there's any other way around that?
Re: Declare and Define Before Use? [rant]
On Wednesday, 4 April 2018 at 20:01:55 UTC, Ali wrote: On Wednesday, 4 April 2018 at 19:51:27 UTC, kdevel wrote: On Wednesday, 4 April 2018 at 19:19:30 UTC, Ali wrote: BTW: You can't write void main () { x.writeln; int x; } import std.stdio; This is because x is not module scope you can do this void main () { x.writeln; } import std.stdio; int x; Cause there's no scope at the module level. struct A { A* a; ~this() { // use a } } void main() { A b = A(&a); A a; // in this case "a" destructed before "b", but "b" uses "a" } Destruction and order of destruction becomes much more confusing. You also can't do scope(exit) at the module level for a reason. This mess shouldn't be allowed, it just makes it way worse to understand what is going on.
Re: Fast GC allocation of many small objects
On Friday, 30 March 2018 at 20:46:43 UTC, Per Nordlöw wrote: On Friday, 30 March 2018 at 20:38:35 UTC, rikki cattermole wrote: Use a custom allocator (that could be backed by the GC) using std.experimental.allocators :) https://dlang.org/phobos/std_experimental_allocator.html is massive. I guess I should allocate my nodes using auto node = theAllocator.make!StrNode("alpha"); Could someone please give a working example of a GC-backed `theAllocator` suitable for my allocation pattern? Be willing to change your code, the allocator can change at any point. What you implement today may not work tomorrow, what you fix to work for tomorrow may not end up working the next day (in terms of releases). That really should be something that is mentioned when you suggest using an experimential feature, there's no guarantees at all. It might not even get put into phobos. If your project is going to be used over the course of a year or more than maybe you shouldn't use it.
Re: Are there any working instructions about how to build and test dmd on Windows?
Yah it's not fun. Some notes: You might need to set MSVC_CC environment variable cause it doesn't use the right format for VS path, depending on your version. https://github.com/dlang/dmd/blob/v2.079.0/src/vcbuild/msvc-dmc.d#L19 You could open a command prompt with the batch file running which will add variables used by the script. C:/Program Files (x86)/Microsoft Visual Studio 14.0/VC/vcvarsall.bat You should be able to build it now with just: make -f win64.mak reldmd When building druntime/phobos you need to pass the VCINSTALLDIR environment variable, but it has an unexpected "/" at the end of it so you need to remove it. make -f win64.mak VCDIR="%VCINSTALLDIR:~0,-1%" DMD=../dmd/src/dmd Didn't check if it works though I don't normally use batch/cmd.
Re: Setting up DMD on windows
On Sunday, 4 February 2018 at 01:33:05 UTC, Seb wrote: On Sunday, 4 February 2018 at 01:23:50 UTC, Rubn wrote: On Saturday, 3 February 2018 at 23:42:28 UTC, welkam wrote: [...] I think you have to build with an old version of MSVC, 2010 maybe? It's been a while since I built it I don't remember the exactly which version ended up working. 2013 and 2015 are tested on the CIs. Wasn't that just added? I don't think that CI was running for the version he is trying to compile.
Re: Setting up DMD on windows
On Saturday, 3 February 2018 at 23:42:28 UTC, welkam wrote: Tried to use DMD compiler that I built from source by following these instructions https://wiki.dlang.org/Building_under_Windows They are outdated but I managed to compile it but I get this error when I tried to compile some code. dmdm -run Main.d C:\D\dmd2\windows\32\..\..\src\druntime\import\core\sys\windows\winbase.d(1828): Error: object.Error@(0): Access Violation 0x0064FED6 0x006502BE 0x006499CF 0x006488ED dmdm is just alias dmdm=C:\D\dmd2\windows\32\dmd.exe $* the compiler version is dmd-2.078.0 Could some one help fix this? I think you have to build with an old version of MSVC, 2010 maybe? It's been a while since I built it I don't remember the exactly which version ended up working.
Union Initialization
Is there any way to initialize an array of unions with more than just the first union type? struct A { float a; } struct B { uint b; } union Test { A a; B b; } Test[2] test = [ Test(A(1.0f)), Test(B(10)), // ERROR ]; AFAIK there's no way to specify to use D with an initializer: Test test = { b: B(10) };
Re: New integer promotion rules
On Wednesday, 17 January 2018 at 22:30:11 UTC, rumbu wrote: code like "m = n < 0 ? -n : n" doesn't worth a wrapper That code is worth a wrapper, it's called "abs"... m = abs(n);
Re: New integer promotion rules
On Wednesday, 17 January 2018 at 20:30:07 UTC, rumbu wrote: And here is why is bothering me: auto max = isNegative ? cast(Unsigned!T)(-T.min) : cast(Unsigned!T)T.max); The generic code above (which worked for all signed integral types T in 2.077) must be rewritten like this in 2.078: static if (T.sizeof >= 4) auto max = isNegative ? cast(Unsigned!T)(-T.min) : cast(Unsigned!T)T.max; else auto max = isNegative ? cast(Unsigned!T)(-cast(int)T.min) : cast(Unsigned!T)T.max; Now I have to translate an 1-liner in a 4-liner all around my project. Or write some wrapper code, which you prob should have done in the first place if you use that all around your project: auto max = myMaxFunc!(isNegative, T);