Interfacing C programs: Pass D string to C function
Hello I trying to write simple wrapper around pcre and have problem passing strings to it. As i understood, the best way is std.string.toStringZ. So, my code look like: string pattern = ; pcre_compile2( toStringz(pattern), options, errcode, errmsg, erroffset, cast(char*)null); This gives me error: Error: function pcre_compile2 (char*, int, int*, char**, int*, char*) is not callable using argument types (immutable(char)*, int, int*, char**, int*, char*) Any ideas for better way to do this task ?
Re: Interfacing C programs: Pass D string to C function
On Friday, 13 December 2013 at 08:00:21 UTC, Dfr wrote: Hello I trying to write simple wrapper around pcre and have problem passing strings to it. As i understood, the best way is std.string.toStringZ. So, my code look like: string pattern = ; pcre_compile2( toStringz(pattern), options, errcode, errmsg, erroffset, cast(char*)null); This gives me error: Error: function pcre_compile2 (char*, int, int*, char**, int*, char*) is not callable using argument types (immutable(char)*, int, int*, char**, int*, char*) Any ideas for better way to do this task ? Try using cast(char*)pattern
Re: What is the common way of porting opaque types in C header files?
On Friday, 13 December 2013 at 01:20:41 UTC, Mike Parker wrote: On 12/13/2013 7:52 AM, Gary Willoughby wrote: I have a lot of opaque types in C headers i'm porting to D. What is the best way to handle these? Would you just use void pointers? In the below example Tcl_AsyncHandler_ is not defined anywhere. C: typedef struct Tcl_AsyncHandler_ *Tcl_AsyncHandler; D: alias void* Tcl_AsyncHandler; D: struct Tcl_AsyncHandler_; alias Tcl_AsyncHandler = Tcl_AsyncHandler_*; Ah right, thanks. I didn't know D allows such types.
Re: Interfacing C programs: Pass D string to C function
On Friday, December 13, 2013 09:00:20 Dfr wrote: Hello I trying to write simple wrapper around pcre and have problem passing strings to it. As i understood, the best way is std.string.toStringZ. So, my code look like: string pattern = ; pcre_compile2( toStringz(pattern), options, errcode, errmsg, erroffset, cast(char*)null); This gives me error: Error: function pcre_compile2 (char*, int, int*, char**, int*, char*) is not callable using argument types (immutable(char)*, int, int*, char**, int*, char*) Any ideas for better way to do this task ? The problem is that toStringz returns immutable(char)* (because string is immutable(string)[]), and your function is taking char*. It will work to pass the result of toStringz to a C function which takes const char* (since immutable will implicitly convert to const), but immutable doesn't implicitly convert to mutable, and casting immutable mutable is almost always a bad idea. The easiest solution would be to use std.utf.toUTFz. e.g. auto cstr = str.toUTFz!(char*)(); or you could do something like auto cstr = str.dup.ptr; In either case, what you're doing is allocating a new char[] which holds the same elements as the original string and getting its ptr property so that you have a char*. - Jonathan M Davis
Re: Allowing string value with getopt without requiring it
On Friday, 13 December 2013 at 01:51:25 UTC, Ithy wrote: Hello. I'm just getting into D (literally writing my first program), and I can't figure out how to do this with getopt: I want to have the option --log, which will enable logging (set a bool variable to true). However, I want the program to also accept --log=filename to allow the user to define custom log file. If --log is used without filename, a default file will be used. I tried this: getopt(args, log, log, log, logFile); Passing just --log to the program works fine, the boolean is set to true. However, using --log=test.log throws an exception, and seemingly getopt expects either true or false. How would I go about implementing this without creating another option like --log-file for custom file name? That doesn't seem possible with getopt. I would use std.getopt.config.passThrough and then deal with the log option manually afterwards.
Re: Interfacing C programs: Pass D string to C function
On 12/13/2013 5:00 PM, Dfr wrote: Hello I trying to write simple wrapper around pcre and have problem passing strings to it. As i understood, the best way is std.string.toStringZ. So, my code look like: string pattern = ; pcre_compile2( toStringz(pattern), options, errcode, errmsg, erroffset, cast(char*)null); This gives me error: Error: function pcre_compile2 (char*, int, int*, char**, int*, char*) is not callable using argument types (immutable(char)*, int, int*, char**, int*, char*) Any ideas for better way to do this task ? Declare the function to like so: pcre* pcre_compile2( const(char)*, int, int*, const(char)**, int*, const(ubyte)*); This matches the C declaration according to [1]. immutable args can be passed to const params without seeing your error. Also, note the last paramters. In C, it's declared to be const unsigned char* and the documentation suggest it's intended to be treated as a byte array rather than a string. In that case, const(ubyte)* is the appropriate choice. D declarations of C functions should generally match the C version as closely as possible, including use of const, but with intent taken into account as well (e.g. byte array vs string). [1] https://code.google.com/p/wiimc/source/browse/trunk/libs/pcre/doc/html/pcre_compile2.html?r=423
String mixins with string arrays
Hi, Is it possible to pass a string array to a string mixin e.g template GenSomething(string foo, string[] bar){ some_kind_of_foreach(br: bar) { const char[] foo ~ br ~ ;\n; } } and call: mixin(GenSomething!(A, [B, C, D])); would generate: A.B; A.C; A.D; Regards, -=mike=-
Re: Type inference and overloaded functions
On Friday, 13 December 2013 at 00:37:36 UTC, Namespace wrote: Why don't you discuss on github? And finally I did it: auto[$] a_arr2 = dyn_arr[4 .. 8]; assert(is(typeof(a_arr2) == int[4])); I will make a Pull Request tomorrow. Hope my code isn't that bad. :/ Done: https://github.com/D-Programming-Language/dmd/pull/2958
Match properties as member variables
From client perspective, properties look like member variables. With (auto) ref, a generic function can catch a member variable and read it and update it: void swap(T)(ref T a, ref T b) {...} The client can use swap with member variables. But he can't use this swap with class properties - they're special. Since the properties look like member variables, I think it is a valid use-case for us to want to be able to write generic code that can handle properties passed as arguments in the same way as member variables passed as arguments. Can you write version of swap, which works also with properties and/or combination of properties and references?
static if - is the 'static' really needed?
Imagine a world in which a simple 'if' has the semantics of a static if, if the condition is evaluable at CT. Is this a world you would rather live in? template Fac(int i) { if (i == 0) { // static if; doesn't introduce scope enum Fac = 1; } else { enum Fac = i * Fac!(i-1); } } // If the condition is not evaluable at CT, the ordinary runtime if semantics (introducing scope) are used. Me: pros: simpler syntax cons: harder to reason about; I recall Andrei's talk about the static if proposal to C++: we don't need _static else_ -- why do we even need 'static' in 'static if' by this reasoning?
Re: String mixins with string arrays
On Friday, 13 December 2013 at 11:40:35 UTC, Mike James wrote: Hi, Is it possible to pass a string array to a string mixin e.g template GenSomething(string foo, string[] bar){ some_kind_of_foreach(br: bar) { const char[] foo ~ br ~ ;\n; } } and call: mixin(GenSomething!(A, [B, C, D])); would generate: A.B; A.C; A.D; Regards, -=mike=- CTFE is your friend here. string genSomething(string foo, string[] bar) { string result; foreach(br: bar) { result ~= foo ~ '.' ~ br ~ ;\n; } } mixin(genSomething(A, [B, C, D]));
Re: static if - is the 'static' really needed?
On Friday, 13 December 2013 at 12:10:02 UTC, comco wrote: Imagine a world in which a simple 'if' has the semantics of a static if, if the condition is evaluable at CT. Is this a world you would rather live in? template Fac(int i) { if (i == 0) { // static if; doesn't introduce scope enum Fac = 1; } else { enum Fac = i * Fac!(i-1); } } // If the condition is not evaluable at CT, the ordinary runtime if semantics (introducing scope) are used. Me: pros: simpler syntax cons: harder to reason about; I recall Andrei's talk about the static if proposal to C++: we don't need _static else_ -- why do we even need 'static' in 'static if' by this reasoning? What would happen when the condition is sometimes evaluable at compile time and sometimes not? void foo(alias a)() { /* static */ if (a) int x = 1; else int x = 42; doSomethingWith(x); }
Re: static if - is the 'static' really needed?
On Friday, 13 December 2013 at 12:50:01 UTC, Nicolas Sicard wrote: On Friday, 13 December 2013 at 12:10:02 UTC, comco wrote: Imagine a world in which a simple 'if' has the semantics of a static if, if the condition is evaluable at CT. Is this a world you would rather live in? template Fac(int i) { if (i == 0) { // static if; doesn't introduce scope enum Fac = 1; } else { enum Fac = i * Fac!(i-1); } } // If the condition is not evaluable at CT, the ordinary runtime if semantics (introducing scope) are used. Me: pros: simpler syntax cons: harder to reason about; I recall Andrei's talk about the static if proposal to C++: we don't need _static else_ -- why do we even need 'static' in 'static if' by this reasoning? What would happen when the condition is sometimes evaluable at compile time and sometimes not? void foo(alias a)() { /* static */ if (a) int x = 1; else int x = 42; doSomethingWith(x); } Multiple versions of the foo function - depending on the caller - as it is with templates? Static ifs already can produce a combinatorial explosion of different method implementations :) At least in the places where declarations are expected and normal if doesn't make sense: like template/class/struct body, if can be implicitly static. Now it is implicitly static right after function / class / template declarations. class A(T) { if (is(T : B)) B b; else T b; ... }
Re: String mixins with string arrays
On Friday, 13 December 2013 at 12:09:59 UTC, John Colvin wrote: On Friday, 13 December 2013 at 11:40:35 UTC, Mike James wrote: Hi, Is it possible to pass a string array to a string mixin e.g template GenSomething(string foo, string[] bar){ some_kind_of_foreach(br: bar) { const char[] foo ~ br ~ ;\n; } } and call: mixin(GenSomething!(A, [B, C, D])); would generate: A.B; A.C; A.D; Regards, -=mike=- CTFE is your friend here. string genSomething(string foo, string[] bar) { string result; foreach(br: bar) { result ~= foo ~ '.' ~ br ~ ;\n; } } mixin(genSomething(A, [B, C, D])); Thanks - that worked a treat (just needed a 'return result;'). Regards, -=mike=-
Re: String mixins with string arrays
On Friday, 13 December 2013 at 13:23:24 UTC, Mike James wrote: On Friday, 13 December 2013 at 12:09:59 UTC, John Colvin wrote: On Friday, 13 December 2013 at 11:40:35 UTC, Mike James wrote: Hi, Is it possible to pass a string array to a string mixin e.g template GenSomething(string foo, string[] bar){ some_kind_of_foreach(br: bar) { const char[] foo ~ br ~ ;\n; } } and call: mixin(GenSomething!(A, [B, C, D])); would generate: A.B; A.C; A.D; Regards, -=mike=- CTFE is your friend here. string genSomething(string foo, string[] bar) { string result; foreach(br: bar) { result ~= foo ~ '.' ~ br ~ ;\n; } } mixin(genSomething(A, [B, C, D])); Thanks - that worked a treat (just needed a 'return result;'). Regards, -=mike=- woops, forgot that :)
Re: Ensuring template argument is descendant of class
On Friday, 13 December 2013 at 05:55:09 UTC, H. S. Teoh wrote: On Fri, Dec 13, 2013 at 06:42:26AM +0100, Brian Rogoff wrote: I'm sympathetic to this POV, or something similar. For example, a multiyear plan to deprecate the 'is' syntax and replace it with something better, in the current D. I'm not a fan of gratuitous changes which make the language unstable, but if there were a pleasing design to replace 'is' I'd like to think that D users could change the relevant sources given a long enough deprecation window. I vote for this. Good luck convincing Walter, though. Step 1 is to come up with a set of better design alternatives, and a transition plan, etc. I'm pretty sure I've read posts from Walter on this forum that agree with the current 'is' is far from ideal, so maybe convincing him is not as hard as you think, though I imagine he has bigger fish to fry these days. Still, it would be encouraging if the D community could address the general issue of *not* being forced to keep bad designs forever. -- Brian
Re: Is file.rename() atomic?
Am Thu, 12 Dec 2013 18:08:12 +0100 schrieb Jacek Furmankiewicz jace...@gmail.com: void rename(in char[] from, in char[] to); Rename file from to to. If the target file exists, it is overwritten. Throws: FileException on error. Just wanted to know if this operation is atomic? or does it depend on the underlying file system? In short, in the file nanoseconds/milliseconds that this operation is occurring is it possible for someone else to be reading the same file and get a dirty read (i.e. with only half of the contents overriden, etc)? Thanks I don't know for sure, but it is likely you are on the safe side I guess ;) 1. the reading process probably didn't allow shared writing to the target file anyways (on Windows) 2. moving a file on the same file system is just a metadata update (giving the data a different name). 3. If all else fails, the target file is most likely deleted first, then recreated with the contents of the file to move which easily avoids what you describe. You could try MoveFileEx on an opened target file with all sharing options enabled and see what happens. -- Marco
Re: Ranges: is it ok if front is a data member?
Am Thu, 12 Dec 2013 08:43:35 -0800 schrieb H. S. Teoh hst...@quickfur.ath.cx: I do this with my own ranges sometimes. Sometimes, it's more performant to precompute the value of .front and store it (as .front), and have .popFront compute the next value, than to have .front compute the value every time. AFAICT, this is perfectly fine and should work with Phobos seamlessly. The power of ducktyping! T Most non-trivial ranges do the actual work in `popFront()' and return a cached value from `front'. It has been argued as a design quirk, that this in general leads to: struct Range { bool popFrontHasBeenCalledOnce = false; T current; @property T front() { if (!popFrontHasBeenCalledOnce) { popFront(); // initializes `current' } return current; } […] } -- Marco
Re: updating druntime
Am Thu, 12 Dec 2013 20:29:31 +0100 schrieb Benji romanbeno...@gmail.com: On Thursday, 12 December 2013 at 19:11:03 UTC, John Colvin wrote: On Thursday, 12 December 2013 at 16:44:28 UTC, Benji wrote: Hello, when I try to compile something with dmd, I get following message: /usr/include/dmd/phobos/std/bitmanip.d(416): Error: undefined identifier '_xopCmp' Error: ICE: _xopCmp not found in object module. You must update druntime How to 'update druntime' ? how did you install dmd/druntime/phobos originally? As it is mentioned in installation instructions to the dmd (linux-ubuntu) Did you use the .deb file? It shouldn't produce such a version mismatch. Did you install over a previous installation and possibly have some leftover files from the old DMD version? I'd say format c: and start over with the installation of DMD. In any case, if you didn't install from the GitHub sources this error message should not appear and someone who isn't hacking on DMD does not have to update druntime manually. -- Marco
Re: updating druntime
On Friday, 13 December 2013 at 15:00:57 UTC, Marco Leise wrote: I'd say format c: A bit drastic, or am i missing something?!?!
Re: Performance of ranges verses direct
Am Thu, 12 Dec 2013 16:02:28 +0100 schrieb John Colvin john.loughran.col...@gmail.com: On Wednesday, 11 December 2013 at 16:40:48 UTC, Joseph Rushton Wakeling wrote: [* If I recall right, it's achievable by special-casing iota when the increment is 1, but don't quote me on that.] That shouldn't be necessary if the iota operations are inlined (which, if their not, is a much greater concern!). The increment is then known to be a particular compile-time constant and code generated appropriately. Also, on x86 the gcc and llvm backends both prefer to use add 1 instead of inc, so you wouldn't even expect to see any difference at that level. This doesn't seem to be the general case... http://stackoverflow.com/questions/12163610/why-inc-and-add-1-have-different-performances For the x86 architecture, INC updates on a subset of the condition codes, whereas ADD updates the entire set of condition codes. (Other architectures have different rules so this discussion may or may not apply). So an INC instruction must wait for other previous instructions that update the condition code bits to finish, before it can modify that previous value to produce its final condition code result. ADD can produce final condition code bits without regard to previous values of the condition codes, so it doesn't need to wait for previous instructions to finish computing their value of the condition codes. - and - On x86 architectures, with variable length instruction encoding, there could be occasions where either one is preferable over the other. If the shorter on would fit in a cache line or decode block where the larger wouldn't, then it will come out ahead. If the shorter one would leave half of the next instruction in the window, and the remaining half in the next window, the larger one might be better by aligning its successor nicely. -- Marco
Re: Ranges: is it ok if front is a data member?
On 13/12/13 16:52, Marco Leise wrote: Most non-trivial ranges do the actual work in `popFront()' and return a cached value from `front'. It has been argued as a design quirk, that this in general leads to: struct Range { bool popFrontHasBeenCalledOnce = false; T current; @property T front() { if (!popFrontHasBeenCalledOnce) { popFront(); // initializes `current' } return current; } […] } For example in much of std.random. With classes you can get round it by defining a default constructor, but with structs it can create some tricky situations. I have wondered about the feasibility of a method called something like .first() which would basically be called the very first time one calls _any_ method of the struct/class in question, and would perform the appropriate initialization.
Re: static if - is the 'static' really needed?
On Friday, 13 December 2013 at 12:10:02 UTC, comco wrote: Imagine a world in which a simple 'if' has the semantics of a static if, if the condition is evaluable at CT. Is this a world you would rather live in? template Fac(int i) { if (i == 0) { // static if; doesn't introduce scope enum Fac = 1; } else { enum Fac = i * Fac!(i-1); } } I would not rather live in it. I would rather live in: static foreach(...) // but that hasn't happened yet.
Demangling D Symbols when Profiling D Programs with perf
I've just discovered the fantastic tool perf on Linux. I profiled a D program with this but when I call perf report the symbols are not demangled. I'm aware of `ddemangle` but this only works in batch-processing mode. I could always dump the output to a file for viewing. But it would be great if someone have found a solution to demangle the symbols *before* they are added to the perf database file.
Re: updating druntime
Am Fri, 13 Dec 2013 16:08:22 +0100 schrieb John Colvin john.loughran.col...@gmail.com: On Friday, 13 December 2013 at 15:00:57 UTC, Marco Leise wrote: I'd say format c: A bit drastic, or am i missing something?!?! That was meant as remove anything D related from your system. format c: on a POSIX system, come on. I was clearly not serious. :) -- Marco
Re: Ranges: is it ok if front is a data member?
On Fri, Dec 13, 2013 at 04:20:18PM +0100, Joseph Rushton Wakeling wrote: On 13/12/13 16:52, Marco Leise wrote: Most non-trivial ranges do the actual work in `popFront()' and return a cached value from `front'. It has been argued as a design quirk, that this in general leads to: struct Range { bool popFrontHasBeenCalledOnce = false; T current; @property T front() { if (!popFrontHasBeenCalledOnce) { popFront(); // initializes `current' } return current; } […] } For example in much of std.random. With classes you can get round it by defining a default constructor, but with structs it can create some tricky situations. I have wondered about the feasibility of a method called something like .first() which would basically be called the very first time one calls _any_ method of the struct/class in question, and would perform the appropriate initialization. Hmm. struct First(T) /* bad name, I know */ if (is(T.init.first())) { T impl; bool doneFirst; auto opDispatch(string funcName, A...)(A args) { if (!doneFirst) { impl.first(); doneFirst = true; } alias func = mixin(impl. ~ func); // does this work? return func(args); } } struct MyStructImpl { void first() { ... } void method() { ... } } alias MyStruct = First!MyStructImpl; MyStruct s; s.method(); // calls s.first() first. s.method(); // only calls method(). T -- Жил-был король когда-то, при нём блоха жила.
Re: Allowing string value with getopt without requiring it
On Fri, Dec 13, 2013 at 10:46:57AM +0100, John Colvin wrote: On Friday, 13 December 2013 at 01:51:25 UTC, Ithy wrote: Hello. I'm just getting into D (literally writing my first program), and I can't figure out how to do this with getopt: I want to have the option --log, which will enable logging (set a bool variable to true). However, I want the program to also accept --log=filename to allow the user to define custom log file. If --log is used without filename, a default file will be used. I tried this: getopt(args, log, log, log, logFile); Passing just --log to the program works fine, the boolean is set to true. However, using --log=test.log throws an exception, and seemingly getopt expects either true or false. How would I go about implementing this without creating another option like --log-file for custom file name? That doesn't seem possible with getopt. I would use std.getopt.config.passThrough and then deal with the log option manually afterwards. I would file an enhancement request in the bugtracker. This is a pretty common idiom in command-line parsing. http://d.puremagic.com/issues/ T -- We are in class, we are supposed to be learning, we have a teacher... Is it too much that I expect him to teach me??? -- RL
Re: updating druntime
On Friday, 13 December 2013 at 15:54:06 UTC, Marco Leise wrote: Am Fri, 13 Dec 2013 16:08:22 +0100 schrieb John Colvin john.loughran.col...@gmail.com: On Friday, 13 December 2013 at 15:00:57 UTC, Marco Leise wrote: I'd say format c: A bit drastic, or am i missing something?!?! That was meant as remove anything D related from your system. format c: on a POSIX system, come on. I was clearly not serious. :) Woops, sorry, missed that it was posix :)
ubyte array changing values between calls? Possible bug?
I have the following code which is massively simplified from a larger type. The problem occurs between assigning the value to the type and retrieving it. The value is assigned through opAssign and the assert passes. When using a property to retrieve the same data the assert fails! import std.bitmanip; import std.stdio; import std.traits; struct IpAddress { private ubyte[] _octets; this(uint value) { this.opAssign(value); } public @property ubyte[] data() { assert(this._octets == [1, 2, 3, 4]); return this._octets; } public void opAssign(uint value) { this._octets = value.nativeToBigEndian(); assert(this._octets == [1, 2, 3, 4]); } } unittest { auto ipAddress = IpAddress(0x01020304); assert(ipAddress.data == [1, 2, 3, 4]); } Any ideas why? On a side note i also expected nativeToBigEndian to byte flip the hex literal, no idea why it hasn't, it's been a long day... I'm using MacOSX (Intel). Compiled with: rdmd --force -de -debug -main -property -unittest -w file.d
Re: ubyte array changing values between calls? Possible bug?
On Friday, 13 December 2013 at 16:37:51 UTC, Gary Willoughby wrote: I have the following code which is massively simplified from a larger type. The problem occurs between assigning the value to the type and retrieving it. The value is assigned through opAssign and the assert passes. When using a property to retrieve the same data the assert fails! import std.bitmanip; import std.stdio; import std.traits; struct IpAddress { private ubyte[] _octets; this(uint value) { this.opAssign(value); } public @property ubyte[] data() { assert(this._octets == [1, 2, 3, 4]); return this._octets; } public void opAssign(uint value) { this._octets = value.nativeToBigEndian(); assert(this._octets == [1, 2, 3, 4]); } } unittest { auto ipAddress = IpAddress(0x01020304); assert(ipAddress.data == [1, 2, 3, 4]); } Any ideas why? On a side note i also expected nativeToBigEndian to byte flip the hex literal, no idea why it hasn't, it's been a long day... I'm using MacOSX (Intel). Compiled with: rdmd --force -de -debug -main -property -unittest -w file.d opAssign is escaping a reference to its stack by assigning the static array to the slice _octets. Therefore, garbage.
Re: Performance of ranges verses direct
I found that performance of ranges is miserable in many cases. You should not use them if there is any chance for big/critical computations. Actually I don't like to have two subsets of language: one with good performance, and other with good maintainability/readability. I have a couple thought about this situation. May by we can use CTFE and mixin for inlining some range based code on library level? FYI One of my benchmark (calculate sum of two simple ranges): #!/usr/bin/rdmd module zip_test; import std.range; import std.datetime; import std.getopt; import std.stdio; import std.algorithm; struct Range{ uint count = 0; @property bool empty(){ return count=limit; } @property int front(){ return count; } bool popFront(){ count++; return countlimit; } } uint testForEach(){ Range r1, r2; uint rs = 0; for(int i=0; !r1.empty !r2.empty; i++){ rs += r1.front + r2.front; r1.popFront(); r2.popFront(); } writefln(foreach: %s, rs); return rs; } uint testZip(){ Range r1, r2; auto tmpRange = step1(r1, r2); auto rs = reduce!(q{ a + b })(0U, tmpRange); // auto rs = reduce!((a,b) = a + b)(0U, tmpRange); writefln(zip: %s, rs); return rs; } auto step1(Range r1, Range r2){ //return zip(r1, r2).map!(a = a[0]+a[1]); return zip(r1, r2).map!(q{a[0]+a[1]}); } uint limit = 10_000; void main(string[] args){ getopt( args, limit, limit); auto r = benchmark!(testForEach, testZip)(10); foreach(idx, rs; r){ writefln(%s - %s, idx, rs.msecs); } } Results: ~/ldc2-0.12.0-linux-x86_64/bin/ldmd2 -O -release -inline zip_test.d ./zip_test --limit 1000 … 0 - 0 1 - 764
Re: ubyte array changing values between calls? Possible bug?
It works fine when using dup to the value returned by nativeToBigEndian: public void opAssign(uint value) { this._octets = value.nativeToBigEndian().dup; assert(this._octets == cast (ubyte[]) [1, 2, 3, 4]); } On 12/13/2013 06:35 PM, John Colvin wrote: On Friday, 13 December 2013 at 16:37:51 UTC, Gary Willoughby wrote: I have the following code which is massively simplified from a larger type. The problem occurs between assigning the value to the type and retrieving it. The value is assigned through opAssign and the assert passes. When using a property to retrieve the same data the assert fails! import std.bitmanip; import std.stdio; import std.traits; struct IpAddress { private ubyte[] _octets; this(uint value) { this.opAssign(value); } public @property ubyte[] data() { assert(this._octets == [1, 2, 3, 4]); return this._octets; } public void opAssign(uint value) { this._octets = value.nativeToBigEndian(); assert(this._octets == [1, 2, 3, 4]); } } unittest { auto ipAddress = IpAddress(0x01020304); assert(ipAddress.data == [1, 2, 3, 4]); } Any ideas why? On a side note i also expected nativeToBigEndian to byte flip the hex literal, no idea why it hasn't, it's been a long day... I'm using MacOSX (Intel). Compiled with: rdmd --force -de -debug -main -property -unittest -w file.d opAssign is escaping a reference to its stack by assigning the static array to the slice _octets. Therefore, garbage.
Re: Performance of ranges verses direct
On Friday, 13 December 2013 at 18:03:28 UTC, Nikolay wrote: Results: ~/ldc2-0.12.0-linux-x86_64/bin/ldmd2 -O -release -inline zip_test.d ./zip_test --limit 1000 … 0 - 0 1 - 764 And now try -inline-threshold=1024 ;-) Reading -help-hidden sometimes helps.
Strict capacity of array
Suppose some class contains slice (dynamic array) as data member. Constructor takes integer value that defines the size of data should be allocated. After object was constructed size of slice never changes by design. Dynamic arrays are allocated with extra space that we can know from 'capacity' property. But how can I allocate exactly as much elements as I want? Because in case described above we don't need extra space. I know it's possible to use malloc in constructor and free in destructor. But what if I want to expose inner slice by shallow copy (i.e. by copying pointer and size, but not underlined data) then use it just like usual dynamic array whose lifetime does not depend on lifetime of an object it belongs and is managed by GC?
Re: updating druntime
On Friday, 13 December 2013 at 15:00:57 UTC, Marco Leise wrote: Am Thu, 12 Dec 2013 20:29:31 +0100 schrieb Benji romanbeno...@gmail.com: On Thursday, 12 December 2013 at 19:11:03 UTC, John Colvin wrote: On Thursday, 12 December 2013 at 16:44:28 UTC, Benji wrote: Hello, when I try to compile something with dmd, I get following message: /usr/include/dmd/phobos/std/bitmanip.d(416): Error: undefined identifier '_xopCmp' Error: ICE: _xopCmp not found in object module. You must update druntime How to 'update druntime' ? how did you install dmd/druntime/phobos originally? As it is mentioned in installation instructions to the dmd (linux-ubuntu) Did you use the .deb file? It shouldn't produce such a version mismatch. Did you install over a previous installation and possibly have some leftover files from the old DMD version? I'd say format c: and start over with the installation of DMD. In any case, if you didn't install from the GitHub sources this error message should not appear and someone who isn't hacking on DMD does not have to update druntime manually. Yes, I used :( I tryied it again via zip-archive, and it works... but, using std.net.curl module functions doesn't work for me... This is my error: (after get(google.com) call) [...] In function `_D3std3net4curl4Curl7performMFbZi': std/net/curl.d:(.text._D3std3net4curl4Curl7performMFbZi+0x1f): undefined reference to `curl_easy_perform' /usr/lib/gcc/x86_64-linux-gnu/4.8/../../../../lib/libphobos2.a(curl_248d_4a1.o): In function `_D3std3net4curl4Curl11errorStringMFiZAya': std/net/curl.d:(.text._D3std3net4curl4Curl11errorStringMFiZAya+0x11): undefined reference to `curl_easy_strerror' collect2: error: ld returned 1 exit status When I compile it this way: dmd helloa.d -L-lphobos2 -L-lcurl Another error appear: [...] helloa.d:(.text._D3std6format66__T14formattedWriteTS3std5array17__T8AppenderTAyaZ8AppenderTaTmTmZ14formattedWriteFNaNfS3std5array17__T8AppenderTAyaZ8AppenderxAammZk+0x45): undefined reference to `_D3std6format18__T10FormatSpecTaZ10FormatSpec6__ctorMFNaNcNfxAaZS3std6format18__T10FormatSpecTaZ10FormatSpec' helloa.o: In function `_D3std6format68__T14formattedWriteTS3std5array17__T8AppenderTAyaZ8AppenderTaTmTAyaZ14formattedWriteFNaNfS3std5array17__T8AppenderTAyaZ8AppenderxAamAyaZk': helloa.d:(.text._D3std6format68__T14formattedWriteTS3std5array17__T8AppenderTAyaZ8AppenderTaTmTAyaZ14formattedWriteFNaNfS3std5array17__T8AppenderTAyaZ8AppenderxAamAyaZk+0x49): undefined reference to `_D3std6format18__T10FormatSpecTaZ10FormatSpec6__ctorMFNaNcNfxAaZS3std6format18__T10FormatSpecTaZ10FormatSpec' helloa.o:helloa.d:(.text._D3std6format64__T14formattedWriteTS3std5array17__T8AppenderTAyaZ8AppenderTaTtZ14formattedWriteFNaNfS3std5array17__T8AppenderTAyaZ8AppenderxAatZk+0x40): more undefined references to `_D3std6format18__T10FormatSpecTaZ10FormatSpec6__ctorMFNaNcNfxAaZS3std6format18__T10FormatSpecTaZ10FormatSpec' follow collect2: error: ld returned 1 exit status After 7 hours of effort and trying everything it still doesn't work :((
Re: Strict capacity of array
On 12/13/2013 10:47 AM, FreeSlave wrote: Suppose some class contains slice (dynamic array) as data member. Constructor takes integer value that defines the size of data should be allocated. After object was constructed size of slice never changes by design. Dynamic arrays are allocated with extra space that we can know from 'capacity' property. But how can I allocate exactly as much elements as I want? Because in case described above we don't need extra space. If it is not maintained by you, you can never be sure. There is arr.reserve(N) that ensures that much room without placing .init elements on the space. I know it's possible to use malloc in constructor and free in destructor. But what if I want to expose inner slice by shallow copy (i.e. by copying pointer and size, but not underlined data) then use it just like usual dynamic array whose lifetime does not depend on lifetime of an object it belongs and is managed by GC? That is supported: auto slice = rawPtr[0..number_of_elements]; Ali
Re: updating druntime
Am Fri, 13 Dec 2013 19:48:46 +0100 schrieb Benji romanbeno...@gmail.com: When I compile it this way: dmd helloa.d -L-lphobos2 -L-lcurl Another error appear: [...] helloa.d:(.text._D3std6format66__T14formattedWriteTS3std5array17__T8AppenderTAyaZ8AppenderTaTmTmZ14formattedWriteFNaNfS3std5array17__T8AppenderTAyaZ8AppenderxAammZk+0x45): undefined reference to `_D3std6format18__T10FormatSpecTaZ10FormatSpec6__ctorMFNaNcNfxAaZS3std6format18__T10FormatSpecTaZ10FormatSpec' helloa.o: In function `_D3std6format68__T14formattedWriteTS3std5array17__T8AppenderTAyaZ8AppenderTaTmTAyaZ14formattedWriteFNaNfS3std5array17__T8AppenderTAyaZ8AppenderxAamAyaZk': helloa.d:(.text._D3std6format68__T14formattedWriteTS3std5array17__T8AppenderTAyaZ8AppenderTaTmTAyaZ14formattedWriteFNaNfS3std5array17__T8AppenderTAyaZ8AppenderxAamAyaZk+0x49): undefined reference to `_D3std6format18__T10FormatSpecTaZ10FormatSpec6__ctorMFNaNcNfxAaZS3std6format18__T10FormatSpecTaZ10FormatSpec' helloa.o:helloa.d:(.text._D3std6format64__T14formattedWriteTS3std5array17__T8AppenderTAyaZ8AppenderTaTtZ14formattedWriteFNaNfS3std5array17__T8AppenderTAyaZ8AppenderxAatZk+0x40): more undefined references to `_D3std6format18__T10FormatSpecTaZ10FormatSpec6__ctorMFNaNcNfxAaZS3std6format18__T10FormatSpecTaZ10FormatSpec' follow collect2: error: ld returned 1 exit status After 7 hours of effort and trying everything it still doesn't work :(( And when you compile like this?: dmd helloa.d -L-lcurl This will link in the static version of Phobos and there is only one static (.a) Phobos on any system. -L-lphobos2 might link against the wrong (.so) if you have an old version. I'm just guessing here. -- Marco
Re: Strict capacity of array
Am Fri, 13 Dec 2013 19:47:34 +0100 schrieb FreeSlave freeslav...@gmail.com: Suppose some class contains slice (dynamic array) as data member. Constructor takes integer value that defines the size of data should be allocated. After object was constructed size of slice never changes by design. Dynamic arrays are allocated with extra space that we can know from 'capacity' property. But how can I allocate exactly as much elements as I want? Because in case described above we don't need extra space. There was a recent discussion about the capacity of a dynamic array that is allocated with a known size (e.g. new int[](25)). I think the extra space comes from the way the GC allocates blocks of memory in preset sizes. Actually a malloc implementation could also have some hidden overallocation. I know it's possible to use malloc in constructor and free in destructor. But what if I want to expose inner slice by shallow copy (i.e. by copying pointer and size, but not underlined data) then use it just like usual dynamic array whose lifetime does not depend on lifetime of an object it belongs and is managed by GC? Have you tried this?: import core.memory; int[] data = (cast(int*)GC.malloc(size * int.sizeof, GC.BlkAttr.NO_SCAN))[0 .. size]; -- Marco
Re: static if - is the 'static' really needed?
On Friday, 13 December 2013 at 12:10:02 UTC, comco wrote: Imagine a world in which a simple 'if' has the semantics of a static if, if the condition is evaluable at CT. Is this a world you would rather live in? They are fundamentally two different things. Eliding the difference is not a good idea. I'm with Jesse, I wish we had a static foreach because it's also a significant difference as well. we don't need _static else_ -- why do we even need 'static' in 'static if' by this reasoning? Not exactly sure what the context of this is, but I suspect he was saying we don't need _static else_ because we don't need it to resolve ambiguities in the AST (which is true). OTOH we would need 'static' in 'static if' to resolve the ambiguities in the semantics.
Re: Strict capacity of array
Thanks for answers. On Friday, 13 December 2013 at 19:35:01 UTC, Marco Leise wrote: Have you tried this?: import core.memory; int[] data = (cast(int*)GC.malloc(size * int.sizeof, GC.BlkAttr.NO_SCAN))[0 .. size]; Did you mean GC.BlkAttr.NONE maybe? If I get it right GC.BlkAttr.NO_SCAN means that memory will never be collected by GC (i.e. it's just like C malloc), but I've asked for opposite.
Re: updating druntime
On Friday, 13 December 2013 at 19:22:20 UTC, Marco Leise wrote: Am Fri, 13 Dec 2013 19:48:46 +0100 schrieb Benji romanbeno...@gmail.com: When I compile it this way: dmd helloa.d -L-lphobos2 -L-lcurl Another error appear: [...] helloa.d:(.text._D3std6format66__T14formattedWriteTS3std5array17__T8AppenderTAyaZ8AppenderTaTmTmZ14formattedWriteFNaNfS3std5array17__T8AppenderTAyaZ8AppenderxAammZk+0x45): undefined reference to `_D3std6format18__T10FormatSpecTaZ10FormatSpec6__ctorMFNaNcNfxAaZS3std6format18__T10FormatSpecTaZ10FormatSpec' helloa.o: In function `_D3std6format68__T14formattedWriteTS3std5array17__T8AppenderTAyaZ8AppenderTaTmTAyaZ14formattedWriteFNaNfS3std5array17__T8AppenderTAyaZ8AppenderxAamAyaZk': helloa.d:(.text._D3std6format68__T14formattedWriteTS3std5array17__T8AppenderTAyaZ8AppenderTaTmTAyaZ14formattedWriteFNaNfS3std5array17__T8AppenderTAyaZ8AppenderxAamAyaZk+0x49): undefined reference to `_D3std6format18__T10FormatSpecTaZ10FormatSpec6__ctorMFNaNcNfxAaZS3std6format18__T10FormatSpecTaZ10FormatSpec' helloa.o:helloa.d:(.text._D3std6format64__T14formattedWriteTS3std5array17__T8AppenderTAyaZ8AppenderTaTtZ14formattedWriteFNaNfS3std5array17__T8AppenderTAyaZ8AppenderxAatZk+0x40): more undefined references to `_D3std6format18__T10FormatSpecTaZ10FormatSpec6__ctorMFNaNcNfxAaZS3std6format18__T10FormatSpecTaZ10FormatSpec' follow collect2: error: ld returned 1 exit status After 7 hours of effort and trying everything it still doesn't work :(( And when you compile like this?: dmd helloa.d -L-lcurl This will link in the static version of Phobos and there is only one static (.a) Phobos on any system. -L-lphobos2 might link against the wrong (.so) if you have an old version. I'm just guessing here. I got two errors mentioned above at once.. :(
const method and return type
class A { auto getter() const { return property; } int property = 0; } Please notice that getter method is marked as const. Why this method return const int? If i force it declaring: int getter() const it returns int. It takes me a lot to understand where the issue was in my code. Is it a bug?
Array - Sockets - Clients
Socket[ulong] clients; ---main() ulong index = clients.length; clients[index] = cli; //-- Socket cli send(tid, index) -spawned() receive( (ulong i) { clients[i].send('Hello concurrent'); // Error clients.length is zero } ); - Help me please!
Re: Array - Sockets - Clients
On 12/13/2013 03:53 PM, Irving Montalvo wrote: Socket[ulong] clients; ---main() ulong index = clients.length; clients[index] = cli; //-- Socket cli send(tid, index) -spawned() receive( (ulong i) { clients[i].send('Hello concurrent'); // Error clients.length is zero } ); - Help me please! Data is thread-local by default. clients are not the same array as seen by the two threads. Declare it as 'shared' and pray that you will not have bugs in your data-sharing concurrency app. :) shared Socket[ulong] clients; At least I think that's what is happening there. :) Ali
Re: const method and return type
On Friday, 13 December 2013 at 23:46:14 UTC, Andrea Fontana wrote: class A { auto getter() const { return property; } int property = 0; Why this method return const int? Inside getter, this is const. Due to transitive const, all the members through this are const too. So inside getter, property is a const int. The auto return value returns the *exact* type, thus const.
Re: const method and return type
I read: Const Member Functions Const member functions are functions that are not allowed to change any part of the object through the member function's this reference. I'm not changing anything. Just returning it. Is this a try to avoid something like the following, then? ... B getter() const { return this.b; } ... void getter2() const { B var = getter(); var.non_const_method(); } I don't think it's the right way, is it? getter2() shouldn't be allowed becouse var is a reference to this.b, that's ok. But enforcing constness of return type IMHO is wrong. Something like: void main() { B value = myclass.getter(); b.non_const(); } seems correct to me. Also this seems correct: void getter2() /*non-const*/ { getter().non_const_method(); } On Saturday, 14 December 2013 at 00:01:31 UTC, Adam D. Ruppe wrote: On Friday, 13 December 2013 at 23:46:14 UTC, Andrea Fontana wrote: class A { auto getter() const { return property; } int property = 0; Why this method return const int? Inside getter, this is const. Due to transitive const, all the members through this are const too. So inside getter, property is a const int. The auto return value returns the *exact* type, thus const.
Re: Array - Sockets - Clients
How do I pass a socket to concurrency? send(tid, cli); // Socket cli -- receive ( (Socket cli) { cli.send(1234567890); } ) - Help me :)
Re: Strict capacity of array
Am Fri, 13 Dec 2013 21:02:58 +0100 schrieb FreeSlave freeslav...@gmail.com: Thanks for answers. On Friday, 13 December 2013 at 19:35:01 UTC, Marco Leise wrote: Have you tried this?: import core.memory; int[] data = (cast(int*)GC.malloc(size * int.sizeof, GC.BlkAttr.NO_SCAN))[0 .. size]; Did you mean GC.BlkAttr.NONE maybe? If I get it right GC.BlkAttr.NO_SCAN means that memory will never be collected by GC (i.e. it's just like C malloc), but I've asked for opposite. You got it wrong :) NO_SCAN means that the memory block you allocate isn't scanned for _more_ references to stuff on the GC heap. If you use the allocated memory as an int[] it doesn't make sense to look into it for pointers to other memory blocks in order to mark them alive. (The GC is a marksweep algorithm.) If you actually store class pointers or similar instead of ints then drop that attribute. -- Marco
Re: updating druntime
Am Fri, 13 Dec 2013 21:40:10 +0100 schrieb Benji romanbeno...@gmail.com: I got two errors mentioned above at once.. :( What the heck is happening on your system? :( -- Marco
Re: const method and return type
Just another thought. If we have: class B; struct C; class A { void method() const { ... } B another_class; C a_struct; } B is just a reference to a object, so method() should not reassign it. The reference should be const, not the object itself. method() should be able to call mutable another_class methods. Am I wrong? Instead a_struct is not a reference, so method() should not edit it, this makes sense. You can return a copy or a const ref of a struct-member On Saturday, 14 December 2013 at 00:09:03 UTC, Andrea Fontana wrote: I read: Const Member Functions Const member functions are functions that are not allowed to change any part of the object through the member function's this reference. I'm not changing anything. Just returning it. Is this a try to avoid something like the following, then? ... B getter() const { return this.b; } ... void getter2() const { B var = getter(); var.non_const_method(); } I don't think it's the right way, is it? getter2() shouldn't be allowed becouse var is a reference to this.b, that's ok. But enforcing constness of return type IMHO is wrong. Something like: void main() { B value = myclass.getter(); b.non_const(); } seems correct to me. Also this seems correct: void getter2() /*non-const*/ { getter().non_const_method(); } On Saturday, 14 December 2013 at 00:01:31 UTC, Adam D. Ruppe wrote: On Friday, 13 December 2013 at 23:46:14 UTC, Andrea Fontana wrote: class A { auto getter() const { return property; } int property = 0; Why this method return const int? Inside getter, this is const. Due to transitive const, all the members through this are const too. So inside getter, property is a const int. The auto return value returns the *exact* type, thus const.
Re: const method and return type
On Saturday, 14 December 2013 at 00:24:01 UTC, Andrea Fontana wrote: Just another thought. If we have: class B; struct C; class A { void method() const { ... } B another_class; C a_struct; } B is just a reference to a object, so method() should not reassign it. The reference should be const, not the object itself. method() should be able to call mutable another_class methods. Am I wrong? Yes, in D, all members of a const object are const too. So inside method() const, another_class is const. Which means another_class.member is also const.
Re: Array - Sockets - Clients
On 12/13/2013 04:11 PM, Irving Montalvo wrote: How do I pass a socket to concurrency? send(tid, cli); // Socket cli -- receive ( (Socket cli) { cli.send(1234567890); } ) - Help me :) Unfortunately, some cast(shared) is needed at this time: import std.stdio; import std.socket; import std.concurrency; import core.thread; struct Done {} void main() { shared(Socket)[ulong] clients; clients[1] = cast(shared)new Socket(AddressFamily.UNIX, SocketType.STREAM); auto tid = spawn(server); send(tid, clients[1]); send(tid, Done()); thread_joinAll(); } void server() { bool done = false; while (!done) { receive( (shared(Socket) client) { writeln(received client); }, (Done _) { done = true; } ); } } Ali
Re: const method and return type
On Friday, 13 December 2013 at 23:46:14 UTC, Andrea Fontana wrote: class A { auto getter() const { return property; } int property = 0; } Please notice that getter method is marked as const. Why this method return const int? `const` as a function attribute just marks the implicit this-reference parameter as const - apart from the necessary syntax deviation, it works like any other parameter. Thus, inside `getter`, `typeof(this)` is `const(A)`, and since const is transitive, that means `typeof(this.property)` is `const(int)`. If you explicitly specify the return type as `int`, then `property` is implicitly converted from `const(int)` to `int`, which is legal since `int` has no mutable indirection.
Re: const method and return type
On Saturday, 14 December 2013 at 00:31:24 UTC, Adam D. Ruppe wrote: On Saturday, 14 December 2013 at 00:24:01 UTC, Andrea Fontana wrote: Just another thought. If we have: class B; struct C; class A { void method() const { ... } B another_class; C a_struct; } B is just a reference to a object, so method() should not reassign it. The reference should be const, not the object itself. method() should be able to call mutable another_class methods. Am I wrong? Yes, in D, all members of a const object are const too. So inside method() const, another_class is const. Which means another_class.member is also const. Why? The object itself it's not a member. The reference to that object is the member. Consider this: class A {} class B { A first; A second; } void main() { auto a = new A; auto b = new B; b.first = a; b.second = a; assert(b.first == b.second); assert(b.first == b.second); } Second assert fail, of course. first and second are just two reference. They are different reference to the same object. Those reference should be const, not the object they refer. Consider this way to escape current constness: class A { int x; } A globalA; class B { void method() const { // first.x = 10; This doesn't work. But IMO it should globalA.x = 10; // This work. Same effect as preceding line writeln(first.x); // 10! } A first; A second; } void main() { globalA = new A; auto b = new B; b.first = globalA; b.second = globalA; b.method(); } You see?
Re: const method and return type
On Saturday, 14 December 2013 at 00:53:27 UTC, Andrea Fontana wrote: Consider this way to escape current constness: This isn't escaping constness. Const only means mutation is prevented through that particular reference. It is distinct from immutability.
Re: Array - Sockets - Clients
Thanks! - receive( (shared(Socket) c) { Socket cli = cast(Socket) c; while (cli.isAlive()) { ubyte[8192] buf; ulong bufLen = cli.receive(buf); ... } } );
Re: updating druntime
On Saturday, 14 December 2013 at 00:15:30 UTC, Marco Leise wrote: Am Fri, 13 Dec 2013 21:40:10 +0100 schrieb Benji romanbeno...@gmail.com: I got two errors mentioned above at once.. :( What the heck is happening on your system? :( I plan to install Arch, so hope that will solve it :P