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: Inlining Code Test
On Sat, 18 Dec 2010 02:17:46 +0100 Don nos...@nospam.com wrote: Nick Voronin wrote: btw, is there no explicit alignment for variables in D at all? align(8) double d; compiles if d is global, but it does nothing. That's a regression. Large globals are always aligned to a 16-byte boundary (see changelog for 2.007) On second thought large globals in static segment (as log says) are probably only those with __gshared prefix. And they do look aligned. However this code: import core.stdc.stdio: printf; int a; double[4] d; void main() { printf(%u %u\n, (cast(size_t)a) % 8, (cast(size_t)d) % 8); } shows that it stopped doing that somewhere between 2.027 and 2.030. -- Nick Voronin elfy...@gmail.com
Re: Inlining Code Test
Looks like alignment of local variables is somewhat broken. import std.stdio; void main() { int a; double d; writeln(a, , d); } testdl.exe 12FE70 12FE78 testdl 12FE74 12FE7C It's not like double is not aligned, otherwise it would be placed right after int, 4 bytes apart, but it is aligned with some assumption which may or may not hold depending on command line. Bug? I hope doubles _should_ be aligned by compiler? On Fri, 17 Dec 2010 09:50:53 +0300, Nick Voronin elfy...@gmail.com wrote: Third... Now here is a funny thing. Absolute times and difference between implementation depends on how do you run the program. I was dumbfounded as of how does it matter, but the fact is that aforementioned avg 5% difference I get if I run it with command line as inline.exe. If I run it as inline without extension I get difference around 15% and absolute times are notably smaller. X:\d\tests\craiginline.exe Sorting with Array.opIndex: 6533 Sorting with pointers: 6264 4.11756 percent faster X:\d\tests\craiginline Sorting with Array.opIndex: 5390 Sorting with pointers: 4674 13.2839 percent faster Something like that. It's not a fluke. I tested it on my old AthlonXp with XP SP2 and saw exactly the same picture (btw, difference in % between implementation was about the same). I ran both variants under stracent and found no difference except one pointer on the stack when LeaveCriticalSection and GetCurrentThreadId are called was always off by 4 bytes. This made me thinking. The only observable difference is length of command line. And indeed, renaming program showed that only length of command line is a reason, not the content. Further tests suggest that some value is either aligned to 8 byte or not depending on length of command line and this makes all the difference (which happens to be greater than difference between implementations of sorting). I couldn't find what value causes slowdown though. -- Using Opera's revolutionary email client: http://www.opera.com/mail/
Re: Inlining Code Test
I found this on bugzilla. http://d.puremagic.com/issues/show_bug.cgi?id=2278 So it's not really a bug. Yet there is no simple workaround. And gap between int and double looks strange when stack frame itself is unaligned. btw, is there no explicit alignment for variables in D at all? align(8) double d; compiles if d is global, but it does nothing. import core.stdc.stdio: printf; align(8) int a; align(8) double d; void main() { printf(%u %u\n, (cast(size_t)a) % 8, (cast(size_t)d) % 8); } This _always_ prints 4 4 for me. It seems that globals are not affected by environment, but not aligned anyway. Honestly, I'm lost :) It all works not as expected but then again I can't find any evidences that my expectations are valid. On Sat, 18 Dec 2010 01:57:44 +0300, bearophile bearophileh...@lycos.com wrote: Nick Voronin: Looks like alignment of local variables is somewhat broken. This is a very nice bug. If not already present then please add it to Bugzilla. If you don't want to add it, then I will add it myself. I have modified your code like this: import core.stdc.stdio: printf; void main() { int a; double d; printf(%u %u\n, (cast(size_t)a) % 8, (cast(size_t)d) % 8); } And this shows the performance difference: import core.stdc.stdio: printf; import std.date: getUTCtime, ticksPerSecond; void main() { double d = 0.0; auto t0 = getUTCtime(); for (size_t i = 0; i 100_000_000; i++) d += 1; auto t1 = getUTCtime(); printf(%lf\n, d); printf(%u\n, (cast(size_t)d) % 8); printf(%lf\n, (cast(double)t1 - cast(double)t0) / ticksPerSecond); } Bye, bearophile -- Using Opera's revolutionary email client: http://www.opera.com/mail/
Re: Inlining Code Test
On Sat, 18 Dec 2010 04:17:46 +0300, Don nos...@nospam.com wrote: Interestingly, since I filed that bug, DMD for MacOSX was created, which ensures that the stack stays aligned in the way I described! So the DMD backend is perfectly capable of doing it now. I added some examples to that bugreport. Just in case :) btw, is there no explicit alignment for variables in D at all? align(8) double d; compiles if d is global, but it does nothing. That's a regression. Large globals are always aligned to a 16-byte boundary (see changelog for 2.007) However this code: import core.stdc.stdio: printf; int a; double[4] d; void main() { printf(%u %u\n, (cast(size_t)a) % 8, (cast(size_t)d) % 8); } shows that it stopped doing that somewhere between 2.027 and 2.030. Thanks. Filed it as http://d.puremagic.com/issues/show_bug.cgi?id=5355 -- Using Opera's revolutionary email client: http://www.opera.com/mail/
Re: Inlining Code Test
On Mon, 13 Dec 2010 01:50:50 +0300, Craig Black craigbla...@cox.net wrote: The following program illustrates the problems with inlining in the dmd compiler. Perhaps with some more work I can reduce it to a smaller test case. I was playing around with a simple Array template, and noticed that similar C++ code performs much better. This is due, at least in part, to opIndex not being properly inlined by dmd. There are two sort functions, quickSort1 and quickSort2. quickSort1 indexes an Array data structure. quickSort2 indexes raw pointers. quickSort2 is roughly 20% faster on my core i7. Compiled with dmd v2.050/win32 -g -O -inline -release First, I looked in debugger on actual asm and I must say inlining is done very well. Code for two versions is almost identical with slight overhead in case of Array for there is extra level of indirection in data access, inlining or not. Second, I have anywhere from 3.3 to 6.7% difference in performance, but no more than that. Tested on Core2Duo E6300, Windows XP SP3. I increased number of iterations for benchmark!() to 5 to reduce volatility of results. That's the only change to source I did. Third... Now here is a funny thing. Absolute times and difference between implementation depends on how do you run the program. I was dumbfounded as of how does it matter, but the fact is that aforementioned avg 5% difference I get if I run it with command line as inline.exe. If I run it as inline without extension I get difference around 15% and absolute times are notably smaller. X:\d\tests\craiginline.exe Sorting with Array.opIndex: 6533 Sorting with pointers: 6264 4.11756 percent faster X:\d\tests\craiginline Sorting with Array.opIndex: 5390 Sorting with pointers: 4674 13.2839 percent faster Something like that. It's not a fluke. I tested it on my old AthlonXp with XP SP2 and saw exactly the same picture (btw, difference in % between implementation was about the same). I ran both variants under stracent and found no difference except one pointer on the stack when LeaveCriticalSection and GetCurrentThreadId are called was always off by 4 bytes. This made me thinking. The only observable difference is length of command line. And indeed, renaming program showed that only length of command line is a reason, not the content. Further tests suggest that some value is either aligned to 8 byte or not depending on length of command line and this makes all the difference (which happens to be greater than difference between implementations of sorting). I couldn't find what value causes slowdown though. -- Using Opera's revolutionary email client: http://www.opera.com/mail/
Re: write, toString, formatValue range interface
I guess the discussion on bugzilla strayed quite far from original point, so I'll answer here. I don't understand you point about Now if we bundle data and Range interface together all kind of funny things happen. A type that implement a range always holds data, usually provides many other features that just range/iteration, Look into std/container.d. Containers hold data, Ranges traverse data (and are separate struct types). Think, how would you generally hold data in something which exhaust itself on iteration? There is save(), but then again it may not be there :) And it creates _new_ range object. See, all kind of complications from mixing things, when they are intended to simplify programing. -- Using Opera's revolutionary email client: http://www.opera.com/mail/
Re: Infinite loop using phobos sort
On Thu, 16 Dec 2010 03:11:40 +0300, Craig Black craigbla...@cox.net wrote: When I try to use Phobos to sort my custom Array, it goes into an infinite loop. I suspect I did something wrong with my Range struct. Does anyone see an obvious flaw here? bordercase this(ref Array!T array) { if(array.empty()) return; start = array.front(); end = array.back(); end points to last actual element } this(T *_start, T *_end) { start = _start; end = _end; same } Range opSlice(int a, int b) { return Range(start+a, start+b); } in opSlice second index points _after_ last element you want. a[0..1] -- range of length 1. You need to fix b by -1. I wonder what kind of assert would catch this one... -- Using Opera's revolutionary email client: http://www.opera.com/mail/
Re: A Benchmark for Phobos Sort Algorithm
On Thu, 16 Dec 2010 04:52:53 +0300, Craig Black craigbla...@cox.net wrote: On my computer, the custom sort algorithm performs almost 40 percent better than the Phobos one. I provided this in case anyone wanted to improve the phobos algorithm. I only benchmarked this with DMD. I would be curious to know how it performs with GDC. Benchmarks! Love them. They will show whatever you want them to. For example I see that customSort is of different complexity and much slower than phobos' sort. =) void quickSort(A, alias L)(A a, int p, int r) { if (p = r) return; if(p + 7 r) return insertionSort!(A, L)(a, p, r); auto x = a[r]; And here is why. Quicksort is quite famous for being O(n^2) worst case (for sorted data). Your straightforward, simple (and less generic, I must say) implementation shines for random data, but performs terribly for ordered data. Phobos' sort isn't really plain quicksort so it is slower for random data (yet still of the same complexity as your code best case), but it is pretty fast for ordered data. I wonder though, what exactly makes std.algorithm.sort twice slower for random data... overhead of ranges? more complex logic/more code? -- Using Opera's revolutionary email client: http://www.opera.com/mail/
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?