Re: enum ubyte[] vs enum ubyte[3]
On Mon, 20 Dec 2010 10:26:16 +0100 Johannes Pfau s...@example.com wrote: Hi, I'm currently patching Ragel (http://www.complang.org/ragel/) to generate D2 compatible code. Interesting. Ragel-generated code works fine for me in D2. I suppose it mostly uses such a restricted C-like subset of language that it didn't change much from D1 to D2. But if you are going to patch it, please make it add extra {} around action code! The thing is that when there is a label before {} block (and in ragel generated code I saw it's always so) the block isn't considered as a new scope which causes problems when you have local variables declaration inside actions. Anyway, good luck with whatever you plan :) Ragel is cool. Right now it creates output like this for static arrays: enum ubyte[] _parseResponseLine_key_offsets = [ 0, 0, 17, 18, 37, 41, 42, 44, 50, 51, 57, 58, 78, 98, 118, 136, 138, 141, 143, 146, 148, 150, 152, 153, 159, 160, 160, 162, 164 ]; Making it output enum ubyte[30] would be more complicated, so I wonder if there's a difference between enum ubyte[] and enum ubyte[30]? One is fixed size array and other is dynamic. Honestly I doubt that it matters for code generated by Ragel, since this is constant and won't be passed around. If it's harder to make it fixed-size then don't bother. -- Nick Voronin elfy...@gmail.com
Re: enum ubyte[] vs enum ubyte[3]
On Mon, 20 Dec 2010 17:17:05 +0100 Johannes Pfau s...@example.com wrote: But if you are going to patch it, please make it add extra {} around action code! The thing is that when there is a label before {} block (and in ragel generated code I saw it's always so) the block isn't considered as a new scope which causes problems when you have local variables declaration inside actions. You mean like this code: - tr15: #line 228 jpf/http/parser.rl { if(start != p) { key = line[(start - line.ptr) .. (p - line.ptr)]; } } - should become: ? - tr15: #line 228 jpf/http/parser.rl {{ if(start != p) { key = line[(start - line.ptr) .. (p - line.ptr)]; } }} - Yes. This way it becomes a scope which is kind of what one would expect from it. One is fixed size array and other is dynamic. Honestly I doubt that it matters for code generated by Ragel, since this is constant and won't be passed around. If it's harder to make it fixed-size then don't bother. Could a dynamic array cause heap allocations, even if it's data is never changed? If not, dynamic arrays would work fine. Sorry, I can't provide reliable information on what can happen in general, but right now there is no difference in produced code accessing elements of enum ubyte[] and enum ubyte[30]. In both cases constants are directly embedded in code. In fact as long as you only access its elements (no passing array as an argument, no assignment to another variable and no accessing .ptr) there is no array object at all. If you do -- new object is created every time you do. I believe Ragel doesn't generate code which passes tables around, so it doesn't matter. -- Nick Voronin elfy...@gmail.com
Re: Classes or stucts :: Newbie
On Mon, 20 Dec 2010 05:43:08 -0500 bearophile bearophileh...@lycos.com wrote: Nick Voronin: Here is where we diverge. Choosing struct vs class on criteria of their placement makes no sense to me. In D you use a class if you want inheritance or when you (often) need reference semantics, and you use a struct when you need a little value passed around by value or when you want a simple form of RAII or when you want to implement something manually (like using PIMPL), or when you want max performance (and you manage structs by pointer, you may even put a tag inside the stuct or the pointer and implement manually some kind of inheritance). With structs you have a literal syntax, postblits, in-place allocation, and you are free to use align() too. Well said. Plenty of differences there more important than stack/heap allocation. -- Nick Voronin elfy...@gmail.com
Re: sleepy receiveTimeout?
On Sat, 18 Dec 2010 23:19:47 +0100 Joost 't Hart joost.t.h...@planet.nl wrote: Quoting the documentation: /Suspends the calling thread for at least the supplied period./ What does at least mean here? Is there also an at most? I do not want my friend to end up in cyberspace. :-) Nope, there isn't :) In ordinary multitasking environment there is no guarantee on upper bound. -- Nick Voronin elfy...@gmail.com
Re: sleepy receiveTimeout?
On Sun, 19 Dec 2010 10:50:08 +0100 Joost 't Hart joost.t.h...@planet.nl wrote: Quoting the documentation: /Suspends the calling thread for at least the supplied period./ What does at least mean here? Is there also an at most? I do not want my friend to end up in cyberspace. :-) Nope, there isn't :) In ordinary multitasking environment there is no guarantee on upper bound. Surely got that bit, but I guess it makes sense to refer a bit more to some good old thread state names: After (exactly!) the given period of suspension the thread returns into ready state. When (if ever) it will become the running thread again depends ... This all nice in theory, but are you sure that every sleep() causes setting of hardware timer? In every OS? In every minor version of OS even? If not (and I'm pretty sure it's not so), then you need to add more details. All about how scheduler works. Or this precise talk on what happen after time is up would just mislead people. Aside from the fact that sometime after time is up thread would become runnable again (which is really obvious, no?) there is nothing to say. -- Nick Voronin elfy...@gmail.com
Re: Classes or stucts :: Newbie
On Mon, 20 Dec 2010 07:00:31 -0800 David Currie curri...@iinet.net.au wrote: Can a class be instantiated on the stack ? Yes, check std.conv.emplace http://www.digitalmars.com/d/2.0/phobos/std_conv.html#emplace and alloca() I don't know details about interaction of such objects with GC though. Also there is scarcely documented storage class scope, which for class objects means that they will be destroyed upon scope exit, but also currently results in that object itself will be placed on the stack, no memory in heap is allocated. C myC(3); // C++ syntax BUT is there a d equivalent It appears that D ASSUMES myC is really a myC*(in C++) Not exactly. All class objects have reference semantic, so when you declare variable of type C you really declare a reference. The reference is what you get from new, pass as parameters, etc. Will a struct do? structs on the contrary have value semantic, so when you declare struct variable you get the memory for struct allocated on stack or in data segment. When you pass or return structs -- you return or pass value, that is a copy of data. You may be also interested in the way dynamic arrays are handled, as arrays are value type, yet they hold a pointer to memory. This means that passing them as parameter or returning them does copy pointer and length, but actual data is stil shared until you do something which will force D to relocate it. All kind of not obvious implications here. Does a struct have a constructor (as opposed to an opcall?) Yes, and more. http://www.digitalmars.com/d/2.0/struct.html -- Nick Voronin elfy...@gmail.com
Re: Classes or stucts :: Newbie
On Sun, 19 Dec 2010 14:38:17 -0800 Jonathan M Davis jmdavisp...@gmx.com wrote: On Sunday 19 December 2010 14:26:19 bearophile wrote: Jonathan M Davis: There will be a library solution to do it, but again, it's unsafe. It can be safer if the compiler gives some help. For me it's one of the important unfinished parts of D. Whereas, I would argue that it's completely unnecessary. structs and classes serve different purposes. There is no need for scoped classes. They may perodically be useful, but on the whole, they're completely unnecessary. How do you define a need for scoped classes? I see two aspects there: first is having destructor called at known point rather than arbitrarily, second is performance. It looks perfectly reasonable for me to want to have first. Do you know why things which makes program act more deterministic are shunned from D? Does it really add so much to safety that it is worth reducing programmer's control? Second is irrelevant to types, if I want to speed up some code and can do it by placing things on stack rather than in heap -- what does it matter if it is class or struct or integer? We have alloca() anyway, so removing modifier won't save me from myself, just push me to more C-like code. Which kind of defeats the purpose of using D. The compiler can help, but it can't fix the problem any more that it can guarantee that a pointer to a local variable doesn't escape once you've passed it to another function. Absolutely. Yet we won't have library solution for pointers instead of language support (hopefully)? :) I think it all goes against being practical as an objective of the language. Safety is important but you don't achieve safety by means of making unsafe thing unconvenient and inefficient. If there is emplace() then there is no reason not to have scope storage class. At least looking from user's POV. I don't know how hard it is on the compiler. In _some_ circumstances, it can catch escaping pointers and references, but in the general case, it can't. In _general_ case there is no safety in D. With all low-level capabilities one can always defeat compiler. Removing intermediate-level safer (yet unsafe) capabilities arguabily gains nothing but frustration. I'm all for encouraging good practices, but this is different. -- Nick Voronin elfy...@gmail.com
Re: rdmd bug?
On Mon, 20 Dec 2010 01:24:02 +0100 CrypticMetaphor crypticmetapho...@gmail.com wrote: Anyway, the problem is, if I call rdmd from outside the folder in which the main source resides in, and main includes another file in that folder, I get an error. // If I'm in a shell, and I do this, I get an error: ...\projectfolderrdmd src\main.d src\main.d(2): Error: module test is in file 'test.d' which cannot be read import path[0] = C:\D\dmd2\windows\bin\..\..\src\phobos import path[1] = C:\D\dmd2\windows\bin\..\..\src\druntime\import Anyway, I want to be able to compile with rdmd from a different folder, is this a bug? or should I use a different tool? :-S *aahhh* Add -Ifullpath_to_projectfolder\src. It's the way it works IMHO, if you import something it must be relative to search path or to current dir. There may be a better way (replace current dir with the dir where source is, but it will take away control), but this works. There is a bug though, I can't make it work with -Irelative_path_to_src. Looks like .deps contain paths relative to where rdmd was ran, while dmd interprets them as paths relative to where .deps file is. -- Nick Voronin elfy...@gmail.com
Re: Classes or stucts :: Newbie
On Sun, 19 Dec 2010 17:26:20 -0800 Jonathan M Davis jmdavisp...@gmx.com wrote: On Sunday 19 December 2010 16:50:34 Nick Voronin wrote: On Sun, 19 Dec 2010 14:38:17 -0800 Jonathan M Davis jmdavisp...@gmx.com wrote: On Sunday 19 December 2010 14:26:19 bearophile wrote: Jonathan M Davis: There will be a library solution to do it, but again, it's unsafe. It can be safer if the compiler gives some help. For me it's one of the important unfinished parts of D. Whereas, I would argue that it's completely unnecessary. structs and classes serve different purposes. There is no need for scoped classes. They may perodically be useful, but on the whole, they're completely unnecessary. How do you define a need for scoped classes? I see two aspects there: first is having destructor called at known point rather than arbitrarily, second is performance. It looks perfectly reasonable for me to want to have first. Do you know why things which makes program act more deterministic are shunned from D? Does it really add so much to safety that it is worth reducing programmer's control? Then use a struct. Here is where we diverge. Choosing struct vs class on criteria of their placement makes no sense to me. Difference in default placement hardly matters at all, you can perfectly put structs in heap or in static segment yet still maintain same properties. It's those properties which matter when I choose one or another, not where it will reside in particular part of program. That's one of the reasons that they exist. And if you _really_ want to make sure that a class' destructor gets run, you can always use clear() (which is arguably an abomination in its own right). This is what I don't understand. Fine. structs are meant for stack, class for heap. Conceptually, anyway. Still there will be ways to put class on stack and struct in heap. And there is(will be) clear(). Now I do see benefit of scope storage. It looks clean, it is supported by compiler meaning reasonable level of protection against misuse, it is extremely effective. What are benefits of _not having_ it? -- Nick Voronin elfy...@gmail.com
Re: helpful runtime error messages
On Wed, 15 Dec 2010 13:28:56 +0300, spir denis.s...@gmail.com wrote: s...@o:~/prog/d$ dmd -ofprog -w -debug -unittest -L--export-dynamic prog.d s...@o:~/prog/d$ ./prog core.exception.rangeer...@prog(20): Range violation ./prog(_d_array_bounds+0x16) [0x807cad6] ./prog(_D4prog7__arrayZ+0x12) [0x807a54a] ./prog(_Dmain+0x38) [0x807a524] ./prog(extern (C) int rt.dmain2.main(int, char**)) [0x807cc76] ./prog(extern (C) int rt.dmain2.main(int, char**)) [0x807cbd0] ./prog(extern (C) int rt.dmain2.main(int, char**)) [0x807ccba] ./prog(extern (C) int rt.dmain2.main(int, char**)) [0x807cbd0] ./prog(main+0x96) [0x807cb76] /lib/tls/i686/cmov/libc.so.6(__libc_start_main+0xe6) [0x1ddbd6] ./prog() [0x807a401] Do you have (even) nicer error reports on some OS's or using some switches? Trass3r pointed this http://3d.benjamin-thaut.de/?p=15 recently. It prints line numbers on windows. It doesn't go as deep as stacktrace above though. Just core.exception.rangeer...@strace2(5): Range violation 00 strace2.d::5(16) _Dmain 01 extern (C) int rt.dmain2.main(int, char**) . void runMain() . 02 extern (C) int rt.dmain2.main(int, char**) . void runAll() . 03 main 04 mainCRTStartup 05 RegisterWaitForInputIdle -- Using Opera's revolutionary email client: http://www.opera.com/mail/
Re: rdmd executable location
try -of option. On Wed, 15 Dec 2010 21:59:32 +0300, CrypticMetaphor crypticmetapho...@gmail.com wrote: Hello, I'm having a bit of trouble with rdmd. rdmd puts the executable in a temp folder, even with the --build-only option. Maybe this is a silly question but, how can I compile with rdmd so I get the executable in the folder I am currently at? other info: I'm programming in Windows XP with dmd version 2.50 -- Using Opera's revolutionary email client: http://www.opera.com/mail/
Re: funny bug with input range interface and toString
On Mon, 13 Dec 2010 11:24:48 +0300, spir denis.s...@gmail.com wrote: I have a strange bug with an input range interface. Initially, I had a (rather big) struct called Text with loads of working unittests. When adding a range interface, noting worked anymore, any test ran into an infinite loop (the terminal writes pages of '[') ending with segfault. @property Text front () { return Text(this.stacks[this.rangeIndex]); } Um. There is recursion. front() of Text returns Text. formatValue iterates through Range, trying to format every element of it... but goes nowhere because Range.front never yields anything but itself typewise. After shrinking the bug's scope,I finally found it happens on simple writeln(text). Not so simple, with all underlying mess of templates :-D I suppose it's a bug that instantiation of formatValue for Range types there always tries to iterate manually, ignoring existing toString. void formatValue(Writer, T, Char)(Writer w, T val, ref FormatSpec!Char f) if ( ( is(T == struct) || is(T == union) ) !isInputRange!T) As you can see it even explicitly mention that default formatting for struct (which can use toString) not to be used for Ranges. I think it's wrong. https://bitbucket.org/denispir/denispir-d/changeset/39200b499fb9#chg-textbug.d. Note that the range interface itself works fine. btw, I wonder, how do you build it? I ended up with very long command line for dmd, as there was no makefile and jake/rdmd failed to produce anything ether. So, it seems that, in my case for any reason, introducing an input range lets D shortcut toString (and try to use what instead?). Look like a bug? Yup! Still, stack overflow is due to unconventional Range interface. -- Using Opera's revolutionary email client: http://www.opera.com/mail/
Re: funny bug with input range interface and toString
On Mon, 13 Dec 2010 21:43:33 +0300, spir denis.s...@gmail.com wrote: I use rdmd for quick testing (because it links automagically). compile: dmd -w -c filename.d build: rdmd -w -offilename -debug -unittest --build-only filename.d Thanks. I missed -of option. -- Using Opera's revolutionary email client: http://www.opera.com/mail/
overzealous pointsTo()
pointsTo() tries to check every member of anonymous union inside struct. import std.exception; union U { int i; string s; } struct S1 { int type; U u; } struct S2 { int type; union { int i; string s; } } void main() { S1 s1; s1.u.i = 0x7FFF_; S2 s2; s2.i = 0x7FFF_; assert(!pointsTo(s1, s1)); // pass, pointsTo does not look into union assert(!pointsTo(s2, s2)); // fails because pointsTo tries to check every member of anonymous union } IMHO it should ignore unions, anonymous or not, checking every member of them just doesn't make sense. -- Using Opera's revolutionary email client: http://www.opera.com/mail/
Re: overzealous pointsTo()
On Sun, 12 Dec 2010 22:36:03 +0300, Nick Voronin elfy...@gmail.com wrote: pointsTo() tries to check every member of anonymous union inside struct. alias this makes a passable workaround though. (I hope) :) union U { int i; string s; } struct S3 { int type; U u; alias u this; } void main() { S3 s3; s3.i = 0x7FFF_; assert(!pointsTo(s3, s3)); // pass } -- Using Opera's revolutionary email client: http://www.opera.com/mail/
Re: effect of a label on following block
On Mon, 15 Nov 2010 19:34:46 +0300, Ellery Newcomer ellery-newco...@utulsa.edu wrote: My gut feeling is that the if statement's behavior is wrong and the while statement's is correct, but it could go either way. I agree, I think case with 'when' works as specs say. No need for a rationale for what can be adequately explained as a compiler bug There is still correct but unexpected behaviour. I found this on bugtracker http://d.puremagic.com/issues/show_bug.cgi?id=199 The rationale was I don't want to change this because it could break existing code, and there doesn't seem to be a compelling reason to do so. Well. :( Please to report to bugzilla I'll report about if/while inconsistency. -- Using Opera's revolutionary email client: http://www.opera.com/mail/
effect of a label on following block
Hello. Consider this code void main() { l: { int v; } v = 5; // ok, v is defined } As I understand from D's grammar this behaviour is not a bug as LabeledStatement: Identifier : NoScopeStatement and NoScopeStatement in turn takes BlockStatement without creating new scope. It looks very unnatural for me though. Especially when label goes before ThenStatement if(1) l1:{ int v; } v = 5; it works as above, yet label after 'while' while(1) l1:{ int v; } v = 5; // error, v is undefined has no such effect, even if ThenStatement is just another ScopeStatement. I don't understand this difference. Any rationale behind this? -- Using Opera's revolutionary email client: http://www.opera.com/mail/
readf
Hello. I'm new to D and I stumbled upon something strange about readf while writing some test code. The code: import std.stream; import std.stdio; int main(char[][] args) { string input = 2abc; auto memstream = new TArrayStream!(string)(input); int x; memstream.readf(%d, x); char[] s = memstream.readString(x); writefln(%d:%s, x, s); // expected 2:ab, writes 2:bc. return 0; } After looking in stream.d I can understand why it is working in unexpected way (readf uses ungetc() which has no effect on readString() ), but is it intended behavior? I see in documentation that ungetc() affects only what is read afterwards with getc(), but no mention that readf() is incompatible with other reading methods. It wouldn't even be the problem if I knew for sure that there is always _exactly_ one char offset, or that return value of readf must be number of bytes read from stream. Is it so or is it all just the way it happened to be in current implementation? On another topic. Compiled with D 2.050 it won't work at all, printing object.Error: Access Violation. Apparently readf in 2.0 requires mutable string as a format string. Writing it like this memstream.readf(%d.dup, x); works. Is it intended too? On yet another topic :) Is there alternative to stream.readf? Somehow while searching for explanation of unexpected behavior I got the idea that readf and streams considered to be second-class citizens in world of D and they are not a proper way to do things, so no one really cares about them... Therefore the question. What do I use to read numbers from file?