Overflow-safe use of unsigned integral types
One of the challenges when working with unsigned types is that automatic wraparound and implicit conversion can combine to unpleasant effect. Consider e.g.: void foo(ulong n) { writeln(n); } void main() { foo(-3); } ... which will output: 18446744073709551613 (or, ulong.max + 1 - 3). Is there a recommended way to handle this kind of potential wraparound where it is absolutely unacceptable? I've considered the following trick: void bar(T : ulong)(T n) { static if (isSigned!T) { enforce(n = 0);// or assert, depending on your priorities } writeln(n); } ... but it would be nice if there was some kind of syntax sugar in place that would avoid such a verbose solution. I know that there have been requests for runtime overflow detection that is on by default (bearophile?), but it could be good to have some simple way to indicate really, no overflow even where by default it's not provided. (Motivation: suppose that you have some kind of function that takes a size_t and uses that to determine an allocation. If a negative number gets passed by accident, the function will thus try to allocate 2^64 - n elements, and your computer will have a very happy time...:-)
Re: Overflow-safe use of unsigned integral types
On Sunday, 10 November 2013 at 12:05:45 UTC, Joseph Rushton Wakeling wrote: One of the challenges when working with unsigned types is that automatic wraparound and implicit conversion can combine to unpleasant effect. Consider e.g.: void foo(ulong n) { writeln(n); } void main() { foo(-3); } ... which will output: 18446744073709551613 (or, ulong.max + 1 - 3). Is there a recommended way to handle this kind of potential wraparound where it is absolutely unacceptable? I've considered the following trick: void bar(T : ulong)(T n) { static if (isSigned!T) { enforce(n = 0);// or assert, depending on your priorities } writeln(n); } ... but it would be nice if there was some kind of syntax sugar in place that would avoid such a verbose solution. I know that there have been requests for runtime overflow detection that is on by default (bearophile?), but it could be good to have some simple way to indicate really, no overflow even where by default it's not provided. (Motivation: suppose that you have some kind of function that takes a size_t and uses that to determine an allocation. If a negative number gets passed by accident, the function will thus try to allocate 2^64 - n elements, and your computer will have a very happy time...:-) When writing software for embedded micros you can always check an overflow flag - is the no such mechanism on PC software? -=mike=-
Object construction and this
Could somebody explain why this http://dpaste.dzfl.pl/248262b9 return this: Foo: 7FBFD59A50 7FBFD59A80 Bar: 7FBFD59A58 7FBFD59A88 Why this value in ctor is different from this value out of ctor if ctor gets an argument?
Re: Object construction and this
On Sunday, 10 November 2013 at 16:06:40 UTC, Alexandr Druzhinin wrote: Could somebody explain why this http://dpaste.dzfl.pl/248262b9 return this: Foo: 7FBFD59A50 7FBFD59A80 Bar: 7FBFD59A58 7FBFD59A88 Why this value in ctor is different from this value out of ctor if ctor gets an argument? The bar values are different, too. And they are, because you're printing the addresses of the references (variables), not the addresses of the objects. You can use cast(void*) to get the address of an object: class Bar { this() { writeln(cast(void*) this); } } void main() { writeln(Bar:); auto bar = new Bar(); writeln(cast(void*) bar); } --- Bar: 7FDBD5BFEFF0 7FDBD5BFEFF0
Re: Object construction and this
Am 10.11.2013 17:06, schrieb Alexandr Druzhinin: Could somebody explain why this http://dpaste.dzfl.pl/248262b9 return this: Foo: 7FBFD59A50 7FBFD59A80 Bar: 7FBFD59A58 7FBFD59A88 Why this value in ctor is different from this value out of ctor if ctor gets an argument? Because in D Classes are reference types. That means the code you wrote is equivalent to the following C++ source: class Foo { public: Foo(Object* o) { printf(%x\n, this); // print a Foo** } } class Bar { public: Bar() { printf(%x\n, this); // print a Bar** } } void main() { Object* o = new Object; Foo* foo = new Foo(o); printf(%x\n, foo); // print a Foo** Bar* bar = new Bar(); printf(%x\n, bar); // print a Bar** } My best guess would be that you wanted to pass this instead of this to writeln as weel as bar instead of bar etc. Kind Regards Benjamin Thaut
Re: Object construction and this
10.11.2013 23:22, Benjamin Thaut пишет: Am 10.11.2013 17:06, schrieb Alexandr Druzhinin: Because in D Classes are reference types. That means the code you wrote is equivalent to the following C++ source: class Foo { public: Foo(Object* o) { printf(%x\n, this); // print a Foo** } } class Bar { public: Bar() { printf(%x\n, this); // print a Bar** } } void main() { Object* o = new Object; Foo* foo = new Foo(o); printf(%x\n, foo); // print a Foo** Bar* bar = new Bar(); printf(%x\n, bar); // print a Bar** } My best guess would be that you wanted to pass this instead of this to writeln as weel as bar instead of bar etc. Kind Regards Benjamin Thaut Yes, of course I should pass this instead of this, thanks. I was looking for bug in wrong place - and using let me hope I found it. :) But kind people didn't let me get up on the wrong way. Thanks!
Re: Delegate function access to classes local variable
On Friday, 8 November 2013 at 13:19:05 UTC, Colin Grogan wrote: On Friday, 8 November 2013 at 13:14:33 UTC, Timon Gehr wrote: On 11/08/2013 01:43 PM, Colin Grogan wrote: Hi folks, I'm having some issue getting a delegate function access to a classes member variable. At object construct time, I'm passing in a delegate function, and a list of parameters after. The parameters are saved to a variable called vars. Should I then not be able to access that vars variable from inside my delegate function? I guess some code is a better explanation: import std.stdio; void main() { Column!string col1 = new Column!string( {return test; }, Hello, ); Column!string col2 = new Column!string( {return vars[0]; }, World); // Compilation fail!! Delegate cant see vars[0] It is not even in scope here. writef(%s, col1.nextValue); writefln(%s, col2.nextValue); // I want it to print Hello, World here } public class Column(Vars...){ private Vars vars; public string delegate() func; public this(string delegate() func, Vars vars){ this.vars = vars; this.func = func; } public string nextValue(){ return this.func(); } } The compilation error is: source/app.d(5): Error: undefined identifier vars This has been wrecking my head for a couple days now, I'm half way resigned to the fact it cant work but said I'd ask here to be sure. Thanks! import std.stdio; void main(){ Column!string col1 = new Column!string((ref m)=Hello, , test); Column!string col2 = new Column!string((ref m)=m.vars[0], World); writef(%s, col1.nextValue); writefln(%s, col2.nextValue); } public class Column(Vars...){ struct Members{ Vars vars; } private Members members; alias members this; string delegate(ref Members) func; this(string delegate(ref Members) func, Vars vars){ this.vars = vars; this.func = func; } string nextValue(){ return func(members); } } Ah, brilliant! I like that construct. Thank you! My optimism may have been premature. After trying this out today, I havent been able to pass in anything more complex than a 1 line to the constructor. For example, Column!(int, int) randonNumberColumn = new Column!(int, int)((ref m)=to!string(uniform(m.vars[0], m.vars[1])), 1, 10); will work. However, Column!(int, int) incrementalNumberColumn = new Column!(int, int)((ref m)={m.vars[0]+=m.vars[1]; return to!string(m.vars[0]-m.vars[1]);}, 1,2); wont. Maybe my syntax is just wrong or this is simply a limitation? Also, if you could explain what the = operator is doing there that would be great. I couldnt find the info on it in the docs...
Re: Overflow-safe use of unsigned integral types
On Sunday, 10 November 2013 at 12:19:18 UTC, mike james wrote: When writing software for embedded micros you can always check an overflow flag - is the no such mechanism on PC software? This is not overflow checking, it's the compiler considering a variable of type int implicitely convertible to equivalent unsigned types at bit level. I suppose it's a bug or may be the documentation is wrong (http://dlang.org/type.html): ubyte u1 = cast(byte)-1; // error, -1 cannot be represented in a ubyte ushort u2 = cast(short)-1; // error, -1 cannot be represented in a ushort These two lines are succesfully compiled by the last DMD on Windows.
Re: Delegate function access to classes local variable
On 11/10/2013 09:03 PM, Colin Grogan wrote: For example, Column!(int, int) randonNumberColumn = new Column!(int, int)((ref m)=to!string(uniform(m.vars[0], m.vars[1])), 1, 10); will work. However, Column!(int, int) incrementalNumberColumn = new Column!(int, int)((ref m)={m.vars[0]+=m.vars[1]; return to!string(m.vars[0]-m.vars[1]);}, 1,2); wont. Maybe my syntax is just wrong or this is simply a limitation? This will work: Column!(int, int) incrementalNumberColumn = new Column!(int, int)((ref m){m.vars[0]+=m.vars[1];return to!string(m.vars[0]-m.vars[1]);}, 1,2); Also, if you could explain what the = operator is doing there that would be great. I couldnt find the info on it in the docs... (ref m)=exp is the same as (ref m){ return exp; } http://dlang.org/expression.html#Lambda (hence (ref m)={return exp; } which is the same as (ref m)=(){ return exp; } is the same as (ref m)=()=exp the return type of this expression is 'string delegate()' instead of string and therefore the compiler rejects your code.)
dchar literals?
OK, maybe I'm slow today. Is there an easy way to write a dchar literal? I tend to use either: ad[0] or: cast(dchar)'a' Because 'a'd does not work...
Re: Overflow-safe use of unsigned integral types
On Sunday, November 10, 2013 21:40:14 rumbu wrote: On Sunday, 10 November 2013 at 12:19:18 UTC, mike james wrote: When writing software for embedded micros you can always check an overflow flag - is the no such mechanism on PC software? This is not overflow checking, it's the compiler considering a variable of type int implicitely convertible to equivalent unsigned types at bit level. I suppose it's a bug or may be the documentation is wrong (http://dlang.org/type.html): ubyte u1 = cast(byte)-1; // error, -1 cannot be represented in a ubyte ushort u2 = cast(short)-1; // error, -1 cannot be represented in a ushort These two lines are succesfully compiled by the last DMD on Windows. Casts are never checked on integral types, so the documentation is outright wrong in this case: https://d.puremagic.com/issues/show_bug.cgi?id=11493 The only checks that are done with casts are 1. whether the compiler can convert from the original type to the requested type (which has nothing to do with the values of anything - just the types) 2. whether a class instance is actually of the type beng cast to (and if it isn't, the cast results in null) When you cast, you're generally telling the compiler that you know what you're doing and don't care what the compiler thinks about whether one value should be converted to the other just so long as the types can do the conversion. - Jonathan M Davis
Re: dchar literals?
On Sunday, November 10, 2013 22:13:04 Philippe Sigaud wrote: OK, maybe I'm slow today. Is there an easy way to write a dchar literal? I tend to use either: ad[0] or: cast(dchar)'a' Because 'a'd does not work... I always do the cast, though honestly, I think that character literals should default to dchar rather than char. I'm not sure that we could ever talk Walter into that though, particularly if he thought that doing so would break code (I'm not sure whether it would or not, but using char for a character is almost always a bad idea, so defaulting to char for character literals just doesn't make sense to me). I'm not aware of there being a shorter way to get character literal to be dchar, though I suppose that if you had to do it a lot, you could create a function with a short name. e.g. dchar toDC(dchar d) { return d; } and end up with toDC('a') instead of cast(dchar)'a'; but I'd probably just use the cast. It certainly sounds like a nice enhancement though to be able to do 'a'd especially if the c and w versions gave errors when the character wouldn't fit in a char or wchar, which isn't the case with a cast. - Jonathan M Davis
Re: Overflow-safe use of unsigned integral types
On Sunday, November 10, 2013 12:10:23 Joseph Rushton Wakeling wrote: One of the challenges when working with unsigned types is that automatic wraparound and implicit conversion can combine to unpleasant effect. Consider e.g.: void foo(ulong n) { writeln(n); } void main() { foo(-3); } ... which will output: 18446744073709551613 (or, ulong.max + 1 - 3). Is there a recommended way to handle this kind of potential wraparound where it is absolutely unacceptable? I've considered the following trick: void bar(T : ulong)(T n) { static if (isSigned!T) { enforce(n = 0);// or assert, depending on your priorities } writeln(n); } ... but it would be nice if there was some kind of syntax sugar in place that would avoid such a verbose solution. If you wanted to do that, you could simply do void bar(T)(T n) if(isUnsigned!T) { ... } and make it so that only unsigned types (and therefore only positive values) are accepted without casting. I know that there have been requests for runtime overflow detection that is on by default (bearophile?), but it could be good to have some simple way to indicate really, no overflow even where by default it's not provided. (Motivation: suppose that you have some kind of function that takes a size_t and uses that to determine an allocation. If a negative number gets passed by accident, the function will thus try to allocate 2^64 - n elements, and your computer will have a very happy time...:-) Honestly, I wouldn't worry about it. It's a good idea to avoid unsigned types when you don't need them in order to avoid problems like this (though size_t is one case, where you have to deal with an unsigned type), but in my experience, overflow problems like this are rare, and testing usually finds problems like this in the rare cases that they do happen. I think that the only reason to really be concerned about it is if you feel that you need to be paranoid about it for some reason. But if you really need to protect against it, I think that the only way to really do it cleanly is to create your own int struct type which protects you - similar to a NonNullable struct but for protecting against integer overflow. And I really think that the situation is very similar to that of nullable references/pointers. You _can_ run into problems with them, but it's rarely a problem unless you do a lot with null and aren't careful about it, and if you're paranoid about it, you use NonNullable. It's just that in this case, instead of worrying about null, you're worrying about integer overflow. Ultimately, I think that it's about the same thing and the the solutions for the two are about the same. - Jonathan M Davis
Re: dchar literals?
Jonathan M Davis: It certainly sounds like a nice enhancement though to be able to do 'a'd especially if the c and w versions gave errors when the character wouldn't fit in a char or wchar, which isn't the case with a cast. I have added your idea to the bug report that I opened time ago: https://d.puremagic.com/issues/show_bug.cgi?id=11103 Bye, bearophile
Is there any way to check if array is dense or not?
As described on http://wiki.dlang.org/Dense_multidimensional_arrays we can have dense and jagged arrays. That's nice. Is it possible to check if an array is jagged or not by using some template like std.traits : isArray ?
Re: Is there any way to check if array is dense or not?
Mariusz `shd` Gliwiński: As described on http://wiki.dlang.org/Dense_multidimensional_arrays we can have dense and jagged arrays. Built-in D arrays are always dense (unless you consider the associative arrays). That page should name them contiguous. Sparse arrays are another thing, and they need to be implemented in libraries: http://en.wikipedia.org/wiki/Sparse_array Is it possible to check if an array is jagged or not by using some template like std.traits : isArray ? To tell if a dynamic array is jagged you need a run-time tests, something like this: foreach (const row; matrix) assert(row.length == matrix.front.length); If you want to tell apart a regular dynamic array from the contiguous one, you have to look at the array structure, all dimensions but the last one need to be fixed-sized arrays. There are traits to tell apart fixed sized arrays and dynamic ones, but you need a recursive template. Why do you need this information? So far I have not needed it. Bye, bearophile
Re: Get variable symbol name that was passed to a paramater?
On Saturday, 9 November 2013 at 11:07:08 UTC, Dicebot wrote: On Saturday, 9 November 2013 at 09:12:21 UTC, Rob T wrote: It works except when passing a variable contained inside a struct or class due to a missing this during evaluation, I'm also worried about template bloat. I figure mixins may help, but not if it's same or less convenient to use as the double entry method. Any suggestions, or is it just impossible or not worth trying? I have not found good workaround for this so far and consider it a main use case for template alias parameter enhancement. There are other corner cases where alias for the inspect function will fail. For example, when used inside a class or struct method, a compiler error results stating that the symbol is not accessible to a non-global function. It may be that enhancing alias is not the right way to solve this problem. As was mentioned, the other method of importing and parsing the source file won't scale well and are ridiculous overkill for what should be a simple thing to do. --rt
Re: Get variable symbol name that was passed to a paramater?
On Sunday, 10 November 2013 at 00:08:11 UTC, Timothee Cour wrote: [...] I've already asked for this in the past (see email: feature request: __ARGS__ for logging (cf __FILE__, __LINE__, __FUNC___): but Jacob pointed out that AST macros would make this un-necessary (like wise with another proposal I made proposal: a new string litteral to embed variables in a string ): I don't think that __ARGS__ is a bad idea, I just think that there are several features in D which could be replaced with a library solution using AST macros (if those were available) So let's either get a roadmap for introducing AST macros (preferred) or let's allow this very simple __ARGS__ in the language. Agreed. I did think that AST macro's may present a solution, also the __ARGS__ solution is a good possibility too. I use __PRETTY_FUNCTION__ a lot now that we finally got it, and __ARGS__ would be an excellent addition that I would definitely use. If AST macros can allow us to define library solutions to create something like __PRETTY_FUNCTION__ and __ARGS__, that would be the ultimate solution for sure. --rt
Re: Get variable symbol name that was passed to a paramater?
On Monday, 11 November 2013 at 00:59:03 UTC, Rob T wrote: There are other corner cases where alias for the inspect function will fail. For example, when used inside a class or struct method, a compiler error results stating that the symbol is not accessible to a non-global function. It may be that enhancing alias is not the right way to solve this problem. As was mentioned, the other method of importing and parsing the source file won't scale well and are ridiculous overkill for what should be a simple thing to do. What I mean is that template alias parameter is intended to be a pass-by-name thing. But the way it works it capture the symbol name tied to the type, not symbol name of actual instance. As it is a template it should be always possible to refer to variable/field valid in instantiating context via such aliased name without loosing actual data context. But it will require considerably more powerful alias definition.
how to handle void arguments in generic programming ?
The code snippet below doesn't work. Is there a way to make it work? import std.stdio; void main(){ writelnIfNonVoid(writeln(ok)); } void writelnIfNonVoid(T...)(T a){ static if(T.length) writeln(a); }
Re: Overflow-safe use of unsigned integral types
On 10.11.2013. 12:10, Joseph Rushton Wakeling wrote: One of the challenges when working with unsigned types is that automatic wraparound and implicit conversion can combine to unpleasant effect. Consider e.g.: void foo(ulong n) { writeln(n); } void main() { foo(-3); } ... which will output: 18446744073709551613 (or, ulong.max + 1 - 3). Is there a recommended way to handle this kind of potential wraparound where it is absolutely unacceptable? I've considered the following trick: void bar(T : ulong)(T n) { static if (isSigned!T) { enforce(n = 0);// or assert, depending on your priorities } writeln(n); } ... but it would be nice if there was some kind of syntax sugar in place that would avoid such a verbose solution. I know that there have been requests for runtime overflow detection that is on by default (bearophile?), but it could be good to have some simple way to indicate really, no overflow even where by default it's not provided. (Motivation: suppose that you have some kind of function that takes a size_t and uses that to determine an allocation. If a negative number gets passed by accident, the function will thus try to allocate 2^64 - n elements, and your computer will have a very happy time...:-) Just for reference: http://forum.dlang.org/thread/kn3f9v$25pd$1...@digitalmars.com