Array of closures assign
This D2 program compiles with no errors: void delegate()[1] foo; void main() { int n; foo[0] = { n++; }; } But this one: void delegate()[1] foo; void main() { int n; foo[] = [{ n++; }]; } test.d(4): Error: cannot implicitly convert expression ([delegate void() { n++; } ]) of type void delegate()[] to const(void delegate()[]) Is this a front-end bug? Bye, bearophile
Re: Strange socket error
Hi Heywood Thankyou for your time. Yes I agree making the call blocking does stop the exceptions churning. Unfortunately the application stops accepting data now because after the first incoming transfer from the web socket client it sees data on the listening socket and promptly blocks on it and never comes off until I make another connection. I think this is expected behaviour. I could spawn a thread for each connection which I would normally do but shouldn't need to as it's really only a few users and I believe that would only sidestep the real problem. There are lots of things here that don't make sense. 1. It works for Windows and it should work for Linux (and Mac) unless Windows is broken and Linux is behaving as it should. 2. I should only see data on the listen socket when I make a new connection. What I see is data on the listen socket when I send data on the connected socket and with non-blocking even when I don't make a connection or send any data at all. 2. The really confusing thing is if I stop my USB and DSP threads it stops behaving like this and sees data on the correct sockets. In other words it works as it does on Windows so I have to assume this is the correct behaviour. 3. I've played around with trying to figure out exactly what it is in the other threads that causes the behaviour. I got as far as finding that only the DSP thead is required so that rules out misbehaving USB. Very oddly there is a loop that is creating some Json data (not very efficiently) as it's doing a lot of string concatenation. If I comment out this loop or reduce its iterations the exception slow down to the point where I just get 2 and then they stop. This points to something horrible going on. I can only hope I've done something stupid that I just happen to be getting away with on Windows. If it's a bug in the compiler or libraries I think I'm stuffed as I wouldn't know where to start. Regards bob On 23/12/2010 00:20, Heywood Floyd wrote: Hi Bob! My guess: You're listener is set to be non-blocking. That means that when you call listener.accept() it will return immediately with an SocketAcceptException, if there's no connection. And you're basically calling listener.accept() over and over again in an infinite loop. The following example shows it: import std.concurrency, std.stdio, std.conv, std.socket; void main() { ushort port = ; Socket listener = new TcpSocket; assert(listener.isAlive); listener.blocking = false; listener.bind(new InternetAddress(port)); listener.listen(10); writeln(Listening on port: , port); Socket sn; while(true){ try { writeln (Accepting); sn = listener.accept(); writeln(Connection from , sn.remoteAddress().toString(), established ); assert(sn.isAlive); assert(listener.isAlive); break; } catch(Exception e) { writeln(Error accepting: , e.toString() ); if(sn) sn.close(); } } writeln(end); } Running the example will print Error accepting: std.socket.SocketAcceptException: Unable to accept socket connection: Resource temporarily unavailable for ever. (Tested on Mac.) When a user connects to 127.0.0.1: (by for instance opening the URL in a browser) socket.accept _does_ return a connection and the program prints end. I don't know why the program doesn't do this on Windows. As far as I can tell the endless exceptions _is_ the correct behaviour, right? Anyway, if you comment out the the line listener.blocking = false; in 'listener.d', does it work as intended then? In the example above this will cause the listener.accept()-call to actually wait until it gets a connection, and thus not spew out all the exceptions. BR /heywood Bob Cowdery Wrote: Hi all, This is a long shot but I'm out of ideas. I ported an app from Windows to Linux and after many issues it is working but I'm left with a strange problem. The app basically reads data streams from a USB device, processes them and outputs real-time graphical data to a browser. There is also some control input from the browser. The interface to the browser is web sockets for which I have written a D web-socket server. Depending on how much of my application I allow to run I get a stream of these errors. Error accepting: std.socket.SocketAcceptException: Unable to accept socket connection: Resource temporarily unavailable ./DcSdr() [0x80aa2ed] ./DcSdr() [0x806f52b] ./DcSdr() [0x804f752] ./DcSdr() [0x809b422] ./DcSdr() [0x80ae77e] /lib/tls/i686/cmov/libpthread.so.0(+0x596e) [0x48496e] /lib/tls/i686/cmov/libc.so.6(clone+0x5e) [0xc5fa4e] This is the web-socket accept. I seem to
Re: double - double[]... | feature or bug?
On Thu, 23 Dec 2010 00:34:41 -0600 Christopher Nicholson-Sauls ibisbase...@gmail.com wrote: On 12/22/10 15:06, Andrej Mitrovic wrote: Oooh. That cought me off guard, sorry. Thanks Steve. I'll concede that the syntax can be odd at first, but it also enables some interesting things. For example, this works: class Foo { this (int i, double f) { /*...*/ } /*...*/ } void someFunc ( Foo foo ... ) { /*...*/ } someFunc( 5, 3.14 ); Basically, given a class (and I think struct's work as well) as the variadic type, it will accept either an instance of said class, or any combination of values which can be mapped to a constructor of that class. It can be convenient sometimes. While I understand some may consider this a nice feature, for me this is an enormous bug. A great way toward code obfuscation. I like D among other reasons because it's rather clear compared to other languages of the family. There should be no automagic constructor call (at least in this case, when the type is not even mentionned on the caller side). This may even lead to very naughty bugs. And what if Foo has subtypes, and the one actually invoked is the one intended by the user? Denis -- -- -- -- -- -- -- vit esse estrany ☣ spir.wikidot.com
Re: double - double[]... | feature or bug?
spir: While I understand some may consider this a nice feature, for me this is an enormous bug. A great way toward code obfuscation. I like D among other reasons because it's rather clear compared to other languages of the family. The main problem here is that I have never felt the need of that feature, so for me it's useless. Has Walter added it after a good number of people have asked for this feature? Has any one here needed it? Bye, bearophile
import from subdir
Hello, Say I have a project with the following tree structure: [app] app.d util.d [test] test.d [data] data.d Is there a way to import util data from test? Denis -- -- -- -- -- -- -- vit esse estrany ☣ spir.wikidot.com
Re: import from subdir
On Thursday 23 December 2010 04:38:56 spir wrote: Hello, Say I have a project with the following tree structure: [app] app.d util.d [test] test.d [data] data.d Is there a way to import util data from test? Use the -I flag when compiling. Presumably, you'd do something like -I../ so that it would also search for files starting at the parent directory. - Jonathan M Davis
Re: is this the expected output
On 23.12.2010 3:40, g g wrote: Thanks for the answers what I did is this ( i feel that it is quite clumsy): Node* x = cast(Node*) (GC.malloc(Node.sizeof)); *x = xa; x.up = curnode; ... which could be improved: Node* x = new Node(...);//paste your constructor args in place of ... if Node has a constructor, or just Node* x = new Node;// if no constructors -- Dmitry Olshansky
Re: import from subdir
On Thu, 23 Dec 2010 05:26:57 -0800 Jonathan M Davis jmdavisp...@gmx.com wrote: On Thursday 23 December 2010 04:38:56 spir wrote: Hello, Say I have a project with the following tree structure: [app] app.d util.d [test] test.d [data] data.d Is there a way to import util data from test? Use the -I flag when compiling. Presumably, you'd do something like -I../ so that it would also search for files starting at the parent directory. - Jonathan M Davis Thank you, I'll try this solution. So, there is no syntax? (I tried import ..util; and import ..data.data; without any success ;-) What about proposing that each _single_ leading dot moves up one dir? In my case, this would give import .util; and import .data.data;. I find this simple, practical and very useful. Denis -- -- -- -- -- -- -- vit esse estrany ☣ spir.wikidot.com
DMD2 out parameters
Hi, I'm not sure if this is already a widely known phenomenon but I ran across a little gotcha yesterday regarding floating point out parameters using DMD2. A year or so ago I wrote a ray tracer using DMD1. A few months ago I tried compiling and running it using DMD2. It was 50% slower. This disappointed me so much that I stopped using D2 until about a week ago. I spent a few hours yesterday investigating why the D2 version of the code was so much worse than the D1 version. After some head scratching and use of -profile and objconv, I eventually managed to isolate the problem. It boiled down to this example: float f; func(f); void func(out float ff) { ff = 1; } This use of 'out' causes func to execute in around 250 ticks on DMD2. Change 'out' to 'ref' and it takes around 10 ticks (the same time as the 'out' version executes on DMD1). If you initialise f to 0 before calling func then it all works quickly again which makes me wonder whether it's some strange DMD2 nan/fpu exceptions quirk which may be documented somewhere?? When I looked at the generated assembly I saw that both DMD1 and DMD2 seem to generate the same thing (using -O -inline - release): func LABEL NEAR pushebp mov ebp, esp pusheax // eax = ptr to ff fld dword ptr [_nan] fstpdword ptr [eax] fld dword ptr [_one] fstpdword ptr [eax] mov esp, ebp pop ebp ret Now this code looks ok if you ignore the fact that 'ff' is being written to twice. And the strange seemingly redundant push of EAX. Has anyone else come across this and if so is it a bug? I'm also interested in people's thoughts on the strange code gen. My D2 version is now running faster than the old D1 version by the way :) Regards, Pete.
Re: DMD2 out parameters
//If you initialise f to 0 before calling func then it all works quickly again Actually I think this is a red herring. I don't think initialising f helps
Re: double - double[]... | feature or bug?
On 12/23/10, bearophile bearophileh...@lycos.com wrote: spir: While I understand some may consider this a nice feature, for me this is an enormous bug. A great way toward code obfuscation. I like D among other reasons because it's rather clear compared to other languages of the family. The main problem here is that I have never felt the need of that feature, so for me it's useless. Has Walter added it after a good number of people have asked for this feature? Has any one here needed it? Bye, bearophile You should probably ask in d-general. It looks like a dangerous feature to have. If you have that function laying in another imported module you might not even realize that you're constructing an object. Consider this: void test(int x, int y, string z); // your module which you accidentally forgot to import void test(int x, Foo f ...); // some other module that *is* imported test(1, 4, def); // calling site that constructs a Foo object Maybe it takes more typing, but I prefer this: test(1, new Foo(4, def)); It's explicit and you can reason about it without having to inspect other modules.
Re: Strange socket error
Hi! I see. I think my previous answer was a bit naiveI didn't appreciate the full scope of the problem. Sorry for that, but you know, internet is fast, snap snap : ) Ok, for now I'm afraid I don't have any more to add. (An isolated example would of course help greatly!) All I can say is, in my experience, the D sockets library _does_ behave differently on different platforms. Had a server that just died seemingly random on osx, while working fine on Linux. Turned out to be bug in D sockets. So there you go. (The bug is still there btw... *cough*) Hm, also, I realize I'm not sure I quite understand the structure of your app, and where in this structure the bug happends. Is this bug happening when your html/5-client tries to connect to the server? Or are the threads using sockets to communicate between eachother? BR /heywood Bob Cowdery Wrote: Hi Heywood Thankyou for your time. Yes I agree making the call blocking does stop the exceptions churning. Unfortunately the application stops accepting data now because after the first incoming transfer from the web socket client it sees data on the listening socket and promptly blocks on it and never comes off until I make another connection. I think this is expected behaviour. I could spawn a thread for each connection which I would normally do but shouldn't need to as it's really only a few users and I believe that would only sidestep the real problem. There are lots of things here that don't make sense. 1. It works for Windows and it should work for Linux (and Mac) unless Windows is broken and Linux is behaving as it should. 2. I should only see data on the listen socket when I make a new connection. What I see is data on the listen socket when I send data on the connected socket and with non-blocking even when I don't make a connection or send any data at all. 2. The really confusing thing is if I stop my USB and DSP threads it stops behaving like this and sees data on the correct sockets. In other words it works as it does on Windows so I have to assume this is the correct behaviour. 3. I've played around with trying to figure out exactly what it is in the other threads that causes the behaviour. I got as far as finding that only the DSP thead is required so that rules out misbehaving USB. Very oddly there is a loop that is creating some Json data (not very efficiently) as it's doing a lot of string concatenation. If I comment out this loop or reduce its iterations the exception slow down to the point where I just get 2 and then they stop. This points to something horrible going on. I can only hope I've done something stupid that I just happen to be getting away with on Windows. If it's a bug in the compiler or libraries I think I'm stuffed as I wouldn't know where to start. Regards bob On 23/12/2010 00:20, Heywood Floyd wrote: Hi Bob! My guess: You're listener is set to be non-blocking. That means that when you call listener.accept() it will return immediately with an SocketAcceptException, if there's no connection. And you're basically calling listener.accept() over and over again in an infinite loop. The following example shows it: import std.concurrency, std.stdio, std.conv, std.socket; void main() { ushort port = ; Socket listener = new TcpSocket; assert(listener.isAlive); listener.blocking = false; listener.bind(new InternetAddress(port)); listener.listen(10); writeln(Listening on port: , port); Socket sn; while(true){ try { writeln (Accepting); sn = listener.accept(); writeln(Connection from , sn.remoteAddress().toString(), established ); assert(sn.isAlive); assert(listener.isAlive); break; } catch(Exception e) { writeln(Error accepting: , e.toString() ); if(sn) sn.close(); } } writeln(end); } Running the example will print Error accepting: std.socket.SocketAcceptException: Unable to accept socket connection: Resource temporarily unavailable for ever. (Tested on Mac.) When a user connects to 127.0.0.1: (by for instance opening the URL in a browser) socket.accept _does_ return a connection and the program prints end. I don't know why the program doesn't do this on Windows. As far as I can tell the endless exceptions _is_ the correct behaviour, right? Anyway, if you comment out the the line listener.blocking = false; in 'listener.d', does it work as intended then? In the example above this will cause the listener.accept()-call to actually wait until it gets a connection, and thus not spew out all the exceptions. BR /heywood Bob Cowdery Wrote:
Re: double - double[]... | feature or bug?
bearophile wrote: spir: While I understand some may consider this a nice feature, for me this is an enormous bug. A great way toward code obfuscation. I like D among other reasons because it's rather clear compared to other languages of the family. The main problem here is that I have never felt the need of that feature, so for me it's useless. Has Walter added it after a good number of people have asked for this feature? Has any one here needed it? Bye, bearophile I'm almost certain that the behaviour is not intentional.
Do we already have full compile time / runtime separation?
Hello, I've been trying to manage this on my own for like 2 days but still couldn't do that, and because my brain just suddenly turned-off, I would ask You for some guidance. The thing is: I'd like to make some kind of messaging in my application. So, there is - interface Msg - classes that are implementing it, i.e. MsgWindowClose - interface Provider for message publishers, i.e. MsgProviderWindowClose - interface Listener for message subscibers i.e. MsgListenerWindowClose - interface Handler for message filters i.e. bool MsgHandlerWindowClose.log() - interface Mediator for message passing between program classes, i.e. MsgMediatorDMultiThreading() - which is using D messages btw. Nothing related to D so far. Key thing is, that most of this Msg objects will be really generic, so I'm building object generator, i.e MsgProviderGen!WindowClose: code template MsgProviderGen(string MSG, Args...) { const char[] MsgProviderGen = class MsgProvider~MSG~ : MsgProvider { ~override Msg~MSG~ getMsg() { ~return new Msg~MSG~; ~} ~}; } /code Which will be bigger of course. Then, for standard and generic messages i can easily define: code private import msg.msg, msg.provider.gen, msg.handler.gen; class MsgWindowClose : Msg { } mixin(MsgProviderGen!WindowClose); /code So far so good, but then if I'd like to add codemixin(immutable uint id=~static_id~;)/code for each *class* (not object) I got a PROBLEM: Each compile-time variable has to be const, right? So I can't increment my `static_id` each time I build a class (how many times template has generated provider/listener of this type). This wont let me statically check if each listener has its provider. Surely it's not the only use of this feature, For loosen coupling, I'd wish to add function that statically returns array of Msg defined in module. It isn't an option without compile-time variables too. Is it something about undefined module initialization? Or maybe there is any way to overcome this problems, since I'm still new @ D language. Ps. How to make associative array of dynamic arrays? codeMsgHandler[hash_t][] _handlers = new MsgHandler[hash_t][];/code wont work. Thanks for help, Mariusz Gliwiński signature.asc Description: This is a digitally signed message part.
Re: double - double[]... | feature or bug?
On Thu, 23 Dec 2010 12:34:45 -0500, Don nos...@nospam.com wrote: bearophile wrote: spir: While I understand some may consider this a nice feature, for me this is an enormous bug. A great way toward code obfuscation. I like D among other reasons because it's rather clear compared to other languages of the family. The main problem here is that I have never felt the need of that feature, so for me it's useless. Has Walter added it after a good number of people have asked for this feature? Has any one here needed it? Bye, bearophile I'm almost certain that the behaviour is not intentional. From http://www.digitalmars.com/d/2.0/function.html : Typesafe variadic functions are used when the variable argument portion of the arguments are used to construct an array or class object . (emphasis added) And it goes on to show a similar example as to what has been discussed here. I think it's intentional, and I agree that I've never used or thought gee, I wish D did this. I wouldn't be sorry to see it go. In fact, I'd advocate for getting rid of it. It creates a hidden allocation, which I'm very much against. -Steve
Vim: Anyone using taglist.vim with D?
I know there's a few people here that use Vim, so has anyone succesfully used the taglist.vim plugin with D? Ctags work for me (on XP), but I can't get taglist to work with D. It does work with C/CPP files, but it seems to ignore D files. I'm asking before I try to modify the plugin, because either I have ctags set up wrong for D, or taglist simply won't work with D files, and there's a function in there called function! s:Tlist_Skip_File(filename, ftype) which looks tempting to modify. I can use ctags on D files already but not with the taglist plugin itself. P.S. I've uploaded a new Ctags Windows binary on the prowiki page, and added .di as another D file extension (i'll put up the patch later). I'm not sure how up-to-date the D2 support is in that 5.8 patch, for example some template functions are ignored in ctags. So I might update these soon. http://prowiki.org/wiki4d/wiki.cgi?ReferenceForTools/ExuberantCtags
Re: DMD2 out parameters
Pete wrote: Ok, i've done some more investigating and it appears that in DMD2 a float NaN is 0x7FE0 (in dword format) but when it initialises a float 'out' parameter it initialises it with 0x7FA0H. This causes an FPU trap which is where the time is going. This looks like a bug to me. Can anyone confirm? Thanks. Yes, it sounds like a NaN-related peformance issue. Note, though, that the slowdown you experience is processor-model specific. It's a penalty of ~250 cycles on a Pentium 4 with x87 instructions, but zero cycles on many other processors. (in fact, it's also zero cycles with SSE on Pentium 4!).
Re: DMD2 out parameters
On 12/23/2010 12:19 PM, Pete wrote: Ok, i've done some more investigating and it appears that in DMD2 a float NaN is 0x7FE0 (in dword format) but when it initialises a float 'out' parameter it initialises it with 0x7FA0H. This causes an FPU trap which is where the time is going. This looks like a bug to me. Can anyone confirm? Thanks. I just did a test with DMD 2.051 on Linux void F1(ref float a) { a++; } void F2(out float a) { a++; } void main() { float a; float b; F1(a); F2(b); } And ASM: 080490e4 _D3out2F1FKfZv: 80490e4: 55 push ebp 80490e5: 8b ec movebp,esp 80490e7: 83 ec 04subesp,0x4 80490ea: d9 e8 fld1 80490ec: d8 00 fadd DWORD PTR [eax] 80490ee: d9 18 fstp DWORD PTR [eax] 80490f0: c9 leave 80490f1: c3 ret 80490f2: 90 nop 80490f3: 90 nop 080490f4 _D3out2F2FJfZv: 80490f4: 55 push ebp 80490f5: 8b ec movebp,esp 80490f7: 83 ec 04subesp,0x4 80490fa: d9 05 00 81 05 08 fldDWORD PTR ds:0x8058100 8049100: d9 18 fstp DWORD PTR [eax] 8049102: d9 e8 fld1 8049104: d8 00 fadd DWORD PTR [eax] 8049106: d9 18 fstp DWORD PTR [eax] 8049108: c9 leave 8049109: c3 ret 804910a: 90 nop 804910b: 90 nop 0804910c _Dmain: 804910c: 55 push ebp 804910d: 8b ec movebp,esp 804910f: 83 ec 08subesp,0x8 8049112: d9 05 00 81 05 08 fldDWORD PTR ds:0x8058100 8049118: d9 5d f8fstp DWORD PTR [ebp-0x8] 804911b: d9 05 00 81 05 08 fldDWORD PTR ds:0x8058100 8049121: d9 5d fcfstp DWORD PTR [ebp-0x4] 8049124: 8d 45 f8leaeax,[ebp-0x8] 8049127: e8 b8 ff ff ff call 80490e4 _D3out2F1FKfZv 804912c: 8d 45 fcleaeax,[ebp-0x4] 804912f: e8 c0 ff ff ff call 80490f4 _D3out2F2FJfZv 8049134: 31 c0 xoreax,eax 8049136: c9 leave 8049137: c3 ret And 0x8058100 is 0x7FA0. As you can see out doesn't force the loading and storing of a different NaN value. Of course, maybe the compiler should skip initializing a float that gets passed into a routine as an out parameter as its first use. E.g. float a; a = 1.0; wouldn't generate two separate assignments.
Re: import from subdir
On 12/23/2010 1:38 PM, spir wrote: Is there a way to import util data from test? I think this should work: util.d first line: module util; data.d first line module data.data; test.d first lines module test.test; import util; import data.data; Disclaimer: I don't know if directory names and file names may overlap, maybe you should rename them.
Re: Undefined references when linking to C library
Jonathan M Davis wrote: Did you wrap the C declarations in an extern(C) block? Without that, it's going to think that your variables are D variables not C variables. The same goes for any functions - _especially_ for the functions. In fact, a large portion of - in not all of - your gpm.d file should likely be in extern(C). I tried extern (C) for the whole module and individually. I get the following error: /usr/lib64/gcc/x86_64-suse-linux/4.5/../../../../x86_64-suse-linux/bin/ld: _gpm_arg: TLS reference in gev.o mismatches non-TLS definition in /usr/lib64/gcc/x86_64-suse-linux/4.5/../../../../lib/libgpm.so section .data /usr/lib64/gcc/x86_64-suse-linux/4.5/../../../../lib/libgpm.so: could not read symbols: Bad value collect2: ld returned 1 exit status --- errorlevel 1 Is this a 32/64 bit issue? I have both versions of libgpm installed. Those file paths are obtuse, but they do point to the 32 bit libraries. I've successfully compiled other programs that use C libraries such as SDL and OpenGL (both via the Derelict2 modules). I also tried htod and compared the output with what I wrote. The differences are inconsequential. Thank you, - Peter Federighi
Re: Memory allocation faile on string concat
On Thu, 11 Nov 2010 07:42:36 -0500, Steven Schveighoffer schvei...@yahoo.com wrote: On Wed, 10 Nov 2010 23:33:58 -0500, Xie xiema...@gmail.com wrote: OK, this actually makes sense to me. It's a manifestation of this issue: http://d.puremagic.com/issues/show_bug.cgi?id=3929 I'm think - it's truth but not at all. Sorry, but i'm give incomplete data. My example run fine, when benchmark(1), (2), but not 10. This means, that memory not collected _between_ calls. Yes, this is what the bug report is about -- the memory is not collected even though there are no references left, because the cache used to speed up appending still has a reference. OK, so I have actually implemented a fix for bug 3929. Essentially, the cache will no longer hold hostage the data that was being appended. However, I have found that this *still* doesn't fix the problem. Even though the cache no longer holds the memory as allocated, the example does something that we can't really get around. When you allocate a very very large block of data (in this case 1/20 of your address space), it is inevitable with a conservative GC that this data never gets collected. Why? Because the stack is scanned conservatively, and the chances that some 4-bytes of data looks like it points to the space is very high. So in order to fix this, we would not only need precise heap scanning, but *also* precise stack scanning, and precise TLS/global data scanning. But I'm still going to check this in to fix the bug, because it does seem to help with smaller blocks. I'll post more on the main newsgroup on this issue. -Steve
Re: Do we already have full compile time / runtime separation?
On Thursday 23 December 2010 01:11:40 Mariusz Gliwiński wrote: Hello, I've been trying to manage this on my own for like 2 days but still couldn't do that, and because my brain just suddenly turned-off, I would ask You for some guidance. The thing is: I'd like to make some kind of messaging in my application. So, there is - interface Msg - classes that are implementing it, i.e. MsgWindowClose - interface Provider for message publishers, i.e. MsgProviderWindowClose - interface Listener for message subscibers i.e. MsgListenerWindowClose - interface Handler for message filters i.e. bool MsgHandlerWindowClose.log() - interface Mediator for message passing between program classes, i.e. MsgMediatorDMultiThreading() - which is using D messages btw. Nothing related to D so far. Key thing is, that most of this Msg objects will be really generic, so I'm building object generator, i.e MsgProviderGen!WindowClose: code template MsgProviderGen(string MSG, Args...) { const char[] MsgProviderGen = class MsgProvider~MSG~ : MsgProvider { ~override Msg~MSG~ getMsg() { ~return new Msg~MSG~; ~} ~}; } /code Which will be bigger of course. Then, for standard and generic messages i can easily define: code private import msg.msg, msg.provider.gen, msg.handler.gen; class MsgWindowClose : Msg { } mixin(MsgProviderGen!WindowClose); /code So far so good, but then if I'd like to add codemixin(immutable uint id=~static_id~;)/code for each *class* (not object) I got a PROBLEM: Each compile-time variable has to be const, right? So I can't increment my `static_id` each time I build a class (how many times template has generated provider/listener of this type). This wont let me statically check if each listener has its provider. Surely it's not the only use of this feature, For loosen coupling, I'd wish to add function that statically returns array of Msg defined in module. It isn't an option without compile-time variables too. Is it something about undefined module initialization? Or maybe there is any way to overcome this problems, since I'm still new @ D language. Ps. How to make associative array of dynamic arrays? codeMsgHandler[hash_t][] _handlers = new MsgHandler[hash_t][];/code wont work. You're mixing up several concepts, which complicates things a fair bit. When directly initializing static variables or member variables, the values used to initialize those variables must not depend on ordering. That generally means that the values used to initialize such variables must either come from constants, templates, or CTFE. So, auto a = 7; auto b = a; is not legal, because a is not constant. If it were immutable a = 7; auto b = a; then it's legal. However, note that b itself is not const, immutable, or an enum. It's fully mutable. Other ways to initialize such variables would be through eponymous templates and calling functions via CTFE (compile-time function evaluation): template add(int a, int b) { enum add = a + b; } double multiply(double a, double b) { return a * b; } auto a = add!(7, 5); auto b = multiply(2, 3); Enforcing the lack of ordering in direct initialization for static variables and member variables makes it so that you avoid bugs like you get in some languages when you try to do something like auto a = b; auto b = 7; and a ends up being garbage because the variables are being initialized in order and b hasn't been initialized yet. It also makes it potentially much faster to compile static and member variables, because they can actually be compiled in parallel instead of enforcing an ordering to them. And, of course, if you did something like auto a = b; auto b = a; the circular dependency would screw you. If you have such ordering issues or if you need such variables to be mutable and yet able be initialized from one another, you need to use static constructors (which also work on immutable variables as long as you initialize them only once, though enums must still be known at compile time, so it doesn't work for them). Now, for templates, the template itself depends on the values/types of its parameters. It's pure code generation. A classic example would be something like struct Pair(T, U) { T first; U second; } When you declare Pair!(int, float), the compiler creates code similar to struct Pair!(int, float) { int first; float second; } If you declared Pair!(double, double), then you'd get a second Pair struct type generated. Because code is being generated like this, the template parameters - be they types or values - must be known at compile time. So, the rules for what can be passed as a template argument are essentially the same as what can be used to initialize a static or member variable directly. Now, with string mixins, you are also generating code.
Re: import from subdir
On Thursday 23 December 2010 11:30:40 CrypticMetaphor wrote: On 12/23/2010 1:38 PM, spir wrote: Is there a way to import util data from test? I think this should work: util.d first line: module util; data.d first line module data.data; test.d first lines module test.test; import util; import data.data; Disclaimer: I don't know if directory names and file names may overlap, maybe you should rename them. That only works if test/test.d is the module test.test rather than test, and he's trying to compile from the parent directory rather than the test directory. - Jonathan M Davis
Re: Vim: Anyone using taglist.vim with D?
Got it working! I just needed to create an extra variable for taglists. I'm using this: let tlist_d_settings='d;c:classes;d:macro definitions;e:enumerators (values inside an enumeration);f:function definitions;g:enumeration names;l:local variables [off];m:class, struct, and union members;M:module;n:namespaces;p:function prototypes [off];s:structure names;t:typedefs;T:templates;u:union names;v:variable definitions;x:external and forward variable declarations [off];X:mixin;V:conditional compilation' You can choose your own from the list ctags gives you with: ctags --list-kinds=d And more docs here: http://vim-taglist.sourceforge.net/extend.html I'll add this to prowiki. On 12/23/10, Andrej Mitrovic n...@none.none wrote: I know there's a few people here that use Vim, so has anyone succesfully used the taglist.vim plugin with D? Ctags work for me (on XP), but I can't get taglist to work with D. It does work with C/CPP files, but it seems to ignore D files. I'm asking before I try to modify the plugin, because either I have ctags set up wrong for D, or taglist simply won't work with D files, and there's a function in there called function! s:Tlist_Skip_File(filename, ftype) which looks tempting to modify. I can use ctags on D files already but not with the taglist plugin itself. P.S. I've uploaded a new Ctags Windows binary on the prowiki page, and added .di as another D file extension (i'll put up the patch later). I'm not sure how up-to-date the D2 support is in that 5.8 patch, for example some template functions are ignored in ctags. So I might update these soon. http://prowiki.org/wiki4d/wiki.cgi?ReferenceForTools/ExuberantCtags
Re: Undefined references when linking to C library
On Thursday 23 December 2010 11:38:28 Peter Federighi wrote: Jonathan M Davis wrote: Did you wrap the C declarations in an extern(C) block? Without that, it's going to think that your variables are D variables not C variables. The same goes for any functions - _especially_ for the functions. In fact, a large portion of - in not all of - your gpm.d file should likely be in extern(C). I tried extern (C) for the whole module and individually. I get the following error: /usr/lib64/gcc/x86_64-suse-linux/4.5/../../../../x86_64-suse-linux/bin/ld: _gpm_arg: TLS reference in gev.o mismatches non-TLS definition in /usr/lib64/gcc/x86_64-suse-linux/4.5/../../../../lib/libgpm.so section .data /usr/lib64/gcc/x86_64-suse-linux/4.5/../../../../lib/libgpm.so: could not read symbols: Bad value collect2: ld returned 1 exit status --- errorlevel 1 Is this a 32/64 bit issue? I have both versions of libgpm installed. Those file paths are obtuse, but they do point to the 32 bit libraries. I've successfully compiled other programs that use C libraries such as SDL and OpenGL (both via the Derelict2 modules). I also tried htod and compared the output with what I wrote. The differences are inconsequential. Yeah. It looks like the compiler is finding the 64-bit versions rather than the 32-bit versions. How to fix that will likely depend on the libraries in question and on how your system is set up. Obviously, a 32-bit chroot environment would fix the problem, but that's also obviously not a pleasant, or even necessarily simple, solution. I'm not really all that well-versed in dealing with linking issues like this, but I'd say that either the compiler is just not finding the 32-bit versions, because of a messed up or missing path, or you need to be linking separately because you're on a 64-bit system (which I don't _think_ is the case, but it might be). Regardless, you can try compiling all of the code with -c and then linking it with gcc directly (probably with -m32). Unfortunately, while I do run a 64-bit environment, due to problems with Arch and multilib systems, I've generally had to run dmd in a chrooted environment, and you don't have to deal with the 32-bit vs 64-bit issues with that, so I don't have much experience with this sort of problem. Regardless, I'll be very glad when the 64-bit port of dmd is completed. - Jonathan M Davis
Re: Undefined references when linking to C library
Peter Federighi wrote: Jonathan M Davis wrote: Did you wrap the C declarations in an extern(C) block? Without that, it's going to think that your variables are D variables not C variables. The same goes for any functions - _especially_ for the functions. In fact, a large portion of - in not all of - your gpm.d file should likely be in extern(C). I tried extern (C) for the whole module and individually. I get the following error: /usr/lib64/gcc/x86_64-suse-linux/4.5/../../../../x86_64-suse-linux/bin/ld: _gpm_arg: TLS reference in gev.o mismatches non-TLS definition in /usr/lib64/gcc/x86_64-suse-linux/4.5/../../../../lib/libgpm.so section .data /usr/lib64/gcc/x86_64-suse-linux/4.5/../../../../lib/libgpm.so: could not read symbols: Bad value collect2: ld returned 1 exit status --- errorlevel 1 Is this a 32/64 bit issue? I have both versions of libgpm installed. Those file paths are obtuse, but they do point to the 32 bit libraries. I've successfully compiled other programs that use C libraries such as SDL and OpenGL (both via the Derelict2 modules). I think gpm_zerobased, _bpm_buf and _gpm_arg should be declared __gshared. Jerome -- mailto:jeber...@free.fr http://jeberger.free.fr Jabber: jeber...@jabber.fr signature.asc Description: OpenPGP digital signature
Re: [D1] type of type
Should have been this: void func(type t){ new t(); }
Re: DMD2 out parameters
I noticed this on an Intel Core 2. I skipped the pentium 4 generation :)
Re: Undefined references when linking to C library
On 23.12.2010 20:38, Peter Federighi wrote: Jonathan M Davis wrote: Did you wrap the C declarations in an extern(C) block? Without that, it's going to think that your variables are D variables not C variables. The same goes for any functions - _especially_ for the functions. In fact, a large portion of - in not all of - your gpm.d file should likely be in extern(C). I tried extern (C) for the whole module and individually. I get the following error: /usr/lib64/gcc/x86_64-suse-linux/4.5/../../../../x86_64-suse-linux/bin/ld: _gpm_arg: TLS reference in gev.o mismatches non-TLS definition in /usr/lib64/gcc/x86_64-suse-linux/4.5/../../../../lib/libgpm.so section .data /usr/lib64/gcc/x86_64-suse-linux/4.5/../../../../lib/libgpm.so: could not read symbols: Bad value collect2: ld returned 1 exit status --- errorlevel 1 Is this a 32/64 bit issue? I have both versions of libgpm installed. Those file paths are obtuse, but they do point to the 32 bit libraries. I've successfully compiled other programs that use C libraries such as SDL and OpenGL (both via the Derelict2 modules). I also tried htod and compared the output with what I wrote. The differences are inconsequential. Thank you, - Peter Federighi I've had simmilar issue a few days ago. The problem is that global values from C should be marked shared in D extern int val; - extern (C) shared int val; or maybe __gshared. Both makes linking stage finishes with success.
Re: Undefined references when linking to C library
wrzosk wrote: I've had simmilar issue a few days ago. The problem is that global values from C should be marked shared in D extern int val; - extern (C) shared int val; or maybe __gshared. Both makes linking stage finishes with success. Jerome M. Berger wrote: I think gpm_zerobased, _bpm_buf and _gpm_arg should be declared __gshared. Indeed. So I added a bunch of __gshareds to all the variables and it compiles and links. Yah! I just have to remember to declare handler functions with extern (C), otherwise the program will segfault once the handler returns. Where should I post/upload the files that I converted? There are a whole two of them: One is gpm.h which is specific to libgpm. The other is paths.h which I was surprised to find not already available. I would assume that it should be available as std.c.linux.paths or core.sys.posix.paths. Also, should the files end with .d or .di I may be the only person who wants to use libgpm with D, but I figure it should be available just in case. Thank you all for your help. - Peter Federighi
Re: import from subdir
On Thu, 23 Dec 2010 12:54:42 -0800 Jonathan M Davis jmdavisp...@gmx.com wrote: What you're trying to do is pretty abnormal really, as far as your average module goes. I assume that you're writing a test app which needs access to the main body of code and are trying to find a way to point it to that code without mixing the two. What is then abnormal in having test modules in their own dir? And indeed they need to import the module(s) they're supposed to test (and possibly ordinary and test data from another dir). AFAIK, this is very ordinary lib structuration for the sake of clarity. Dunno. The normal way to deal with that would be -I. The same goes for C++ actually. Not to mention, you probably don't want your tests to rely on where they are on disk in comparison to the rest of your code. If you later want to change where you put your test code, it could be a big hassle to have to go change all of your imports. Just use -I. It makes your test code properly portable and is really the intended way to do the sort of thing that you're trying to do. Hem, I do not find a hassle to change one a few import once if ever I move a test module in the dir tree. But I find very unconvenient to have different compile/link command lines for every module just because of the lack of an importing syntax, requiring the use of -I. Instead of a command-line option, I would prefere to write it down once and for in the module itself. Maybe we could have something like pathlevel 2; saying that (when an imported module is not found) the indicated path is to be understood as relative to 2 dir levels higher (which would probably be the root of the lib). By the way, when I write import data.foo, the language actually searches and inside /data (relative to the current module's dir) and find foo.d there. (Even if the module is not explicitely named at all.) So, there is still an implicite or default relationship between dir tree structure and module denomination. Or do I misinterpret your words? Denis -- -- -- -- -- -- -- vit esse estrany ☣ spir.wikidot.com
Re: import from subdir
On Thursday 23 December 2010 16:42:15 spir wrote: On Thu, 23 Dec 2010 12:54:42 -0800 Jonathan M Davis jmdavisp...@gmx.com wrote: What you're trying to do is pretty abnormal really, as far as your average module goes. I assume that you're writing a test app which needs access to the main body of code and are trying to find a way to point it to that code without mixing the two. What is then abnormal in having test modules in their own dir? And indeed they need to import the module(s) they're supposed to test (and possibly ordinary and test data from another dir). AFAIK, this is very ordinary lib structuration for the sake of clarity. Dunno. What is abnormal is having your test code rely where your normal code is on disk. Also, depending on what you're doing for testing, normally you'd just have the unit tests alongside your normal code and do a unittest build to test your code. So, you wouldn't even need separate test code unless you're doing something more exotic that you don't want in your unit tests. The normal way to deal with that would be -I. The same goes for C++ actually. Not to mention, you probably don't want your tests to rely on where they are on disk in comparison to the rest of your code. If you later want to change where you put your test code, it could be a big hassle to have to go change all of your imports. Just use -I. It makes your test code properly portable and is really the intended way to do the sort of thing that you're trying to do. Hem, I do not find a hassle to change one a few import once if ever I move a test module in the dir tree. But I find very unconvenient to have different compile/link command lines for every module just because of the lack of an importing syntax, requiring the use of -I. Instead of a command-line option, I would prefere to write it down once and for in the module itself. Maybe we could have something like pathlevel 2; saying that (when an imported module is not found) the indicated path is to be understood as relative to 2 dir levels higher (which would probably be the root of the lib). By the way, when I write import data.foo, the language actually searches and inside /data (relative to the current module's dir) and find foo.d there. (Even if the module is not explicitely named at all.) So, there is still an implicite or default relationship between dir tree structure and module denomination. Or do I misinterpret your words? You misunderstand. From the module's perspective, import foo.bar; imports a module with the name foo.bar. It knows that bar is in the foo package, so unless the module doing the importing is in the foo package, it can't access the package-restricted functions and types from foo.bar or any other module in foo. It knows that bar is the module. But it doesn't care at all about what that means for files on disk. Consider the fact that you can have this directory structure: dir/dir1/foo/bar.d dir/dir2/dir3/hello/world.d dir/dir2/dir3/foo/silly.d where you're compiling from dir/dir2/dir3 and have -I../../dir1/. bar.d and silly.d are considered to be in the same package in spite of the fact that the fact that they're in different directories. When hello.world imports foo.bar, it doesn't care that it's not in the same directory as foo.silly. If foo.silly calls a package-restricted function in foo.bar, it's allowed to because they're in the same package, but it doesn't care that they're not in the same directory. The directory structure relates to the package hierarchy. The compiler finds files using that structure/hierarchy. It knows that if a module is importing foo.bar, that there is a directory foo either in the directory where compilation is taking place or in one of the directories given by the -I flag, and it knows that bar.d (or bar.di) will be in the foo directory. If there are multiple such directories (because of the -I flag being used), then it knows that bar.d is in one of them (if it were in more than one, then there would be an ambiguity error). The package hiercharcy tells the compiler where the source files are. However, the imports themselves don't care at all about the directory structure. As shown in the example above, you could have each module in a package in a different directory as long as it was in the appropriate place in the directory structure given all of the -I flags being used. So, importing has no concept of directories or files - only packages and modules. The compiler is able to translate that to directories and files, but the imports don't care about it. From the language's perspective, it would be perfectly possible to change it so that all files were always in the same directory but used dots to separate packages and modules: dir/dir1/foo.bar.d dir/dir2/dir3/hello.world.d dir/dir2/dir3/foo.silly.d Now, no compiler is going to function that way, but conceptually, it could. So, trying to use .. and the like in
TDPL dictionary example - error
Greetings, I just joined here, so sorry if this has been posted before. I'm reading TDPL and the example on page 8 doesn't compile. I'm using the latest GDC with GCC 4.4.5. I've checked the errata, but nothing for this error. import std.stdio; import std.string; void main(){ size_t[char[]] dictionary; foreach(line; stdin.byLine()){ foreach(word; splitter(strip(line))){ if(word in dictionary) continue; auto newID = dictionary.length; dictionary[word] = newID; writeln(newID, '\t', word); } } //writeln(dictionary.length); } This is the error: dictionary.d:12: Error: associative arrays can only be assigned values with immutable keys, not char[] If i use immutable keys, it works, but it defeats the purpose. So what's wrong with the code?
Re: TDPL dictionary example - error
Friday 24 December 2010 @ 06:24:34 Caligo: Greetings, I just joined here, so sorry if this has been posted before. I'm reading TDPL and the example on page 8 doesn't compile. I'm using the latest GDC with GCC 4.4.5. I've checked the errata, but nothing for this error. import std.stdio; import std.string; void main(){ size_t[char[]] dictionary; foreach(line; stdin.byLine()){ foreach(word; splitter(strip(line))){ if(word in dictionary) continue; auto newID = dictionary.length; dictionary[word] = newID; writeln(newID, '\t', word); } } //writeln(dictionary.length); } This is the error: dictionary.d:12: Error: associative arrays can only be assigned values with immutable keys, not char[] If i use immutable keys, it works, but it defeats the purpose. So what's wrong with the code? It works for DMD, I think it's a GDC bug (i'm new in D too, so i might be wrong). Keep in mind that GDC implements only D 1.0 and book has D 2.0 code. Sincerely, Mariusz Gliwiński signature.asc Description: This is a digitally signed message part.
Re: TDPL dictionary example - error
No, GDC supports D1 and D2. Version 2.051 I think. I know I've compiled mine with D2 support. 2010/12/24 Mariusz Gliwiński alienballa...@gmail.com Friday 24 December 2010 @ 06:24:34 Caligo: Greetings, I just joined here, so sorry if this has been posted before. I'm reading TDPL and the example on page 8 doesn't compile. I'm using the latest GDC with GCC 4.4.5. I've checked the errata, but nothing for this error. import std.stdio; import std.string; void main(){ size_t[char[]] dictionary; foreach(line; stdin.byLine()){ foreach(word; splitter(strip(line))){ if(word in dictionary) continue; auto newID = dictionary.length; dictionary[word] = newID; writeln(newID, '\t', word); } } //writeln(dictionary.length); } This is the error: dictionary.d:12: Error: associative arrays can only be assigned values with immutable keys, not char[] If i use immutable keys, it works, but it defeats the purpose. So what's wrong with the code? It works for DMD, I think it's a GDC bug (i'm new in D too, so i might be wrong). Keep in mind that GDC implements only D 1.0 and book has D 2.0 code. Sincerely, Mariusz Gliwiński