digitalmars.D.learn - uint[3] not equivalent to void[12]?
- Ralph Doncaster (13/13) Feb 09 2018 This seems odd to me. Is there a way I can make a function that
- Mike Parker (25/39) Feb 09 2018 void has no size, so what does it mean to have 12 of them?
- Mike Parker (6/18) Feb 09 2018 Also, it's worth mentioning in case you aren't aware that this
- Ralph Doncaster (16/35) Feb 09 2018 according to the docs and my testing, the size of a void array
- Nicholas Wilson (22/61) Feb 09 2018 uint[3] and void[12] have the same size but are different types
- Ralph Doncaster (3/22) Feb 09 2018 Thanks. That's what I thought. If I stick with using D, I'll
- H. S. Teoh (14/29) Feb 09 2018 You probably didn't mean to pass a static array, because those are
This seems odd to me. Is there a way I can make a function that takes an array of any type but only of a specific size in bytes? void.d(8): Error: function void.foo (void[12] arr) is not callable using argument types (uint[3]) Failed: ["/usr/bin/dmd", "-v", "-o-", "void.d", "-I."] void foo(void [12] arr) { } void main() { uint[3] arr; foo(arr); }
Feb 09 2018
On Friday, 9 February 2018 at 15:05:33 UTC, Ralph Doncaster wrote:This seems odd to me. Is there a way I can make a function that takes an array of any type but only of a specific size in bytes? void.d(8): Error: function void.foo (void[12] arr) is not callable using argument types (uint[3]) Failed: ["/usr/bin/dmd", "-v", "-o-", "void.d", "-I."] void foo(void [12] arr) { } void main() { uint[3] arr; foo(arr); }void has no size, so what does it mean to have 12 of them? Here are a couple of options, depending on what you need. ==== import std.stdio; enum numBytes = 12; void foo(T, size_t N)(T[N] arr) if((N * T.sizeof) == numBytes) { writeln(arr); } void bar(ubyte[12] arr) { writeln(arr); } void main() { uint[3] arr = [20, 10, 1]; foo(arr); bar(cast(ubyte[12])arr); } === Output: [20, 10, 1] [20, 0, 0, 0, 10, 0, 0, 0, 1, 0, 0, 0]
Feb 09 2018
On Friday, 9 February 2018 at 15:24:27 UTC, Mike Parker wrote:==== import std.stdio; enum numBytes = 12; void foo(T, size_t N)(T[N] arr) if((N * T.sizeof) == numBytes) { writeln(arr); } void bar(ubyte[12] arr) { writeln(arr); }Also, it's worth mentioning in case you aren't aware that this can be expensive, depending on the size of the array. Static arrays are passed by value. You may want to make the arr parameters ref or, if you want to protect the contents, const ref: void foo(T, size_t N)(ref const(T)[N] arr)
Feb 09 2018
On Friday, 9 February 2018 at 15:24:27 UTC, Mike Parker wrote:On Friday, 9 February 2018 at 15:05:33 UTC, Ralph Doncaster wrote:according to the docs and my testing, the size of a void array element is 1, so the following code prints 12: import std.stdio; void foo(void [] arr) { writeln("length: " arr.length); } void main() { uint[3] arr; foo(arr); } I thought about using templates, but I was looking for a simple way of making a function that takes an array of 12 bytes, whether it is uint[3], ubyte[12], or ushort[6].This seems odd to me. Is there a way I can make a function that takes an array of any type but only of a specific size in bytes? void.d(8): Error: function void.foo (void[12] arr) is not callable using argument types (uint[3]) Failed: ["/usr/bin/dmd", "-v", "-o-", "void.d", "-I."] void foo(void [12] arr) { } void main() { uint[3] arr; foo(arr); }void has no size, so what does it mean to have 12 of them?
Feb 09 2018
On Friday, 9 February 2018 at 15:50:24 UTC, Ralph Doncaster wrote:On Friday, 9 February 2018 at 15:24:27 UTC, Mike Parker wrote:Correct.On Friday, 9 February 2018 at 15:05:33 UTC, Ralph Doncaster wrote:according to the docs and my testing, the size of a void array element is 1,This seems odd to me. Is there a way I can make a function that takes an array of any type but only of a specific size in bytes? void.d(8): Error: function void.foo (void[12] arr) is not callable using argument types (uint[3]) Failed: ["/usr/bin/dmd", "-v", "-o-", "void.d", "-I."] void foo(void [12] arr) { } void main() { uint[3] arr; foo(arr); }void has no size, so what does it mean to have 12 of them?so the following code prints 12: import std.stdio; void foo(void [] arr) { writeln("length: " arr.length); } void main() { uint[3] arr; foo(arr); } I thought about using templates, but I was looking for a simple way of making a function that takes an array of 12 bytes, whether it is uint[3], ubyte[12], or ushort[6].uint[3] and void[12] have the same size but are different types so the compiler will reject it. you can reinterpret cast them(i.e. *cast(void[12])(&arr) ), but this is a rather blunt tool. Is it safe in the case that the types size is at least 12 but not safe in general.Is there a way I can make a function that takes an array of any type but only of a specific size in bytes?With a template that constrains the types size: void foo(T)(T t) if (T.sizeof == 12) { //... } alternately reject incorrect values at runtime void foo(ubyte[] t) in { assert(t.length == 12); } do { //... }
Feb 09 2018
On Friday, 9 February 2018 at 16:28:50 UTC, Nicholas Wilson wrote:On Friday, 9 February 2018 at 15:50:24 UTC, Ralph Doncaster wrote:Thanks. That's what I thought. If I stick with using D, I'll probably go with the runtime check.Is there a way I can make a function that takes an array of any type but only of a specific size in bytes?With a template that constrains the types size: void foo(T)(T t) if (T.sizeof == 12) { //... } alternately reject incorrect values at runtime void foo(ubyte[] t) in { assert(t.length == 12); } do { //... }
Feb 09 2018
On Fri, Feb 09, 2018 at 03:05:33PM +0000, Ralph Doncaster via Digitalmars-d-learn wrote:This seems odd to me. Is there a way I can make a function that takes an array of any type but only of a specific size in bytes? void.d(8): Error: function void.foo (void[12] arr) is not callable using argument types (uint[3]) Failed: ["/usr/bin/dmd", "-v", "-o-", "void.d", "-I."] void foo(void [12] arr) { } void main() { uint[3] arr; foo(arr); }You probably didn't mean to pass a static array, because those are passed by value and may entail unnecessary copying. (Though in this case, if you're only expecting 12 bytes, that's not that big of a difference.) But in any case, probably something like this would do: void foo(void[] arr) in { assert(arr.length == 12); } do { ... } T -- If creativity is stifled by rigid discipline, then it is not true creativity.
Feb 09 2018