Re: opAssign() calls members' postblits?
On Saturday, 21 June 2014 at 20:03:26 UTC, Ali Çehreli wrote: Now, http://dlang.org/struct.html#AssignOverload says: ref S opAssign(S s) { Note that opAssign takes by-value. The post-blits that you see are due that copy. i.e. b in main is copied to the argument that opAssign sees. Thank you, this makes sense now.
Question about iteger literals
I have the following programme import std.stdio; bool isDigit(char c) nothrow { return c = '0' c = '9'; } ushort hexValue(char c) nothrow { if( isDigit(c) ) return c - '0'; else if (c = 'a' c = 'f') return c - 'a' + 10; else if (c = 'A' c = 'F') return c - 'A' + 10; else return ushort.max; } void main() { writeln(hexValue('A')); } This example is compiling successfully in DMD 2.064 but in DMD 2.065 a got the following error: /d544/f547.d(12): Error: cannot implicitly convert expression (cast(int)c - 48) of type int to ushort /d544/f547.d(14): Error: cannot implicitly convert expression (cast(int)c - 97 + 10) of type int to ushort /d544/f547.d(16): Error: cannot implicitly convert expression (cast(int)c - 65 + 10) of type int to ushort So I have a question why these expressions are casted to int? I was thinking that result should be of char type. And it could be implicitly converted to ushort (because there is enough place to store result). Is it a bug in compiler or I should insert explicit casts?
Re: Question about iteger literals
Uranuz: bool isDigit(char c) nothrow This function is already in Phobos, it's std.ascii.isDigit. ushort hexValue(char c) nothrow Better to use this signature (assuming you want a ushort result, despite a ubyte suffices and a uint is faster): ushort hexValue(in char c) pure nothrow @safe @nogc else return ushort.max; Special error values are not very safe. Consider the usage of a Nullable!(ubyte, ubyte.max) instead, if you can stand the little abstraction penalty. why these expressions are casted to int? Because in C/C++/D if you perform arithmetic operations among types shorter than int you produce an int. I was thinking that result should be of char type. In general it can't be a char. And it could be implicitly converted to ushort (because there is enough place to store result). The precedent compiler version was wrong, and the bug has being fixed by the great Kenji. If you have an expression like: char - 'a' + 10 It means: [0, 255] - 87 That is [-87, 168] that can't fit in the [0, 65535] range. Currently in D the range value analysis works only on the current expression, so the information from the if(c = 'a' c = 'f') condition is ignored here. There are discussions and even code to fix this: http://forum.dlang.org/thread/lnrc8l$1254$1...@digitalmars.com https://github.com/lionello/dmd/compare/if-else-range https://github.com/D-Programming-Language/dmd/pull/3679 But both Walter and Andrei have so far ignored this significant D improvement, so I don't know if and when it will be added. Bye, bearophile
Re: DMD Fails with fPIC error
Thanks, that did the trick. Here's a summary post for anyone else with the same problem: Problem: DMD uses GCC to perform linking. On Hardened Gentoo (and derivatives like Sabayon), GCC implies -fPIE, which causes linking to fail if phobos and druntime were not compiled with -fPIC. You can check if this is the case by looking at the output of `gcc --version` - it will include the phrase Gentoo Hardened. Workaround A: Dynamically link Phobos instead. $ dmd -defaultlib=:libphobos2.so -fPIC test.d Workaround B: Use a non-hardened compiler, such as Clang or a vanilla build of GCC. (Compiling GCC takes about 7 GB and 40 min, which makes it more expensive than actually fixing the problem). $ env CC=/usr/bin/clang dmd test.d Actual Fix: Compile Phobos and Druntime with PIC=1. Note that for ebuilds, this includes the install target (which presumably does some linking). You can then compile programs with: $ dmd -fPIC test.d Additional Notes: -I've submitted a pull request to the overlay so that PIC is set automatically if hardened GCC is detected. -LDC currently has the same problem. I'll probably look at fixing it in the near future.
Re: Question about iteger literals
ushort hexValue(in char c) pure nothrow @safe @nogc else return ushort.max; I understand what pure, nothrow and @safe mean there. But what @nogc changes in there so I should use this modifier? Is it logical specifier that this function can be used without garbage collector or what?
Re: Question about iteger literals
In expression return c - 'a' + 10; I could think that 10 has type int and resulting value promoted to the largest type. But I don't understand why in expression where both of arguments have type char: return c - '0'; I have resulting type int. It's very strange for me and looks very buggy)
Re: Some kind of RPC exists for D?
On Saturday, 21 June 2014 at 18:22:54 UTC, Paul wrote: I wrote some (JSONRPC and TXTRPC) and used them with vibe. I can send you via email Hi Paul, alternatively you could upload your code to GitHub or some similar place and place the link here. Then you also have a means to proof that the code is your work along with the date of publication. -- Bienlein
Re: Question about iteger literals
Uranuz: But what @nogc changes in there so I should use this modifier? @nogc will be present in dmd 2.066, it means that the function (and all the functions it calls) can't perform operations that cause a call to GC functions. Sometimes GC operations are a source of performance loss. Bye, bearophile
Re: Question about iteger literals
Uranuz: But I don't understand why in expression where both of arguments have type char: return c - '0'; I have resulting type int. It's very strange for me and looks very buggy) In D operations among chars return a int. The same happens in C/C++. If you subtract a char from a char in general you can have a negative result, that can't fit in a char. So what's buggy is your thinking. Bye, bearophile
Re: Question about iteger literals
In D operations among chars return a int. The same happens in C/C++. If you subtract a char from a char in general you can have a negative result, that can't fit in a char. So what's buggy is your thinking. Ok. Thank you! I never thought about it that way
Re: Question about iteger literals
Another stupid question. Using this logic substraction for two uint values should return int too, because it can produce negative result. Am I right or not?
Re: Question about iteger literals
Uranuz: Another stupid question. Using this logic substraction for two uint values should return int too, because it can produce negative result. Am I right or not? There are no stupid questions, there are only some stupid answers. Generally uint - uint generates a result with a [-4_294_967_295, 4__294_967_295] range, that can't fit in an integer. I think D here makes an exception to its rule, to avoid too many casts. Because too many casts make the code even less safe than breaking the range assignments rules. Bye, bearophile
Re: Question about iteger literals
On Sunday, 22 June 2014 at 11:57:48 UTC, Uranuz wrote: Another stupid question. Using this logic substraction for two uint values should return int too, because it can produce negative result. Am I right or not? Now this code import std.stdio; void main() { uint a = 50; uint b = 60; auto c = a - b; writeln(typeid(c)); } produce output uint. It's some breakage in my logic. I am thinking that all integer-like types should behave similar way. I perceive char type as ubyte, that should be printed as symbol when using functions like writeln(). But the folowing example import std.stdio; void main() { ubyte a = 50; ubyte b = 60; auto c = a - b; writeln(typeid(c)); } produces output int like you said. Why there are so complicated rules in the *new* language. It's hard to understand the logic.
Re: Question about iteger literals
Uranuz: Why there are so complicated rules in the *new* language. It's hard to understand the logic. Despite D being only 14 years old, one of its rules is to (usually) give the same results if you write code that is valid in C. This means it has to follow many rules of C language. If you try your code in C you will see some similar results. This rule of D is quite handy. Other reasons for the current design of D is that sometimes practicality beats design purity, because D is an engineering product. And I guess another reason is that Walter is not a mathematician nor a computer science theorist, so he has not seen some more principled designs, or he has not appreciated them because of their more formal nature. Bye, bearophile
Re: Question about iteger literals
If these rules are not so clear and have some exceptions (but I don't understand why they are needed) then some documentation needed about this. But I would prefer to have result of uint substraction like uint, and char substraction like char. If we will changing all the types it will be kind of mess. Using this logic we should have some bigger type for int multiplication operator to fit in result of multiplication of int.max*int.max. I know that some assembler operations do this and multiplication of two registers with byte size results in placing product into two result register. But in context of higher level programming language it's better to have better type consistensy. Or we will nead a bigger type to store product for ulong.max*ulong.max result. Is it good or not?
mixin(__MODULE__) fails if module name is module
E.g.: module.d: (or just `module module;` in source file) ``` import std.stdio; void main() { foreach (m; __traits(allMembers, mixin(__MODULE__))) { // module.d-mixin-4(4): Error: expression expected, not 'module' writeln(m); } } ``` Documentation says: Package names cannot be keywords, hence the corresponding directory names cannot be keywords, either. Shouldn't keywords be disallowed for module names?
Re: mixin(__MODULE__) fails if module name is module
sigod: Shouldn't keywords be disallowed for module names? I agree. (Walter seems not too keen on strictness). This question seems more fit for the main D newsgroup. Look in Bugzilla if there is a enhancement request. Bye, bearophile
Re: mixin(__MODULE__) fails if module name is module
On Sunday, 22 June 2014 at 12:52:11 UTC, sigod wrote: module.d: (or just `module module;` in source file) I was wrong about `module module;` declaration.
Re: mixin(__MODULE__) fails if module name is module
This question seems more fit for the main D newsgroup. Should I create new thread in the main newsgroup? Look in Bugzilla if there is a enhancement request. Yeah. I found one: https://issues.dlang.org/show_bug.cgi?id=456
package reflection
In the video Case Studies In Simplifying Code With Compile-Time Reflection [was pointed out][0] that it is possible to reflect on imported packages. So, I tried: reflection.d: ``` import std.stdio; import test.module1; import test.module2; void main() { foreach (m; __traits(allMembers, mixin(__MODULE__))) { writeln(m); } writeln(--); foreach (m; __traits(allMembers, test)) { writeln(m); } } ``` test/module1.d: ``` module test.module1; void module_1() {} ``` test/module2.d: ``` module test.module2; void module_2() {} ``` It produces: ``` $ rdmd reflection.d object std test main -- object module_1 ``` As you see `module_2` wasn't listed. If I change order of import declarations `module_2` will be listed instead of `module_1`. I also tried to create `test/package.d` and publicly import other modules through it, but it behave in the same way. So, how to reflect on imported packages? [0]: http://youtu.be/xpImt14KTdc?t=42m26s
Re: package reflection
On 2014-06-22 14:11:58 +, sigod said: In the video Case Studies In Simplifying Code With Compile-Time Reflection [was pointed out][0] that it is possible to reflect on imported packages. So, I tried: reflection.d: ``` import std.stdio; import test.module1; import test.module2; void main() { foreach (m; __traits(allMembers, mixin(__MODULE__))) { writeln(m); } writeln(--); foreach (m; __traits(allMembers, test)) { writeln(m); } } ``` test/module1.d: ``` module test.module1; void module_1() {} ``` test/module2.d: ``` module test.module2; void module_2() {} ``` It produces: ``` $ rdmd reflection.d object std test main -- object module_1 ``` As you see `module_2` wasn't listed. If I change order of import declarations `module_2` will be listed instead of `module_1`. I also tried to create `test/package.d` and publicly import other modules through it, but it behave in the same way. So, how to reflect on imported packages? [0]: http://youtu.be/xpImt14KTdc?t=42m26s This is very frustrating indeed, and I have an open bug request about it. Please bump it so it gets some attention: https://issues.dlang.org/show_bug.cgi?id=11595 -Shammah
Re: What is the correct way to forward method calls to the struct field?
Thanks a lot! There is a problem though: when i pass incorrect parameters to such a method, it says, that S has no such field, which is a misleading error message.
Re: What is the correct way to forward method calls to the struct field?
There is also a problem: when i declare opDispatch to be private, i still have access to this forwarding from another package. Is it a bug or what?
Re: What is the correct way to forward method calls to the struct field?
On Sun, Jun 22, 2014 at 5:04 PM, monnoroch via Digitalmars-d-learn digitalmars-d-learn@puremagic.com wrote: There is also a problem: when i declare opDispatch to be private, i still have access to this forwarding from another package. Is it a bug or what? I don't know. I never used private in conjunction with a template. Let's hope someone more knowledgeable than me can answer this.
Re: What is the correct way to forward method calls to the struct field?
On Sun, Jun 22, 2014 at 5:02 PM, monnoroch via Digitalmars-d-learn digitalmars-d-learn@puremagic.com wrote: Thanks a lot! There is a problem though: when i pass incorrect parameters to such a method, it says, that S has no such field, which is a misleading error message. You can test the mixin with static if, like this: struct SomeT { int foo(double d) { return 0;} void bar(double d) { return;} } struct S { auto opDispatch(string name, Args...)(Args args) { static if (is(typeof(mixin((*iface). ~ name)(args return mixin((*iface). ~ name)(args); else pragma(msg, S. ~ name ~ cannot be called with arguments of type ~ Args.stringof); } SomeT** iface; } void main() { SomeT st; SomeT* st_p = st; SomeT** st_p_p = st_p; S s = S(st_p_p); s.foo(3.14); s.foo(abc); s.bar(abc, 3.14); }
Re: What is the correct way to forward method calls to the struct field?
Nah, this gives me lots of compiler crap, like .empty and others, when compiler tries to compile them.
Re: What is the correct way to forward method calls to the struct field?
Cool! Only this does not show me where the error was. __FILE__ and __LINE__ is not any help here, because it's a template. Any other way to find out where the actual error was?
very short pipeShell program
After hours of reading (obviously not comprehending) std.process and looking at code samples, I still can't even do something this simple. Open a Windows command line and run miscellaneous commands. Only the first command, dir is shown in the final output. auto pipe = pipeShell(dir, Redirect.all); pipe.stdin.writeln(cd); pipe.stdin.writeln(whomai); pipe.stdin.flush(); pipe.stdin.close(); foreach(str; pipe.stdout.byLine) writefln(from shell: %s,str); I tried putting the wait() command was well in various places. to no avail.
Re: very short pipeShell program
On 06/22/2014 05:01 PM, WhatMeWorry wrote: After hours of reading (obviously not comprehending) std.process and looking at code samples, I still can't even do something this simple. Open a Windows command line and run miscellaneous commands. Only the first command, dir is shown in the final output. auto pipe = pipeShell(dir, Redirect.all); pipe.stdin.writeln(cd); pipe.stdin.writeln(whomai); Typo: whoami pipe.stdin.flush(); pipe.stdin.close(); foreach(str; pipe.stdout.byLine) writefln(from shell: %s,str); I tried putting the wait() command was well in various places. to no avail. As I understand it, the returned 'pipe' is used to communicate with the command passed to pipeShell. Since 'dir' does not understand 'cd', 'whoami', etc. it fails for you. I tried the following on Linux and it worked. I think you must replace bash with cmd on Windows: import std.stdio; import std.process; void main() { auto pipe = pipeShell(bash, Redirect.all); pipe.stdin.writeln(dir); pipe.stdin.writeln(cd); pipe.stdin.writeln(whoami); pipe.stdin.flush(); pipe.stdin.close(); foreach(str; pipe.stdout.byLine) writefln(from shell: %s,str); } Ali
Passing around a list of differently typed functions
As the subject says, I would like to pass around an array of functions. The trick is, that the functions have different type signatures. Is there a way to put the two functions int foo(int a, int b); bool bar(bool a, bool b); into one array, that I can pass around and cast as necessary? Thanks, Evan