Re: internal compiler error with immutable
On Sat, 07 Feb 2015 09:23:42 -0800, H. S. Teoh via Digitalmars-d-learn wrote: On Sat, Feb 07, 2015 at 02:35:13PM +, Danny via Digitalmars-d-learn wrote: [...] cut- gdc A.d cc1d: ../../src/gcc/d/dfrontend/statement.c:293: ErrorStatement::ErrorStatement(): Assertion `global.gaggedErrors || global.errors' failed. cc1d: internal compiler error: Aborted Please submit a full bug report, with preprocessed source if appropriate. See file:///usr/share/doc/gcc-4.9/README.Bugs for instructions. gdc (Debian 4.9.1-19) 4.9.1 cut- [...] Please file a bug at http://issues.dlang.org/. Compiler internal errors are *always* bugs that need to be fixed. Thanks! this is both non-DMD bug, and nonexistent-in-new-gdc bug. signature.asc Description: PGP signature
Re: Better native D 2D graphics library?
On Sunday, 8 February 2015 at 09:52:50 UTC, Namespace wrote: On Sunday, 8 February 2015 at 01:39:19 UTC, Gan wrote: On Saturday, 7 February 2015 at 23:29:01 UTC, Namespace wrote: On Saturday, 7 February 2015 at 22:09:03 UTC, Gan wrote: Is there a better D graphics library in the works? I'm using SFML(which is very easy and has lots of features) but it seems to use a lot of ram(if you leave it running for a while on a graphic intensive scene) and trying to make it include the dependencies with the compiled executable is complicated. Is there a D 2D graphics library that's just as easy, cross platform, doesn't use X11, allows drawing to off-screen buffers and drawing those to screen? (plus supports nice drawing of shapes, circles, rectangles, lines) I'm probably asking too much- I doubt such a thing exists. I once wrote such a library: https://github.com/Dgame/Dgame But since I left D I don't maintain it. Maybe that will change in the next few weeks. But otherwise you are free to use or improve it. That's really cool. Very very similar to SFML. Only thing that makes me concerned is: static immutable string Disk = D; static immutable string Mode = Release; pragma(lib, Disk ~ :\\D\\dmd2\\src\\ext\\derelict\\lib\\dmd\\DerelictSDL2.lib); pragma(lib, Disk ~ :\\D\\dmd2\\src\\ext\\derelict\\lib\\dmd\\DerelictUtil.lib); pragma(lib, Disk ~ :\\D\\dmd2\\src\\ext\\derelict\\lib\\dmd\\DerelictGL3.lib); pragma(lib, Disk ~ :\\D\\dmd2\\src\\ext\\Dgame\\lib\\ ~ Mode ~ \\DgameInternal.lib); pragma(lib, Disk ~ :\\D\\dmd2\\src\\ext\\Dgame\\lib\\ ~ Mode ~ \\DgameAudio.lib); pragma(lib, Disk ~ :\\D\\dmd2\\src\\ext\\Dgame\\lib\\ ~ Mode ~ \\DgameGraphics.lib); pragma(lib, Disk ~ :\\D\\dmd2\\src\\ext\\Dgame\\lib\\ ~ Mode ~ \\DgameSystem.lib); pragma(lib, Disk ~ :\\D\\dmd2\\src\\ext\\Dgame\\lib\\ ~ Mode ~ \\DgameMath.lib); pragma(lib, Disk ~ :\\D\\dmd2\\src\\ext\\Dgame\\lib\\ ~ Mode ~ \\DgameWindow.lib); I'm not entirely sure what that is or if it's cross-compatible friendly or sharing-with-friends friendly. Though I really hope you re-maintain it. It worked on Mac, Linux and Windows so far without any problems. Forget to add the documentation page I made: http://rswhite.de/dgame4/ Very cool. I was debating switching to SDL but now I'm only debating between switching from SFML to DGame. When I leave my SFML game running for 7 hours, it uses 700mb of ram. Also my friend can't play my games due to missing dylibs(the SFML setup process is complicated). Those are the main reasons I'm looking for an alternative. I'll do a DGame test, if it beats SFML on those issues- I'm hooked.
Re: Fun with floating point
On Sat, 07 Feb 2015 21:33:46 +, Kenny wrote: The above code snippet works correctly when I use LDC compiler (it finds expected 'f' value and prints it to console). I'm wondering is it a bug in DMD? nope, this is a bug in your code. compiler (by the specs) is free to perform intermediate calculations with any precision that is not lower than a highest used type (i.e. not lower that `float`'s one for `while` condition (`f + eps != f`). it may be even infinite precision, so your code may not exit the loop at all. signature.asc Description: PGP signature
Re: internal compiler error with immutable
On 02/07/2015 06:35 AM, Danny wrote: I'm trying to use immutable class instances and that seems to be really difficult. You are not alone. :) Just some reminders: - immutable is a requirement that may not be usable with every type. - immutable string foo() {} is a member function that works on immutable objects. For that reason, that 'immutable' is recommended to appear after the parameter list: string foo() immutable {} For example, with the following program I get an internal compiler error: It generates regular compilation errors with dmd git head. override immutable string toString() { I received the following error for the toString() function above as there is no 'Object.toString immutable' to override: Error: function deneme.Attrsp.toString does not override any function, did you mean to override 'object.Object.toString'? for(i = 0U; i MAX_COMPRESSED_ATTRS; ++i) { if(codes[i] is null) { I received the followin compilation error for the line above: Error: non-shared inout method std.typecons.Rebindable!(immutable(Attrsp)).Rebindable.RebindableCommon!(immutable(Attrsp), Attrsp, Rebindable!(immutable(Attrsp))).get is not callable using a shared mutable object I'm not even trying to modify the contents of the instance, I'm just trying to assign another one to the array slot That would be a violation of immutable, no? (actually not even another one - it was null before). The compiler does not keep track of variables to see that it is null. Since immutable (and const) are transitive, it does not allow rebinding a class reference. Ali
Re: Fun with floating point
nope, this is a bug in your code. compiler (by the specs) is free to perform intermediate calculations with any precision that is not lower than a highest used type (i.e. not lower that `float`'s one for `while` condition (`f + eps != f`). it may be even infinite precision, so your code may not exit the loop at all. Thanks, it's clear now. I still have one question in the above post, I would appreciate if you check it too.
Re: Fun with floating point
On Sun, 08 Feb 2015 09:05:30 +, Kenny wrote: Thanks, it's clear now. I still have one question in the above post, I would appreciate if you check it too. i've seen that, but i don't know the answer, sorry. here we have to summon Walter to explain what his intentions was, how it should work and why. signature.asc Description: PGP signature
Re: Fun with floating point
For example, according to IEEE-754 specification if we work with 32bit floating point numbers (floats in D) then the following pseudo code prints 'Works'. F32 f = 16777216.0f; F32 f2 = f + 0.1f; if is_the_same_binary_presentation(f, f2) Print(Works); As I understand D does not guarantee this. Please confirm if it's correct. One clarification: In D the following should always print 'Works' float f = 16777216.0f; float f2 = f + 1.0f; if (f == f2) writeln(Works); I asked more about this case: float f = 16777216.0f; if (f == f + 1.0f) writeln(Works); Although all operands are 32bit FP the result is not guaranteed to be equal to the result for FP32 computations as specified by IEEE-754.
Re: Fun with floating point
On Sunday, 8 February 2015 at 09:19:08 UTC, Kenny wrote: For example, according to IEEE-754 specification if we work with 32bit floating point numbers (floats in D) then the following pseudo code prints 'Works'. F32 f = 16777216.0f; F32 f2 = f + 0.1f; if is_the_same_binary_presentation(f, f2) Print(Works); As I understand D does not guarantee this. Please confirm if it's correct. One clarification: In D the following should always print 'Works' float f = 16777216.0f; float f2 = f + 1.0f; if (f == f2) writeln(Works); I asked more about this case: float f = 16777216.0f; if (f == f + 1.0f) writeln(Works); Although all operands are 32bit FP the result is not guaranteed to be equal to the result for FP32 computations as specified by IEEE-754. «Algorithms should be written to work based on the minimum precision of the calculation. They should not degrade or fail if the actual precision is greater.» http://dlang.org/float.html :-/
Re: Fun with floating point
i think you are mixing two things here. IEEE doesn't specify which internal representation compilers should use, it only specifies the results for chosen representation. so if D specs states that `float` calculations are always performing with `float` precision (and specs aren't), your sample should work. but the specs says that compiler is free to promote such expression to any type it wants, it just should not loose precision. so the actual type of `f` in `f == f + 1.0f` can be freely promoted to `double`, `real` or even to some GMP representation. It's clear now, thanks!. Also thanks to everyone for the answers, it was very helpful.
Re: internal compiler error with immutable
On 02/07/2015 06:35 AM, Danny wrote: What I'm trying to do is save space by putting often-used Attrs into an array and just compressing references to those into 1 Byte in the other data structures where it's used (these other data structures are not thread-local). The following is based on my understanding of that description: import std.conv; import std.concurrency; import std.stdio; class C { int value; // Constructor for immutable(C) objects this (int value) immutable { this.value = value; } } // Stores commonly used C objects and allows access to them by // ubyte indexes class CommonlyUsedCs { immutable(C)[] cs; // This add() works on 'shared' CommonlyUsedCs objects ubyte add(immutable(C) c) shared { ubyte index; synchronized { index = cs.length.to!ubyte; cs ~= c; } return index; } immutable(C) get(ubyte index) const shared { return cs[index]; } } void main() { auto cucs = new shared(CommonlyUsedCs)(); // Populate the Cs foreach (ubyte i; 0 .. 10) { if (i % 2) { cucs.add(new immutable(C)(i)); } } // Start a thread and tell it what index its C is at spawn(user, cucs, ubyte(3)); } void user(shared(CommonlyUsedCs) cucs, ubyte index) { writefln(My C has value %s, cucs.get(index).value); } Ali
Re: Better native D 2D graphics library?
On Sunday, 8 February 2015 at 01:39:19 UTC, Gan wrote: On Saturday, 7 February 2015 at 23:29:01 UTC, Namespace wrote: On Saturday, 7 February 2015 at 22:09:03 UTC, Gan wrote: Is there a better D graphics library in the works? I'm using SFML(which is very easy and has lots of features) but it seems to use a lot of ram(if you leave it running for a while on a graphic intensive scene) and trying to make it include the dependencies with the compiled executable is complicated. Is there a D 2D graphics library that's just as easy, cross platform, doesn't use X11, allows drawing to off-screen buffers and drawing those to screen? (plus supports nice drawing of shapes, circles, rectangles, lines) I'm probably asking too much- I doubt such a thing exists. I once wrote such a library: https://github.com/Dgame/Dgame But since I left D I don't maintain it. Maybe that will change in the next few weeks. But otherwise you are free to use or improve it. That's really cool. Very very similar to SFML. Only thing that makes me concerned is: static immutable string Disk = D; static immutable string Mode = Release; pragma(lib, Disk ~ :\\D\\dmd2\\src\\ext\\derelict\\lib\\dmd\\DerelictSDL2.lib); pragma(lib, Disk ~ :\\D\\dmd2\\src\\ext\\derelict\\lib\\dmd\\DerelictUtil.lib); pragma(lib, Disk ~ :\\D\\dmd2\\src\\ext\\derelict\\lib\\dmd\\DerelictGL3.lib); pragma(lib, Disk ~ :\\D\\dmd2\\src\\ext\\Dgame\\lib\\ ~ Mode ~ \\DgameInternal.lib); pragma(lib, Disk ~ :\\D\\dmd2\\src\\ext\\Dgame\\lib\\ ~ Mode ~ \\DgameAudio.lib); pragma(lib, Disk ~ :\\D\\dmd2\\src\\ext\\Dgame\\lib\\ ~ Mode ~ \\DgameGraphics.lib); pragma(lib, Disk ~ :\\D\\dmd2\\src\\ext\\Dgame\\lib\\ ~ Mode ~ \\DgameSystem.lib); pragma(lib, Disk ~ :\\D\\dmd2\\src\\ext\\Dgame\\lib\\ ~ Mode ~ \\DgameMath.lib); pragma(lib, Disk ~ :\\D\\dmd2\\src\\ext\\Dgame\\lib\\ ~ Mode ~ \\DgameWindow.lib); I'm not entirely sure what that is or if it's cross-compatible friendly or sharing-with-friends friendly. Though I really hope you re-maintain it. It worked on Mac, Linux and Windows so far without any problems. Forget to add the documentation page I made: http://rswhite.de/dgame4/
Re: Fun with floating point
There is no right or wrong when you compare floating point values for equality (and inequality) unless those values can be represented exactly in the machine. 1.0 is famously not representable exactly. (It is similar to how 1/3 cannot be represented in the decimal system.) Here I tested one aspect of IEEE-754 floating point behavior (not ordinary floating point calculations for daily job). All integers can be represented exactly until some maximum value. I believe that first section from http://dlang.org/float.html explains why behavior of my program should not be considered a bug in the compiler. But does it mean that due to these rules the results of the computation are not according to IEEE-754 for some specified floating point format (32 bit single precision in my examples)? For example, according to IEEE-754 specification if we work with 32bit floating point numbers (floats in D) then the following pseudo code prints 'Works'. F32 f = 16777216.0f; F32 f2 = f + 0.1f; if is_the_same_binary_presentation(f, f2) Print(Works); As I understand D does not guarantee this. Please confirm if it's correct.
Re: How to write asia characters on console?
On Sunday, 8 February 2015 at 06:26:38 UTC, Ali Çehreli wrote: On 02/07/2015 09:57 PM, Lave Zhang wrote: Hi, My first D program is like this: --- import std.stdio; void main(string[] args) { dstring s1 = hello你好d; writeln(s1); } --- But the output is not correct(and my console codepage is 936): C:\D\dmd2\samples\ddmd hello.d -offilename hello.exe C:\D\dmd2\samples\dhello.exe hello浣犲ソ thanks. This thread may be useful: http://forum.dlang.org/thread/suzymdzjeifnfirtb...@dfeed.kimsufi.thecybershadow.net#post-suzymdzjeifnfirtbnrc:40dfeed.kimsufi.thecybershadow.net Ali Thanks, my problem has been solved:) --- import std.stdio; import core.stdc.wchar_; extern(C) int setlocale(int, char*); static this() { fwide(core.stdc.stdio.stdout, 1); setlocale(0, cast(char*)china); } int main(string[] args) { string s1 = hello你好; writefln(%s, s1); return 0; }
Re: Fun with floating point
On Sun, 08 Feb 2015 09:19:06 +, Kenny wrote: I asked more about this case: float f = 16777216.0f; if (f == f + 1.0f) writeln(Works); Although all operands are 32bit FP the result is not guaranteed to be equal to the result for FP32 computations as specified by IEEE-754. i think you are mixing two things here. IEEE doesn't specify which internal representation compilers should use, it only specifies the results for chosen representation. so if D specs states that `float` calculations are always performing with `float` precision (and specs aren't), your sample should work. but the specs says that compiler is free to promote such expression to any type it wants, it just should not loose precision. so the actual type of `f` in `f == f + 1.0f` can be freely promoted to `double`, `real` or even to some GMP representation. signature.asc Description: PGP signature
Re: Fun with floating point
Also note that denormal numbers is an issue, e.g. D assumes that they are always supported, I think. Which frequently is not the case...
Re: strange work of GC
On 2015-02-08 at 06:36, Mike Parker wrote: On 2/8/2015 11:32 AM, FG wrote: On 2015-02-08 at 01:20, Mike Parker wrote: In your case, forget destructors and the destroy method. Just implement a common method on all of your objects that need cleanup (perhaps name it 'terminate') and call that. This gives you the deterministic destruction that you want (the same as calling destroy on each object) while avoiding the possibility that the GC can call your cleanup method. What is wrong with doing all that in a destructor? I don't know if it is just an implementation detail, but a destroyed object is either zero-filled or reinitialized to the default, so, if implemented correctly, it knows whether a cleanup is required (and I'm assuming that a model of simple single ownership is used, like in Qt). Therefore it should be safe to use destroy to finalize an object and even to put destroy in its destructor in order to perform a controlled cascade destruction of all the children that require immediate cleanup (ie. releasing expensive non-GC resources, closing connections, etc.). The main difference with C++ being that you would only force finalization, but then let the GC free the memory in its normal fashion. First, there are no guarantees about when or if a destructor is going to be called. The fact that the current GC calls the destructors of all live objects at application shutdown is an implementation detail. If you want deterministic destruction, you can not rely on destructors. I admit that I became accustomed to that implementation detail and would like it to stay. Second, if you are going to call destroy on every object to clean them up, then in principle that's fine. But now you have to be careful that no mistakes slip into the code base, e.g. forgetting to call destroy on an object that touches GC memory in its destructor. One could also forget to call terminate(). :) The advantage of ~this() is that it is standard, while terminate() is not. You call it that, someone else might call it finalize(), close() or whatever. I do see a benefit in using terminate() directly instead of the GC-fired destructor, because it's not constrained by having to steer clear of the InvalidMemoryOperationError, but it is overshadowed by inconvenience. So let's assume that terminate() is GC-friendly (ie. would work even when called from a destructor). By separating resource cleanup from object destruction, you get both deterministic cleanup and more freedom in choosing whether or not to clean up at all. I separate them only when the object needs it (flush a write, close a connection, release a big chunk of memory, etc.), by calling destroy and not waiting until the GC decides that it's time to deallocate memory for that object and performs the destruction by itself. For every other case of object I also do not care when and if it gets cleaned up. At app exit, I only call terminate on objects that absolutely need to do something before the process exits, like writing a final message to a log file [...] resource cleanup only happens when and if I say. Exactly, but if I put a call to terminate() in the destructor, then clean up will be automated in those cases when I don't care about cleaning up myself or *forget* to do it. That just isn't possible if all cleanup is in destructors. You either have to destroy *every* object yourself, or be vigilant about which objects you let the GC call destructors on. Why not? Are you saying that because of the lack of guarantees that a destructor will be called by the GC? And not *every* object -- it was stated that we don't care about all those objects that don't require special clean up.
Re: internal compiler error with immutable
Hi Ketmar, Hi Ali, thank you! On Sunday, 8 February 2015 at 09:42:14 UTC, Ali Çehreli wrote: spawn(user, cucs, ubyte(3)); ^to! Other than that, it works. (The Attributes are basically literal constants but the library cannot know which are used in a given program - but probably not more than 20 or so are used realistically - it would be a UI design faux pas for content to be - like XP start menu - in hundreds of different yellowish greenish colors) Unfortunately, I can't seem to get opEquals to work with immutable (or const, for that matter) either. (does compile, though) The obvious bool opEquals(immutable(C) b) immutable { return value == b.value; } doesn't work. Probably have to override the one from Object ? Even though I don't really use polymorphism here. override bool opEquals(Object b) immutable { return value == (cast(immutable(C)) b).value; } Nope. Doesn't work (or compile) either. As a test, I added foreach (ubyte i; 0 .. 10) { if (i % 2) { cucs.add(new immutable(C)(i)); assert(new immutable(C)(i) == new immutable(C)(i)); // this } } to your program but the assertion fails after the changes (if it even compiles). Hmm, maybe I should just store immutable struct C pointers? Yep, that works, although then I have to compare for equality by *a == *b... oh well, I use opEquals comparison only internally after all.
Re: Classes and @disable this()
On Sunday, 8 February 2015 at 16:28:21 UTC, fra wrote: On Sunday, 8 February 2015 at 16:22:36 UTC, fra wrote: Missclick... Anywya: class Something { @disable this(); this(int i) {} } produces an undefined reference error. I guess it has to do with classes implicitly inheriting from Object, and Object defining a this(), and @disable telling the compiler not to produce code for the given function. However making it a compiler error would be far, far better then getting the linker error. In my case, the mangled name was 100% unintelligible (the usual _ctor was nowhere to be found, probably due to the class name being so long that it was getting shortened in some way) No need to use @disable this(); A default constructor will only be generated when you don't define a constructor yourself.
Classes and @disable this()
I just realized that you cannot define a disabled default constructor for classes: writing code like this will give a linker error class Something {
Re: why GC not work?
On 2015-02-08 at 15:56, mzf wrote: On Saturday, 7 February 2015 at 06:08:39 UTC, ketmar wrote: On Sat, 07 Feb 2015 04:30:07 +, Safety0ff wrote: False pointers, current GC is not precise. not only that. constantly allocating big chunks of memory will inevitably lead to OOM due to current GC design. you can check it with manual freeing. there were some topics about it, and the solution is either use 64 bit OS ('cause the memory is here, but there is no address space to allocate it), or use `malloc()` and `free()` from libc. hi,i still have two questions: 1. how large is the big chunks ? 10MB? 50MB? ... where are topics about this? if I don't know the exact size, it is very likely a memory leak You wrote yourself, that you used win7 x86,dmd v2.066.0, that is x86 and not x86-64. In 32-bits even with blocks as small as 1 MB there is a chance that the garbage collector will think some data on stack is a pointer to that block because when cast to void* it could point right into that allocated block of memory. 2. auto buf = new byte[](1024*1024*100); now the gc can't free this buf. can i free it by manual? Yes. import core.memory; GC.free(buf.ptr); // and don't use buf afterwards
Re: Classes and @disable this()
On Sunday, 8 February 2015 at 16:22:36 UTC, fra wrote: Missclick... Anywya: class Something { @disable this(); this(int i) {} } produces an undefined reference error. I guess it has to do with classes implicitly inheriting from Object, and Object defining a this(), and @disable telling the compiler not to produce code for the given function. However making it a compiler error would be far, far better then getting the linker error. In my case, the mangled name was 100% unintelligible (the usual _ctor was nowhere to be found, probably due to the class name being so long that it was getting shortened in some way)
Re: Classes and @disable this()
fra: However making it a compiler error would be far, far better I think this can be filed in Bugzilla as diagnostic enhancement: class Foo { @disable this(); this(int i) {} } void main() {} Bye, bearophile
Re: why GC not work?
On Sunday, 8 February 2015 at 16:23:44 UTC, FG wrote: 2. auto buf = new byte[](1024*1024*100); now the gc can't free this buf. can i free it by manual? Yes. import core.memory; GC.free(buf.ptr); // and don't use buf afterwards That won't work, see: http://forum.dlang.org/thread/uankmwjejsitmlmrb...@forum.dlang.org
Re: why GC not work?
On 2015-02-08 at 19:15, safety0ff wrote: On Sunday, 8 February 2015 at 16:23:44 UTC, FG wrote: 2. auto buf = new byte[](1024*1024*100); now the gc can't free this buf. can i free it by manual? Yes. import core.memory; GC.free(buf.ptr); // and don't use buf afterwards That won't work, see: http://forum.dlang.org/thread/uankmwjejsitmlmrb...@forum.dlang.org Perhaps it was fixed in DMD 2.066.1, because this works for me just fine: import core.memory; void testGC() { auto b = new byte[](1024 * 1024 * 100); GC.free(b.ptr); } void main() { foreach (i; 1..100) testGC(); }
Re: How to write asia characters on console?
Thanks, my problem has been solved:) --- import std.stdio; import core.stdc.wchar_; extern(C) int setlocale(int, char*); static this() { fwide(core.stdc.stdio.stdout, 1); setlocale(0, cast(char*)china); } int main(string[] args) { string s1 = hello你好; writefln(%s, s1); return 0; } This solution has a problem, look at this: http://forum.dlang.org/thread/jfawjvoedsxsznsue...@forum.dlang.org#post-tyslcbycorgfaqimldnd:40forum.dlang.org
Re: Better native D 2D graphics library?
Let me hear what comes out. ;)
Re: Fast array copy. SIMD manual or automatic?
On Saturday, 7 February 2015 at 06:30:32 UTC, tcak wrote: I have two char arrays at the size of 16KB. I will copy a part of data between them again and again. arrayA[0 .. dataLen] = arrayB[0 .. dataLen]; Does the compiler generate code that uses SIMD operations (128-bits memory copy) automatically, or do I need to do anything special for this? Does SIMD even matter anything when it comes to copying? I was sure it was just about moving data into SIMD registers for later operation on that.
Re: why GC not work?
On Saturday, 7 February 2015 at 06:08:39 UTC, ketmar wrote: On Sat, 07 Feb 2015 04:30:07 +, Safety0ff wrote: False pointers, current GC is not precise. not only that. constantly allocating big chunks of memory will inevitably lead to OOM due to current GC design. you can check it with manual freeing. there were some topics about it, and the solution is either use 64 bit OS ('cause the memory is here, but there is no address space to allocate it), or use `malloc()` and `free()` from libc. hi,i still have two questions: 1. how large is the big chunks ? 10MB? 50MB? ... where are topics about this? if I don't know the exact size, it is very likely a memory leak 2. auto buf = new byte[](1024*1024*100); now the gc can't free this buf. can i free it by manual?
Rational of some DMD decisions
Hiho, as I am currently very insterested in compiler implementation I often look into the DMD github and look how things are done there. Often I find myself curious about things at first but find out the rational behind certain implementation decisions. One thing I can't figure out is the different approach with pre- and postfix expressions. While prefix expressions inherit from UnaExp (unary expression) which makes sense to me as it is an expression with only one parameter (in general) the postfix inc and decrement expressions are inherited from BinExpr (binary expression) which define their second expression to be an integer expression with a value of 1. So I am very curious about the rational behind this design decision. Why do Postfix expression not inherit from UnaExp, too? Am I missing something very important? Thanks in advance! =) I hope this is the right place to ask questions about the DMD compiler. Regards, Robin
Template constructor in a non-template struct.
Hi, I couldn't find information about problem I'm having. This builds: enum { Option1, Option2 } struct boring { this(int Opt = Option1)(int arg1, int arg2) { ... } } However, I can't figure out how to instantiate that constructor. When I call it like this: auto a = boring(1, 2); The compiler doesn't seem the template constructor, only the non-template constructors which take a different set of arguments. When I call it like this: auto a = boring!(Option1)(1, 2); It complains that my struct isn't a template struct, which makes sense; however, I don't really understand how I'd differentiate a constructor template from a class/struct template. Any ideas? -Chris
Re: Template constructor in a non-template struct.
ChrisG: I don't really understand how I'd differentiate a constructor template from a class/struct template. One solution is to use a template struct (struct/class names start with an upper case in D, while typed enum members usually start with a lower case): enum E { option1, option2 } struct Boring(E Opt = E.option1) { this(int arg1, int arg2) {} } void main() { auto a = Boring!(E.option2)(1, 2); } If you want to instantiate the constructor template without type inference, then this seems to work, but it's not idiomatic D: enum E { option1, option2 } struct Boring { this(E Opt = E.option1)(int arg1, int arg2) {} } void main() { auto a = Boring().__ctor!(E.option2)(1, 2); } Bye, bearophile
Re: why GC not work?
On Sunday, 8 February 2015 at 18:43:18 UTC, FG wrote: On 2015-02-08 at 19:15, safety0ff wrote: That won't work, see: http://forum.dlang.org/thread/uankmwjejsitmlmrb...@forum.dlang.org Perhaps it was fixed in DMD 2.066.1, because this works for me just fine: Here's the link I couldn't find earlier: https://issues.dlang.org/show_bug.cgi?id=14134
Re: Classes and @disable this()
On Sunday, February 08, 2015 17:51:09 bearophile via Digitalmars-d-learn wrote: fra: However making it a compiler error would be far, far better I think this can be filed in Bugzilla as diagnostic enhancement: class Foo { @disable this(); this(int i) {} } void main() {} The compiler should probably just give you an error telling you that disabling the default constructor on classes is illegal. And since no default constructor is automatically declared if you declare another constructor, there isn't even any point in disabling the default constructor (which is probably why no one has been complaining about this). @disable this() only makes sense on structs. - Jonathan M Davis
Re: Template constructor in a non-template struct.
Thanks bearophile. Your first suggestion about making the struct a template is something I considered. However, because of all the code I've already written that approach would force me to use inheritance or convert a ton of functions to templates. Ick. The __ctor syntax looks like the answer to my question. If my struct is used by anyone else though, I'm not sure it would be OK to assume they would even be aware of that syntax. hmmm... Thinking I'll just make it a runtime parameter for now. Thank you. -Chris On Sunday, 8 February 2015 at 21:58:40 UTC, bearophile wrote: ChrisG: I don't really understand how I'd differentiate a constructor template from a class/struct template. One solution is to use a template struct (struct/class names start with an upper case in D, while typed enum members usually start with a lower case): enum E { option1, option2 } struct Boring(E Opt = E.option1) { this(int arg1, int arg2) {} } void main() { auto a = Boring!(E.option2)(1, 2); } If you want to instantiate the constructor template without type inference, then this seems to work, but it's not idiomatic D: enum E { option1, option2 } struct Boring { this(E Opt = E.option1)(int arg1, int arg2) {} } void main() { auto a = Boring().__ctor!(E.option2)(1, 2); } Bye, bearophile
primitive type variables not nullable ?
colors = [ black : నలుపు, white : తెలుపు, red : యెరుపు, green : పచ్చ, blue: నీలం ]; writefln(Before: ); writeln(colors); colors = null; writefln(after: ); writeln(colors); This above bit of code is trying to delete all elements at once by assigning a null to colors associative array. Interesting thing is the write output after assigning null to colors variable shows []. Here is the output. Before: [blue:నీలం, red:యెరుపు, white:తెలుపు, green:పచ్చ, black:నలుపు] after: [] So primitive types can never be null ? An null assignment would set the primitive type variable to a default value ?
Static method of inner class needs this
class Outer { class Inner { static Inner createInner() { return new Inner(); //need 'this' to access member this } } } Is this a bug? If Inner is not nested, it works as expected: class Inner { static Inner createInner() { return new Inner() } } D version: 2.066.1
parse string as char
Is there a simple way to parse a string as a char? eg: unittest{ assert(parseChar(`a`)=='a'); assert(parseChar(`\n`)=='\n'); //NOTE: I'm looking at `\n` not \n // should also work with other forms of characters, see http://dlang.org/lex.html } Note, std.conv.to doesn't work (`\n`.to!char does not work)
Re: Better native D 2D graphics library?
On Saturday, 7 February 2015 at 23:29:01 UTC, Namespace wrote: On Saturday, 7 February 2015 at 22:09:03 UTC, Gan wrote: Is there a better D graphics library in the works? I'm using SFML(which is very easy and has lots of features) but it seems to use a lot of ram(if you leave it running for a while on a graphic intensive scene) and trying to make it include the dependencies with the compiled executable is complicated. Is there a D 2D graphics library that's just as easy, cross platform, doesn't use X11, allows drawing to off-screen buffers and drawing those to screen? (plus supports nice drawing of shapes, circles, rectangles, lines) I'm probably asking too much- I doubt such a thing exists. I once wrote such a library: https://github.com/Dgame/Dgame But since I left D I don't maintain it. Maybe that will change in the next few weeks. But otherwise you are free to use or improve it. I use Dgame for hobby projects and can definitely recommend it.
Re: Rational of some DMD decisions
Thank you for your reply. I didn't know that it isn't possible to overload the post-inc and decrement operators in Dlang but I think I don't even miss this feature if pre-inc/dec is still available. =)
Re: primitive type variables not nullable ?
Tobias Pankrath: Check for null with (x is null) not via printing to stdout. In most cases instead of checking dynamic arrays for null, it's better to use std.array.empty. Bye, bearophile
Re: appender!(string[]).put(string) doesn't work
On 2/8/2015 4:09 PM, David Held wrote: auto data = appender!(string[]); ... data.put(someString); [...] Never mind. someString is actually the result of stdin.byLine(), which returns a char[], not a string. I didn't notice this until just now. .idup fixes this just fine (although, I suppose changing it to char[][] might be even better). Dave
Re: Rational of some DMD decisions
On 02/08/2015 01:05 PM, Robin wrote: the postfix inc and decrement expressions are inherited from BinExpr (binary expression) which define their second expression to be an integer expression with a value of 1. Post-increment cannot be overloaded in D. It is always implemented in terms of pre-increment (or +=): http://dlang.org/operatoroverloading.html Although I can't find it on the spec, I think it used to be spelled out that pre-increment (and post-increment) could be the equivalent of += 1. I am pretty sure about that because my notes say so! :p (because I based everything on what I knew to be correct at the time). http://ddili.org/ders/d.en/operator_overloading.html Quoting myself: if an opBinary overload supports the duration += 1 usage, then opUnary need not be overloaded for ++duration and duration++. Instead, the compiler uses the duration += 1 expression behind the scenes. Similarly, the duration -= 1 overload covers the uses of --duration and duration-- as well. Perhaps that's why the compiler uses a binary operator for post-increment. Ali
appender!(string[]).put(string) doesn't work
auto data = appender!(string[]); ... data.put(someString); source\colony.d(360): Error: template std.array.Appender(string[]).Appender.put does not match any function template declaration. Candidates are: D:\D\dmd2\windows\bin\..\..\src\phobos\std\array.d(2251): std.array.Appender!(string[]).Appender.put(U)(U item) if (canPutItem!U) D:\D\dmd2\windows\bin\..\..\src\phobos\std\array.d(2279): std.array.Appender!(string[]).Appender.put(Range)(Range items) if (canPutConstRange!Range) D:\D\dmd2\windows\bin\..\..\src\phobos\std\array.d(2288): std.array.Appender!(string[]).Appender.put(Range)(Range items) if (canPutRange!Range) source\colony.d(360): Error: template std.array.Appender!(string[]).Appender.put(U)(U item) if (canPutItem!U) cannot deduce template function from argument types !()(char[]) The example in the documentation implies that this should work fine. What am I missing? Dave
Re: primitive type variables not nullable ?
Never mind, stupid question I realize, would delete it if I could. http://stackoverflow.com/questions/11047276/null-for-primitive-data-types
Re: parse string as char
On 9/02/2015 3:40 p.m., Timothee Cour via Digitalmars-d-learn wrote: Is there a simple way to parse a string as a char? eg: unittest{ assert(parseChar(`a`)=='a'); assert(parseChar(`\n`)=='\n'); //NOTE: I'm looking at `\n` not \n // should also work with other forms of characters, see http://dlang.org/lex.html } Note, std.conv.to http://std.conv.to doesn't work (`\n`.to!char does not work) Ugh, if you are just wanting to get a singular char in a string just you slices. assert(mystr[0] == 'm');
Re: primitive type variables not nullable ?
On Sunday, 8 February 2015 at 23:13:33 UTC, Venkat Akkineni wrote: Never mind, stupid question I realize, would delete it if I could. http://stackoverflow.com/questions/11047276/null-for-primitive-data-types Check for null with (x is null) not via printing to stdout.