Re: Bug in shifting
On Fri, 14 Dec 2018 00:16:51 +, Michelle Long wrote: > byte x = 0xF; > ulong y = x >> 60; "Error: shift by 60 is outside the range 0..31" This is the result of integer promotion rules. Change the 30 to a 60 and it works, and the result is, as you would expect, 0. > I thought D required breaks for cases? Seems it doesn't any longer! A number of things can terminate a case block: * break * continue * goto * assert * throw * return Probably a few others.
Re: Bug in shifting
On Friday, 14 December 2018 at 02:17:20 UTC, Jonathan M Davis wrote: On Thursday, December 13, 2018 6:56:33 PM MST Steven Schveighoffer via Digitalmars-d-learn wrote: On 12/13/18 7:16 PM, Michelle Long wrote: > I've noticed the compiler is not throwing up errors and > warnings like it used to: > > I thought D required breaks for cases? Seems it doesn't any > longer! I'm only using -g -gf -d It doesn't require breaks for cases, it requires no fall-through on cases. Again, an example would help describe what you mean. Well, to be more precise, it doesn't allow fallthrough when the case statement contains code. It will allow it when it doesn't. e.g. case 0: case 1: break; is perfectly legal. However, when the case statement contains code, then yeah, some form of control statement is required to exit the case statement, but that's a lot more than just break. continue, goto, return, etc. can all be used to exit a case statement. Any control statement that explicitly exits the case statement will work. And of course, goto case can be used for explicit fallthrough. - Jonathan M Davis I thought I had code in it which is what struct me as odd. There is a good chance I was wrong about this though since I was adding a bunch of case statements and code. Given that this occurred with the other problem might correlate to something else. Not that big a yet but the first struck me as a big problem if it is a bug... having code that should error but passes and provides wrong calculations is very prone to producing major bugs in a program. I don't feel like trying to reproduce them, but if they crop up again I'll try and catch them.
Re: Bug in shifting
On Thursday, December 13, 2018 6:56:33 PM MST Steven Schveighoffer via Digitalmars-d-learn wrote: > On 12/13/18 7:16 PM, Michelle Long wrote: > > I've noticed the compiler is not throwing up errors and warnings like it > > used to: > > > > I thought D required breaks for cases? Seems it doesn't any longer! I'm > > only using -g -gf -d > > It doesn't require breaks for cases, it requires no fall-through on > cases. Again, an example would help describe what you mean. Well, to be more precise, it doesn't allow fallthrough when the case statement contains code. It will allow it when it doesn't. e.g. case 0: case 1: break; is perfectly legal. However, when the case statement contains code, then yeah, some form of control statement is required to exit the case statement, but that's a lot more than just break. continue, goto, return, etc. can all be used to exit a case statement. Any control statement that explicitly exits the case statement will work. And of course, goto case can be used for explicit fallthrough. - Jonathan M Davis
Re: Bug in shifting
On 12/13/18 7:16 PM, Michelle Long wrote: byte x = 0xF; ulong y = x >> 60; Surely you meant x << 60? As x >> 60 is going to be 0, even with a ulong. Does not compute the proper value. It seems that the shift amount is wrapped. My code is more complex. The code above does give an error. I am using the code in a template. If I change x to ulong it works as expected. Given that your code above doesn't compile, it's hard to figure out what you mean. Do you have a working example? I've noticed the compiler is not throwing up errors and warnings like it used to: I thought D required breaks for cases? Seems it doesn't any longer! I'm only using -g -gf -d It doesn't require breaks for cases, it requires no fall-through on cases. Again, an example would help describe what you mean. -Steve
Re: Bug in shifting
I do not understand you? What is wrong? It works ok. https://run.dlang.io/is/ZFf0FQ What do you mean by D required breaks for cases? On Fri, Dec 14, 2018 at 1:20 AM Michelle Long via Digitalmars-d-learn < digitalmars-d-learn@puremagic.com> wrote: > byte x = 0xF; > ulong y = x >> 60; > > Does not compute the proper value. > > It seems that the shift amount is wrapped. My code is more > complex. The code above does give an error. I am using the code > in a template. If I change x to ulong it works as expected. > > I've noticed the compiler is not throwing up errors and warnings > like it used to: > > I thought D required breaks for cases? Seems it doesn't any > longer! I'm only using -g -gf -d > > > DMD64 D Compiler v2.083.0 > > >
Bug in shifting
byte x = 0xF; ulong y = x >> 60; Does not compute the proper value. It seems that the shift amount is wrapped. My code is more complex. The code above does give an error. I am using the code in a template. If I change x to ulong it works as expected. I've noticed the compiler is not throwing up errors and warnings like it used to: I thought D required breaks for cases? Seems it doesn't any longer! I'm only using -g -gf -d DMD64 D Compiler v2.083.0
Re: Can you move a disabled this(this) struct in to a container type if it's an rvalue?
On Thursday, 13 December 2018 at 13:17:05 UTC, aliak wrote: Ah. Is there any case where you would not want to do that when you have a T value as parameter? Hypothetically, yes, e.g. an object that contains references to itself. However, D operates on the assumption that you don't have such objects. And even though it can't be statically checked, move and swap do actually perform this check at runtime in debug builds. Operating under that rule, it should be legal to move any values that are passed to you. In fact, I postulate that it *must* be done instead of making copies. Unfortunately, Phobos doesn't agree. struct S { int x; this(this) { x++; } } import std.stdio; writeln(S.init); I would expect that to print S(0). However, it doesn't, which is sad. And, what if it's "this()(auto ref T value)"? Then moving could be dangerous if the parameter was passed as a ref. Or maybe it just wouldn't compile? In that case moving indeed could be dangerous since you'd be modifying caller's state. A workaround is indeed to have different signatures or use `auto ref`. The constructor example in this thread doesn't fully address the difference between copying and moving though, because it's dealing with initialization. A more practical example is an actual container, like an array (simplified for brevity): struct Array(T) { T[] memory; size_t size; void append()(auto ref T x) { static if (__traits(isRef, x)) { import std.conv : emplace; // copy-construct. Note that this is different than doing // memory[size++] = x; // because that will call opAssign instead of initializing + postblit emplace([size++], x); } else { import std.algorithm.mutation : moveEmplace; moveEmplace(x, memory[size++]); } } } That's different from the example being discussed, since assignment inside a constructor gets special treatment: struct Container(T) { T data; this()(auto ref T x) { static if (__traits(isRef, x)) data = x; // this assignment is initialization, so emplace is not needed, copy is being made else moveEmplace(x, data); } }
Re: Print RAM used by arrays
On 12/13/18 4:32 PM, Giovanni Di Maria wrote: Hi. How can I know the amount of RAM allocated by a vector? For example: string[8][1000] array; for(int i=0;i<1000;i++) { array[i]=["","","","","","","",""]; } how can I know the amount of bytes of above matrix? array.sizeof. BUT I would caution that you have used fixed-sized arrays so they will NOT be allocated on the heap, but rather on the stack (or thread-local storage if it's a global). For a variable-sized array, such as string[8][], the .sizeof property is always going to be 2 words. For that case, you need to use the GC to ask for the block size: writeln(GC.sizeof(array.ptr)); Can I clean the memory ofter his use, without use GC? It depends on where you put it. But generally D does not give back any memory to the OS unless asked to do so. But maybe that's not your question? -Steve
Print RAM used by arrays
Hi. How can I know the amount of RAM allocated by a vector? For example: string[8][1000] array; for(int i=0;i<1000;i++) { array[i]=["","","","","","","",""]; } how can I know the amount of bytes of above matrix? Can I clean the memory ofter his use, without use GC? Thank you to everybody Giovanni Di Maria
Re: Can you move a disabled this(this) struct in to a container type if it's an rvalue?
On Thursday, 13 December 2018 at 13:17:05 UTC, aliak wrote: Ah. Is there any case where you would not want to do that when you have a T value as parameter? And, what if it's "this()(auto ref T value)"? Then moving could be dangerous if the parameter was passed as a ref. Or maybe it just wouldn't compile? Here's a version that moves rvalues and either copies lvalues, or fails to compile if it can't: struct Container(T) { T value; this(T value) { import std.algorithm.mutation : move; this.value = move(value); } import std.traits : isCopyable; static if (isCopyable!T) { this(ref T value) { this.value = value; } } } Full example: https://run.dlang.io/is/0dw6zz
Re: Turn GC allocated string into a scoped heap allocation
On 12/13/18 9:06 AM, Per Nordlöw wrote: On Thursday, 13 December 2018 at 13:46:47 UTC, Steven Schveighoffer wrote: If you use loweredExpr as a key in a builtin AA, then you need to make it a heap allocation, because the GC cleans up AAs. I only need it for lookup not for storage. I guess what I meant is that the GC will clean up the AA. But I forgot that you could free the key early, as long as you never use the AA again. However, if you are using it ONLY to lookup, and not store keys, this means you have to take care not to assign values to new keys. The right way to do this is to check if the key exists when doing the lookup, and then idup'ing the key before you store it. something like: if(auto v = tmpKey in AA) { // use *v to deal with the value } else { // store a new value AA[tmpKey.idup] = newValue; } If you are never storing, then you can probably use the .get feature of AAs. If you want to scope destroy, you have to be wary that toLower will return the original string if it's already lowercase. Something like: auto tmpKey = s.toLower; auto toFree = s is tmpKey ? null : tmpKey; scope(exit) GC.free(toFree.ptr); -Steve
Re: Turn GC allocated string into a scoped heap allocation
On Thursday, 13 December 2018 at 13:46:47 UTC, Steven Schveighoffer wrote: If you use loweredExpr as a key in a builtin AA, then you need to make it a heap allocation, because the GC cleans up AAs. -Steve I only need it for lookup not for storage.
Re: Turn GC allocated string into a scoped heap allocation
On 12/13/18 4:38 AM, Per Nordlöw wrote: How do I turn the GC-allocation in toLower() to a scoped heap allocation together with toLowerInPlace() in void f(const scope const(char)[] expr) { import std.uni : toLower; loweredExpr = toLower(expr); // temporary // use loweredExpr as key in hash table } when `loweredExpr` is used as a temporary inside `f`? If you use loweredExpr as a key in a builtin AA, then you need to make it a heap allocation, because the GC cleans up AAs. -Steve
Re: Can you move a disabled this(this) struct in to a container type if it's an rvalue?
On 12/13/18 8:17 AM, aliak wrote: On Thursday, 13 December 2018 at 12:08:22 UTC, Boris-Barboris wrote: On Thursday, 13 December 2018 at 09:51:42 UTC, aliak wrote: [...] You can just move in container constructor: struct S { @disable this(this); this(int i) {} } struct Container(T) { T value; this(T value) { import std.algorithm: move; this.value = value.move; } } void main() { auto a = Container!S(S(3)); } Ah. Is there any case where you would not want to do that when you have a T value as parameter? Probably not an issue. Note that if you take the parameter by value, the T must be an rvalue if it has disabled postblit. In other words, this wouldn't work: S s; auto a = Container!S(s); // error So moving it isn't going to affect anything outside the function. And, what if it's "this()(auto ref T value)"? Then moving could be dangerous if the parameter was passed as a ref. Or maybe it just wouldn't compile? What will happen is then you *could* take an already existing T as a parameter, and the T you pass in will be destroyed upon calling the constructor. move resets the original to the .init value if it has a destructor or postblit. Is it dangerous? Probably not, but you may want to document for anyone who uses the container to expect that. -Steve
Re: Can you move a disabled this(this) struct in to a container type if it's an rvalue?
On Thursday, 13 December 2018 at 12:08:22 UTC, Boris-Barboris wrote: On Thursday, 13 December 2018 at 09:51:42 UTC, aliak wrote: [...] You can just move in container constructor: struct S { @disable this(this); this(int i) {} } struct Container(T) { T value; this(T value) { import std.algorithm: move; this.value = value.move; } } void main() { auto a = Container!S(S(3)); } Ah. Is there any case where you would not want to do that when you have a T value as parameter? And, what if it's "this()(auto ref T value)"? Then moving could be dangerous if the parameter was passed as a ref. Or maybe it just wouldn't compile?
Re: Can you move a disabled this(this) struct in to a container type if it's an rvalue?
On Thursday, 13 December 2018 at 09:51:42 UTC, aliak wrote: Ie: struct S { @disable this(this); this(int i) {} } struct Container(T) { T value; this(T value) { this.value = value; } } void main() { auto a = Container!S(S(3)); // can't do this. } I can build a custom constructor for Container that makes this work: static auto construct(Args...)(auto ref Args args) { import std.algorithm: move; auto value = T(args); auto opt = Container!T.init; opt.value = move(value); return move(opt); } And then "auto a = Container!T.construct(3);" works. But is there a way to do it without adding a custom constructor type? Cheers, - Ali You can just move in container constructor: struct S { @disable this(this); this(int i) {} } struct Container(T) { T value; this(T value) { import std.algorithm: move; this.value = value.move; } } void main() { auto a = Container!S(S(3)); }
Re: Can you move a disabled this struct in to a container type if it's an rvalue?
On Wednesday, 12 December 2018 at 21:11:38 UTC, Paul Backus wrote: On Wednesday, 12 December 2018 at 20:05:18 UTC, aliak wrote: Ie: struct S { @disable this(); this(int i) {} } struct Container(T) { T value; this(auto ref T value) { this.value = value; } } void main() { auto a = Container!S(S(3)); // can't do this. } The only error I get when I compile this has to do with incorrect use of `auto ref`. If I change the constructor's signature to `this()(auto ref T value)`, it works fine. Crap! So sorry, this was supposed to be this(this) and that auto ref is not supposed to be there :( Posted new (and correct) message: https://forum.dlang.org/thread/sasdsmxmikxqfxhtb...@forum.dlang.org
Can you move a disabled this(this) struct in to a container type if it's an rvalue?
Ie: struct S { @disable this(this); this(int i) {} } struct Container(T) { T value; this(T value) { this.value = value; } } void main() { auto a = Container!S(S(3)); // can't do this. } I can build a custom constructor for Container that makes this work: static auto construct(Args...)(auto ref Args args) { import std.algorithm: move; auto value = T(args); auto opt = Container!T.init; opt.value = move(value); return move(opt); } And then "auto a = Container!T.construct(3);" works. But is there a way to do it without adding a custom constructor type? Cheers, - Ali
Turn GC allocated string into a scoped heap allocation
How do I turn the GC-allocation in toLower() to a scoped heap allocation together with toLowerInPlace() in void f(const scope const(char)[] expr) { import std.uni : toLower; loweredExpr = toLower(expr); // temporary // use loweredExpr as key in hash table } when `loweredExpr` is used as a temporary inside `f`?