Re: I seem to be able to crash writefln
On Thu, Mar 10, 2011 at 1:31 AM, Jonathan M Davis wrote: > On Wednesday 09 March 2011 23:15:13 Andrew Wiley wrote: >> On Wed, Mar 9, 2011 at 5:19 PM, Joel Christensen wrote: >> > This is on Windows 7. Using a def file to stop the terminal window coming >> > up. >> > >> > win.def >> > EXETYPE NT >> > SUBSYSTEM WINDOWS >> > >> > bug.d >> > import std.stdio; >> > import std.string; >> > >> > void main() { >> > auto f = File( "z.txt", "w" ); >> > scope( exit ) >> > f.close; >> > string foo = "bar"; >> > foreach( n; 0 .. 10 ) { >> > writefln( "%s", foo ); >> > f.write( format( "count duck-u-lar: %s\n", n ) ); >> > } >> > } >> > >> > output (from in z.txt): >> > count duck-u-lar: 0 >> >> My understanding is that the "0..10" isn't actually a range notation, >> and you need to use iota(0, 10). I may be wrong, but if I'm right, >> hopefully someone can explain why this syntax works? >> I remember there being a discussion about this recently; I'll see if I >> can find it. > > 0..10 works with foreach. It's specific to foreach. iota also works, because > it > produces a range rather being built in to the language. As such, iota works in > places _other_ than foreach. But 0..10 works just fine in foreach. It > definitely > pre-dates iota. > > - Jonathan M Davis > Ah, then I guess I just need to learn me some D. Sorry for the noise.
Re: Best way in D2 to rotate a ubyte[4] array
On Wed, Mar 9, 2011 at 7:25 PM, U2 fan wrote: > == Quote from bearophile (bearophileh...@lycos.com)'s article >> Tom: >> > What is the most efficient way of implement a rotation of ubyte[4] array? >> > >> > By rotation I mean: rotateRight([1, 2, 3, 4]) -> [4, 1, 2, 3] >> Two versions, I have done no benchmarks so far: >> import std.c.stdio: printf; >> union Four { >> ubyte[4] a; >> uint u; >> } >> void showFour(Four f) { >> printf("f.u: %u\n", f.u); >> printf("f.a: [%d, %d, %d, %d]\n", >> cast(int)f.a[0], cast(int)f.a[1], >> cast(int)f.a[2], cast(int)f.a[3]); >> } >> void main() { >> Four f; >> f.a[] = [1, 2, 3, 4]; >> showFour(f); >> f.u = (f.u << 8) | (f.u >> 24); >> showFour(f); >> printf("\n"); >> // alternative >> f.a[] = [1, 2, 3, 4]; >> uint u2 = f.u; >> showFour(f); >> printf("u2: %u\n", u2); >> asm { >> rol u2, 8; >> } >> f.u = u2; >> showFour(f); >> } >> Bye, >> bearophile > > I am offend! > Once I figured it out, I lol'd quite a bit.
Re: I seem to be able to crash writefln
On Wednesday 09 March 2011 23:15:13 Andrew Wiley wrote: > On Wed, Mar 9, 2011 at 5:19 PM, Joel Christensen wrote: > > This is on Windows 7. Using a def file to stop the terminal window coming > > up. > > > > win.def > > EXETYPE NT > > SUBSYSTEM WINDOWS > > > > bug.d > > import std.stdio; > > import std.string; > > > > void main() { > >auto f = File( "z.txt", "w" ); > >scope( exit ) > >f.close; > >string foo = "bar"; > >foreach( n; 0 .. 10 ) { > >writefln( "%s", foo ); > >f.write( format( "count duck-u-lar: %s\n", n ) ); > >} > > } > > > > output (from in z.txt): > > count duck-u-lar: 0 > > My understanding is that the "0..10" isn't actually a range notation, > and you need to use iota(0, 10). I may be wrong, but if I'm right, > hopefully someone can explain why this syntax works? > I remember there being a discussion about this recently; I'll see if I > can find it. 0..10 works with foreach. It's specific to foreach. iota also works, because it produces a range rather being built in to the language. As such, iota works in places _other_ than foreach. But 0..10 works just fine in foreach. It definitely pre-dates iota. - Jonathan M Davis
Re: I seem to be able to crash writefln
On Wed, Mar 9, 2011 at 5:19 PM, Joel Christensen wrote: > This is on Windows 7. Using a def file to stop the terminal window coming > up. > > win.def > EXETYPE NT > SUBSYSTEM WINDOWS > > bug.d > import std.stdio; > import std.string; > > void main() { > auto f = File( "z.txt", "w" ); > scope( exit ) > f.close; > string foo = "bar"; > foreach( n; 0 .. 10 ) { > writefln( "%s", foo ); > f.write( format( "count duck-u-lar: %s\n", n ) ); > } > } > > output (from in z.txt): > count duck-u-lar: 0 > My understanding is that the "0..10" isn't actually a range notation, and you need to use iota(0, 10). I may be wrong, but if I'm right, hopefully someone can explain why this syntax works? I remember there being a discussion about this recently; I'll see if I can find it.
Re: I seem to be able to crash writefln
On 10-Mar-11 1:04 PM, spir wrote: On 03/10/2011 12:19 AM, Joel Christensen wrote: This is on Windows 7. Using a def file to stop the terminal window coming up. win.def EXETYPE NT SUBSYSTEM WINDOWS bug.d import std.stdio; import std.string; void main() { auto f = File( "z.txt", "w" ); scope( exit ) f.close; string foo = "bar"; foreach( n; 0 .. 10 ) { writefln( "%s", foo ); f.write( format( "count duck-u-lar: %s\n", n ) ); } } output (from in z.txt): count duck-u-lar: 0 What do you mean, crashing writefln? What do you get on the terminal? About the file, there seems to be a bug --but unrelated to writefln. The file is closed, I guess because of scope(exit), before the output stream is flushed. If this is the right interpretation, then there is a precedence issue; scope's action should not be performed before the func's own action is actually completed. Denis It quits out the at about the 2nd attempt at printing text (that doesn't go to the terminal because of the def file argument in the compile arguments). I didn't see any problem with the File stuff, I can use writeln and it does all ten iterations, (not printing any thing of course). I used write instead of writeln, write doesn't flush like writeln, maybe. I noticed my program that had been running fine before, but suddenly bailed out almost strait away since I used the def file in the compile arguments. Joel
Re: Commenting out a print slows my code?
Charles McAnany Wrote: > (There's also a StopWatch timing things, and isTaxiNumber returns a struct, > not a bool. See attached code.) > This code runs in about 0.09 seconds. > If I comment out the writefln, it takes 0.11 seconds. > (These are collected from about 20 runs of each. Times are very consistent.) > Any ideas why commenting out the write makes things slower? > Cheers, > Charles. I couldn't get the code to compile with the stop watch. So instead I removed that and used time. In this case I get user times between .150 and .200 approximately. Maybe with the print statement your program is given higher priority than without, that would mean the operating system would let your application run longer or more frequently than other programs (don't remember if one or both of those is changed).
Re: Best way in D2 to rotate a ubyte[4] array
== Quote from bearophile (bearophileh...@lycos.com)'s article > Tom: > > What is the most efficient way of implement a rotation of ubyte[4] array? > > > > By rotation I mean: rotateRight([1, 2, 3, 4]) -> [4, 1, 2, 3] > Two versions, I have done no benchmarks so far: > import std.c.stdio: printf; > union Four { > ubyte[4] a; > uint u; > } > void showFour(Four f) { > printf("f.u: %u\n", f.u); > printf("f.a: [%d, %d, %d, %d]\n", >cast(int)f.a[0], cast(int)f.a[1], >cast(int)f.a[2], cast(int)f.a[3]); > } > void main() { > Four f; > f.a[] = [1, 2, 3, 4]; > showFour(f); > f.u = (f.u << 8) | (f.u >> 24); > showFour(f); > printf("\n"); > // alternative > f.a[] = [1, 2, 3, 4]; > uint u2 = f.u; > showFour(f); > printf("u2: %u\n", u2); > asm { > rol u2, 8; > } > f.u = u2; > showFour(f); > } > Bye, > bearophile I am offend!
Commenting out a print slows my code?
Hi, all. I'm in college, taking a freshman-level CS class. (I'm actually a senior chemist with free time.) Anyhoo, the warm-up assignment was Hardy Taxi problem, phrased like this: [Exposition removed.] 1729 is the smallest number such that for (a!=b!=c!=d)>0, there exists a combination of a, b, c, and d where a^3+b^3 = 1729 = c^3+d^3. The task was to find all other numbers with this property less than 25,000. The code is basically for (int iters = 1; iters <= 25_000; iters++){ if(isTaxiNumber(iters)){ writefln("%s is a taxi number", iters); } } (There's also a StopWatch timing things, and isTaxiNumber returns a struct, not a bool. See attached code.) This code runs in about 0.09 seconds. If I comment out the writefln, it takes 0.11 seconds. (These are collected from about 20 runs of each. Times are very consistent.) Any ideas why commenting out the write makes things slower? Cheers, Charles. begin 644 taxi.d M:6UP;W)T('-T9"YD871E=&EM93L@+R\@9F]R('1H92!3=&]P5V%T8V@@PT*"6EN="!T87AI3G5M8F5R.PT* M"6EN="!A+"!B+"!C+"!D.PD-"@ES=')I;F<@=&]3=')I;F,RMB7C,@/2!N(#UC7C,@*V1>,RX@#0HJ(')E='5R;G,Z(`T* M*B!A('1A>&E#86(@5XS('=APT*"0EI M;G0@ M7B@Q+S,N,"D[#0H)"6EN="!N96%R97-T26YT(#T@8V%S="AI;G0I("AC=6)E M4F]O="`K(#`N-2D[#0H)"61O=6)L92!D:69F(#T@*&-U8F52;V]T("T@;F5A MPT*"0D):68@*&AI=',@/"`R("8F(')EPT*"0D)"7)E,R`\(&X@ M#0II;G0@8W5B95)O;W1&;&]O7B`H,2\S+C`I.PT*"6EN="!C
Re: std.path.shell throws exception with garbage string
On Wednesday, March 09, 2011 15:55:07 Andrej Mitrovic wrote: > import std.process; > > void main() > { > char[] chBuffer = new char[](256); > chBuffer[] = '\0'; > chBuffer[0..3] = "dir".dup; > > auto result = shell(chBuffer.idup); > } > > It does two things: > 1. It prints out the result of the shell invocation to stdout. This > shouldn't happen. > > 2. It throws this: > std.file.FileException@std\file.d(295): > 5a5785b9a9ef300e292f021170a6bb2e34b80c86bb8decbb6b9b8d3b5e852cd > > This sample works: > import std.process; > > void main() > { > string chBuffer = "dir"; > auto result = shell(chBuffer); > } > > Here the shell invocation isn't printed to the screen, but stored in result > like it should be. > > The problem is I'm working with the win32 API and I can't use lovely D > strings. I've tried using to!string and .idup on the call to 'shell', I've > tried appending null's to the char[] but nothing seems to help. What am I > doing wrong? How about not feeding any strings with stray '\0' characters in it. shell takes a D string, which is _not_ null terminated. Looking at the implementation for cmd on Windows, it ultimately calls std.c.process.system which _does_ take a null terminated string, but the string that is fed to system has stuff _after_ the string that you give it. That means that feeding it a string with '\0' in it like that is going to give a bad string to system, so it fails. In order to get the output of the command that you run, shell attempts to redirect the output to file, but your nulls screw it up and it doesn't get redirected and the file never gets created. The filename is a randomly generated number - hence the bizarre exception message. If you put '\0' in the middle of a string, D will just treat it as data, whereas functions will cut off at that point and assume that the string ended there. If you're passing a string to a C function, make sure it's null-terminated. If you're passing a string to a D function, do _not_ null-terminate it. You're passing a null-terminated string to a D function. That's just asking for trouble. What you need to do is only pass the string up to - but not including - the null terminator to shell. If you have a char*, then to!string should do the right thing. But if you have a char[], then you either need to slice it right before the null terminator or use its ptr property and use to!string on _that_. - Jonathan M Davis
Re: std.path.shell throws exception with garbage string
Found myself a solution. And probably the cause of the issue. shell() doesn't expect a null-terminated string, but just a string with the shell command without any newlines or nulls. So I can do this (importing std.algorithm for until): auto command = to!string(chBuffer[].until('\n')); auto result = shell(command); Not too shabby. Still that error message wasn't of much help. shell() internally creates a temp file with a random file name, temporarily redirects stdout to that file to catch the contents of a system() invocation, and then reads that file with readtext(). Somehow, something errors out if there's a newline or null in the string, and it all explodes with a weird error message.
Re: I seem to be able to crash writefln
On 03/10/2011 12:19 AM, Joel Christensen wrote: This is on Windows 7. Using a def file to stop the terminal window coming up. win.def EXETYPE NT SUBSYSTEM WINDOWS bug.d import std.stdio; import std.string; void main() { auto f = File( "z.txt", "w" ); scope( exit ) f.close; string foo = "bar"; foreach( n; 0 .. 10 ) { writefln( "%s", foo ); f.write( format( "count duck-u-lar: %s\n", n ) ); } } output (from in z.txt): count duck-u-lar: 0 What do you mean, crashing writefln? What do you get on the terminal? About the file, there seems to be a bug --but unrelated to writefln. The file is closed, I guess because of scope(exit), before the output stream is flushed. If this is the right interpretation, then there is a precedence issue; scope's action should not be performed before the func's own action is actually completed. Denis -- _ vita es estrany spir.wikidot.com
Re: Best way in D2 to rotate a ubyte[4] array
On 03/10/2011 12:55 AM, Jonathan M Davis wrote: I don't know of anything more efficient than: >ubyte[4] bytes = [1,2,3,4]; >bytes = bytes[$-1] ~ bytes[0..$-1]; // Rotate left I'm stunned that this works. I'd even consider reporting it as a bug. You're concatenating a ubyte[] ont a ubyte... This works for other arrays as well. dmd understands. Denis -- _ vita es estrany spir.wikidot.com
Re: Best way in D2 to rotate a ubyte[4] array
On 03/09/2011 04:25 PM, bearophile wrote: Tom: What is the most efficient way of implement a rotation of ubyte[4] array? By rotation I mean: rotateRight([1, 2, 3, 4]) -> [4, 1, 2, 3] Two versions, I have done no benchmarks so far: import std.c.stdio: printf; union Four { ubyte[4] a; uint u; } void showFour(Four f) { printf("f.u: %u\n", f.u); printf("f.a: [%d, %d, %d, %d]\n", cast(int)f.a[0], cast(int)f.a[1], cast(int)f.a[2], cast(int)f.a[3]); } void main() { Four f; f.a[] = [1, 2, 3, 4]; showFour(f); f.u = (f.u<< 8) | (f.u>> 24); showFour(f); printf("\n"); // alternative f.a[] = [1, 2, 3, 4]; uint u2 = f.u; showFour(f); printf("u2: %u\n", u2); asm { rol u2, 8; } f.u = u2; showFour(f); } /* dmd -O -release test.d __Dmain comdat pushEBP mov EBP,ESP sub ESP,8 push4 mov EAX,offset FLAT:_D12TypeInfo_xAh6__initZ push4 push3 push2 push1 push4 mov dword ptr -8[EBP],0 pushEAX callnear ptr __d_arrayliteralT add ESP,018h pushEAX lea EAX,-8[EBP] pushEAX callnear ptr _memcpy mov EAX,-8[EBP] callnear ptr _D4test8showFourFS4test4FourZv mov EAX,-8[EBP] mov ECX,-8[EBP] shl EAX,8;<= shr ECX,018h or EAX,ECX mov -8[EBP],EAX mov EAX,-8[EBP] callnear ptr _D4test8showFourFS4test4FourZv mov EAX,offset FLAT:_DATA[024h] pushEAX callnear ptr _printf mov EAX,offset FLAT:_D12TypeInfo_xAh6__initZ push4 push4 push3 push2 push1 push4 pushEAX callnear ptr __d_arrayliteralT add ESP,018h pushEAX lea EAX,-8[EBP] pushEAX callnear ptr _memcpy mov EAX,-8[EBP] mov -4[EBP],EAX mov EAX,-8[EBP] callnear ptr _D4test8showFourFS4test4FourZv mov EAX,offset FLAT:_DATA[028h] pushdword ptr -4[EBP] pushEAX callnear ptr _printf add ESP,024h rol -4[EBP],8 ;<= mov EAX,-4[EBP] mov -8[EBP],EAX mov EAX,-4[EBP] callnear ptr _D4test8showFourFS4test4FourZv mov ESP,EBP pop EBP ret */ In theory a C/C++/D compiler has to compile an expression like (x<< 8)|(x>>24) with a ROL instruction, in practice DMD doesn't do it. Months ago I have asked the two (four in X86) roll instructions to be added to the Phobos core intrinsics module, but I am not sure what Walter answered me. Bye, bearophile I love it. I've done a little benchmark that just repeats the rotate left a certain number of times, and then a rotate right a certain number of times. It looks like shifting ( << | >> ) is faster than the process of copying the uint value, shifting it, and copying it back. If I move the assignment for the rol outside of the for loop, the rol is about twice as fast. http://dl.dropbox.com/u/12135920/rotate.d Both are anywhere from 30 to 80 times faster than the slicing method I proposed (also included in the rotate.d file). -- Rotating static array left to right 500 times Finished in1971.46 milliseconds Rotating static array right to left 500 times Finished in1987.60 milliseconds Rotating dynamic array left to right 500 times Finished in1932.40 milliseconds Rotating dynamic array right to left 500 times Finished in1981.71 milliseconds Shifting Union left to right 500 times Finished in 33.46 milliseconds Shifting Union right to left 500 times Finished in 34.26 milliseconds Rolling Union left to right 500 times Finished in 67.51 milliseconds Rolling Union right to left 500 times Finished in 67.47 milliseconds Rolling Union left to right 500 times with assignment with temporary variable outside of the loop Finished in 28.81 milliseconds Rolling Union right to left 500 times with assignment with temporary variable outside of the loop Finished in 25.57 milliseconds
Re: Best way in D2 to rotate a ubyte[4] array
On Wednesday, March 09, 2011 15:35:29 Kai Meyer wrote: > On 03/09/2011 03:41 PM, Tom wrote: > > What is the most efficient way of implement a rotation of ubyte[4] array? > > > > By rotation I mean: rotateRight([1, 2, 3, 4]) -> [4, 1, 2, 3] > > > > TIA, > > Tom; > > I don't know of anything more efficient than: > ubyte[4] bytes = [1,2,3,4]; > bytes = bytes[$-1] ~ bytes[0..$-1]; // Rotate left I'm stunned that this works. I'd even consider reporting it as a bug. You're concatenating a ubyte[] ont a ubyte... > bytes = bytes[1..$] ~ bytes[0]; // Rotate right You're concatenating a ubyte onto a slice of the array (so it's ubyte[] instead of ubyte[4]). That will result in a temporary whose value will then be assigned to the original ubyte[4]. > Both static arrays and dynamic arrays (ubyte[] bytes = [1,2,3,4];) > perform about the same between 1 and 10 milling rotations in either > direction. I think a temporary array might be created for the rhs, and > then have the values of the rhs array copied to the lhs array, but I > don't know. With static arrays, I'm not sure there would be a way to get > around it with out at least a temporary value for the one that's moving > between the first and last positions. Honestly, given that this is 4 ubytes, I would fully expect that the fastest way to do this would involve casting it to a unit and shifting it - something along the lines of what Bearophile suggested. I'd be _very_ suprised if this implementation were faster, since it involves creating a temporary array. - Jonathan M Davis
std.path.shell throws exception with garbage string
import std.process; void main() { char[] chBuffer = new char[](256); chBuffer[] = '\0'; chBuffer[0..3] = "dir".dup; auto result = shell(chBuffer.idup); } It does two things: 1. It prints out the result of the shell invocation to stdout. This shouldn't happen. 2. It throws this: std.file.FileException@std\file.d(295): 5a5785b9a9ef300e292f021170a6bb2e34b80c86bb8decbb6b9b8d3b5e852cd This sample works: import std.process; void main() { string chBuffer = "dir"; auto result = shell(chBuffer); } Here the shell invocation isn't printed to the screen, but stored in result like it should be. The problem is I'm working with the win32 API and I can't use lovely D strings. I've tried using to!string and .idup on the call to 'shell', I've tried appending null's to the char[] but nothing seems to help. What am I doing wrong?
Re: Best way in D2 to rotate a ubyte[4] array
El 09/03/2011 20:25, bearophile escribió: Tom: What is the most efficient way of implement a rotation of ubyte[4] array? By rotation I mean: rotateRight([1, 2, 3, 4]) -> [4, 1, 2, 3] Two versions, I have done no benchmarks so far: import std.c.stdio: printf; union Four { ubyte[4] a; uint u; } void showFour(Four f) { printf("f.u: %u\n", f.u); printf("f.a: [%d, %d, %d, %d]\n", cast(int)f.a[0], cast(int)f.a[1], cast(int)f.a[2], cast(int)f.a[3]); } void main() { Four f; f.a[] = [1, 2, 3, 4]; showFour(f); f.u = (f.u<< 8) | (f.u>> 24); showFour(f); printf("\n"); // alternative f.a[] = [1, 2, 3, 4]; uint u2 = f.u; showFour(f); printf("u2: %u\n", u2); asm { rol u2, 8; } f.u = u2; showFour(f); } /* dmd -O -release test.d __Dmain comdat pushEBP mov EBP,ESP sub ESP,8 push4 mov EAX,offset FLAT:_D12TypeInfo_xAh6__initZ push4 push3 push2 push1 push4 mov dword ptr -8[EBP],0 pushEAX callnear ptr __d_arrayliteralT add ESP,018h pushEAX lea EAX,-8[EBP] pushEAX callnear ptr _memcpy mov EAX,-8[EBP] callnear ptr _D4test8showFourFS4test4FourZv mov EAX,-8[EBP] mov ECX,-8[EBP] shl EAX,8;<= shr ECX,018h or EAX,ECX mov -8[EBP],EAX mov EAX,-8[EBP] callnear ptr _D4test8showFourFS4test4FourZv mov EAX,offset FLAT:_DATA[024h] pushEAX callnear ptr _printf mov EAX,offset FLAT:_D12TypeInfo_xAh6__initZ push4 push4 push3 push2 push1 push4 pushEAX callnear ptr __d_arrayliteralT add ESP,018h pushEAX lea EAX,-8[EBP] pushEAX callnear ptr _memcpy mov EAX,-8[EBP] mov -4[EBP],EAX mov EAX,-8[EBP] callnear ptr _D4test8showFourFS4test4FourZv mov EAX,offset FLAT:_DATA[028h] pushdword ptr -4[EBP] pushEAX callnear ptr _printf add ESP,024h rol -4[EBP],8 ;<= mov EAX,-4[EBP] mov -8[EBP],EAX mov EAX,-4[EBP] callnear ptr _D4test8showFourFS4test4FourZv mov ESP,EBP pop EBP ret */ In theory a C/C++/D compiler has to compile an expression like (x<< 8)|(x>>24) with a ROL instruction, in practice DMD doesn't do it. Months ago I have asked the two (four in X86) roll instructions to be added to the Phobos core intrinsics module, but I am not sure what Walter answered me. Bye, bearophile Wow, thanks b, didn't know of the rol instruction... Tom;
Re: Best way in D2 to rotate a ubyte[4] array
On 03/09/2011 03:41 PM, Tom wrote: What is the most efficient way of implement a rotation of ubyte[4] array? By rotation I mean: rotateRight([1, 2, 3, 4]) -> [4, 1, 2, 3] TIA, Tom; I don't know of anything more efficient than: ubyte[4] bytes = [1,2,3,4]; bytes = bytes[$-1] ~ bytes[0..$-1]; // Rotate left bytes = bytes[1..$] ~ bytes[0]; // Rotate right Both static arrays and dynamic arrays (ubyte[] bytes = [1,2,3,4];) perform about the same between 1 and 10 milling rotations in either direction. I think a temporary array might be created for the rhs, and then have the values of the rhs array copied to the lhs array, but I don't know. With static arrays, I'm not sure there would be a way to get around it with out at least a temporary value for the one that's moving between the first and last positions.
Re: Best way in D2 to rotate a ubyte[4] array
Tom: > What is the most efficient way of implement a rotation of ubyte[4] array? > > By rotation I mean: rotateRight([1, 2, 3, 4]) -> [4, 1, 2, 3] Two versions, I have done no benchmarks so far: import std.c.stdio: printf; union Four { ubyte[4] a; uint u; } void showFour(Four f) { printf("f.u: %u\n", f.u); printf("f.a: [%d, %d, %d, %d]\n", cast(int)f.a[0], cast(int)f.a[1], cast(int)f.a[2], cast(int)f.a[3]); } void main() { Four f; f.a[] = [1, 2, 3, 4]; showFour(f); f.u = (f.u << 8) | (f.u >> 24); showFour(f); printf("\n"); // alternative f.a[] = [1, 2, 3, 4]; uint u2 = f.u; showFour(f); printf("u2: %u\n", u2); asm { rol u2, 8; } f.u = u2; showFour(f); } /* dmd -O -release test.d __Dmain comdat pushEBP mov EBP,ESP sub ESP,8 push4 mov EAX,offset FLAT:_D12TypeInfo_xAh6__initZ push4 push3 push2 push1 push4 mov dword ptr -8[EBP],0 pushEAX callnear ptr __d_arrayliteralT add ESP,018h pushEAX lea EAX,-8[EBP] pushEAX callnear ptr _memcpy mov EAX,-8[EBP] callnear ptr _D4test8showFourFS4test4FourZv mov EAX,-8[EBP] mov ECX,-8[EBP] shl EAX,8; <= shr ECX,018h or EAX,ECX mov -8[EBP],EAX mov EAX,-8[EBP] callnear ptr _D4test8showFourFS4test4FourZv mov EAX,offset FLAT:_DATA[024h] pushEAX callnear ptr _printf mov EAX,offset FLAT:_D12TypeInfo_xAh6__initZ push4 push4 push3 push2 push1 push4 pushEAX callnear ptr __d_arrayliteralT add ESP,018h pushEAX lea EAX,-8[EBP] pushEAX callnear ptr _memcpy mov EAX,-8[EBP] mov -4[EBP],EAX mov EAX,-8[EBP] callnear ptr _D4test8showFourFS4test4FourZv mov EAX,offset FLAT:_DATA[028h] pushdword ptr -4[EBP] pushEAX callnear ptr _printf add ESP,024h rol -4[EBP],8 ; <= mov EAX,-4[EBP] mov -8[EBP],EAX mov EAX,-4[EBP] callnear ptr _D4test8showFourFS4test4FourZv mov ESP,EBP pop EBP ret */ In theory a C/C++/D compiler has to compile an expression like (x<< 8)|(x>>24) with a ROL instruction, in practice DMD doesn't do it. Months ago I have asked the two (four in X86) roll instructions to be added to the Phobos core intrinsics module, but I am not sure what Walter answered me. Bye, bearophile
I seem to be able to crash writefln
This is on Windows 7. Using a def file to stop the terminal window coming up. win.def EXETYPE NT SUBSYSTEM WINDOWS bug.d import std.stdio; import std.string; void main() { auto f = File( "z.txt", "w" ); scope( exit ) f.close; string foo = "bar"; foreach( n; 0 .. 10 ) { writefln( "%s", foo ); f.write( format( "count duck-u-lar: %s\n", n ) ); } } output (from in z.txt): count duck-u-lar: 0
Best way in D2 to rotate a ubyte[4] array
What is the most efficient way of implement a rotation of ubyte[4] array? By rotation I mean: rotateRight([1, 2, 3, 4]) -> [4, 1, 2, 3] TIA, Tom;
Re: full ident name without mangle/demange?
Nick Sabalausky napisał: > Is there a way to get the fully-qualified name of an identifier without > doing "demange( mangledName!(foo) )"? Heh, looks like there isn't. It may be worth filing an enhancement request for __traits(fullyQualifiedName, foo). BTW, what do you need it for? -- Tomek
Re: Iterating over 0..T.max
On 03/09/2011 09:09 AM, Magnus Lie Hetland wrote: In a (template) data structure I'm working on, I had the following thinko: auto a = new T[n]; foreach (T i, ref e; a) { e = i; } Then I instantiated it with T=bool, and n=256. Infinite loop, of course -- the problem being that i wraps around to 0 after the last iteration. Easily fixed, and not that much of a problem (given that I caught it) -- I'll just use e = cast(T) i. (Of course, even with that solution, I'd get wrap problems if n=257, but I just want to make sure I allow T.max as a size.) But I'm wondering: given D's excellent valua range propagations and overflow checking, would it be possible to catch this special case (i.e., detect when the array can be too long for the index type)? Or are any other safeguards possible to prevent this sort of thing? I don't see how that works in dmd2, and I don't have much experience with dmd1, so I'll admit that this may be different on dmd1. I get compilation errors with your code: import std.stdio; void main() { make_new!(bool)(256); } void make_new(T)(size_t n) { auto a = new T[n]; foreach (T i, ref e; a) { e = i; } } This gives me: tmax.d(12): Error: operation not allowed on bool 'i' tmax.d(5): Error: template instance tmax.make_new!(bool) error instantiating As far as I understand, a foreach over an array makes the first value (i) a uint for the index, and the second value (e) a copy of the value in the array (in our case a bool). import std.stdio; void main() { make_new!(bool)(1); } void make_new(T)(size_t n) { auto a = new T[n]; writef("%s\n", typeof(a).stringof); foreach (i,e; a) { writef("%s\n", typeof(i).stringof); writef("%s\n", typeof(e).stringof); } } /* Output: bool[] uint bool */ But to the question about boundaries, 'i' is a uint (size_t), and on a 4GB machine, I can't call "auto a = new bool[size_t.max];". The program segfaults. size_t.max / 2 for a size gives me "Memory allocation failed". size_t.max / 4 works fine. I'm not sure how to get a program to do what you describe.
Re: struct opEquals
On Wed, 09 Mar 2011 12:15:26 -0500, SiegeLord wrote: Steven Schveighoffer Wrote: It's a mis-designed feature of structs. There is a bug report on it: http://d.puremagic.com/issues/show_bug.cgi?id=3659 It worked fine in D1. Or did you mean that the mis-designed feature is the const system? No, the mis-designed feature is the compiler requiring that specific signature in D2. Const is not the mis-designed feature. It works in D1 because D1 doesn't generate intelligent opEquals for structs that do not have them, it just does a bit compare. For example, if you did this in D1, it fails the assert: struct S { string name; } void main() { S s1, s2; s1.name = "hello".dup; s2.name = "hello".dup; assert(s1 == s2); // fails in D1, should pass on D2. } -Steve
Re: struct opEquals
Steven Schveighoffer Wrote: > It's a mis-designed feature of structs. There is a bug report on it: > > http://d.puremagic.com/issues/show_bug.cgi?id=3659 It worked fine in D1. Or did you mean that the mis-designed feature is the const system? Anyway, thanks for the link to the bug report. I'll work around it for now. -SiegeLord > > -Steve
Re: struct opEquals
On Wed, 09 Mar 2011 11:40:25 -0500, SiegeLord wrote: 1) Why does this code not work (dmd 2.051) and how do I fix it: struct S { static S New() { S s; return s; } const bool opEquals(ref const(S) s) { return true; } } void main() { S s; assert(s == S.New); } Because passing an argument via ref means it must be an lvalue. New() returns an rvalue. However, that restriction is lifted for the 'this' parameter, so the following should actually work: assert(S.New() == s); 2) Why is the type of struct opEquals have to be const bool opEquals(ref const(T) s)? Why is it even enforced to be anything in particular (it's not like there's an Object or something to inherit from)? It's a mis-designed feature of structs. There is a bug report on it: http://d.puremagic.com/issues/show_bug.cgi?id=3659 -Steve
struct opEquals
1) Why does this code not work (dmd 2.051) and how do I fix it: struct S { static S New() { S s; return s; } const bool opEquals(ref const(S) s) { return true; } } void main() { S s; assert(s == S.New); } 2) Why is the type of struct opEquals have to be const bool opEquals(ref const(T) s)? Why is it even enforced to be anything in particular (it's not like there's an Object or something to inherit from)? -SiegeLord
Re: Mocking framework
I should correct myself a bit... By putting the if on the class level I need to add every method used by the class, and also add all these methods to the mock object. It should be added to the method level where doStuff() is called.
Iterating over 0..T.max
In a (template) data structure I'm working on, I had the following thinko: auto a = new T[n]; foreach (T i, ref e; a) { e = i; } Then I instantiated it with T=bool, and n=256. Infinite loop, of course -- the problem being that i wraps around to 0 after the last iteration. Easily fixed, and not that much of a problem (given that I caught it) -- I'll just use e = cast(T) i. (Of course, even with that solution, I'd get wrap problems if n=257, but I just want to make sure I allow T.max as a size.) But I'm wondering: given D's excellent valua range propagations and overflow checking, would it be possible to catch this special case (i.e., detect when the array can be too long for the index type)? Or are any other safeguards possible to prevent this sort of thing? -- Magnus Lie Hetland http://hetland.org
Re: Mocking framework
I gave this some thought, and I'm probably just a bit braindamaged by C#. Consider you wish to unittest a class that fetches data from a database and sends an email. The common scenario here is to use IoC and mock the objects so you can check that "FetchData" was called and "SendEmail" is called using the data from your "FetchData". So this is the scenario: interface SomeBigInterface { void doStuff(); // And many more methods here } class SomeClassImplementingInterface : SomeBigInterface { void doStuff() {} // And many more methods here } class SomeClass { SomeBigInterface _i; this(SomeBigInterface i) { _i = i; } void someComplexStuff() { _i.doStuff(); } } And how can I mock the entire SomeBigInterface containing 20 methods just to make sure doStuff is called? And what if it didn't take an interface, but an SmtpClient? But then I thought I might be forcing D into the limitations of C# and other pure oo langauges. Then I created this instead: // Now I'm only depending on the methods I use, not an entire interface or a specific class/struct class SomeClass2(T) if( is(typeof({ return T.init.doStuff(); })) ) { T _i; this(T i) { _i = i; } void someComplexStuff() { _i.doStuff(); } } Then I can mock it up a lot easier: class MyMock { int called; void doStuff() { ++called; } } auto mock = new MyMock(); auto a = new SomeClass2!MyMock(mock); assert(mock.called == 0); a.someComplexStuff(); assert(mock.called == 1); a.someComplexStuff(); assert(mock.called == 2); And voila.. It's simpler to create the mock object by hand than through a library. The question is, is this good practice? Should I often just create templates like isSomeInterface (like the range api does) checking for methods and properties instead of using interfaces directly?
Re: Templated struct doesn't need the parameterized type in return type definitions?
On Tue, 08 Mar 2011 15:25:27 -0500, Steven Schveighoffer wrote: > "Hey, wouldn't it be cool if I could add a custom allocator to all > classes!?"... > > class Collection(T, alloc = DefaultAllocator!T) { > Collection!(T) add(T t) { ...; return this; } // 20 other now subtly > incorrect functions like add... > } > > See the problem? This seems like a good reason to keep allowing the feature. It would be nice if it could be documented clearly somewhere, maybe here: http://www.digitalmars.com/d/2.0/template.html#ClassTemplateDeclaration