www.digitalmars.com         C & C++   DMDScript  

digitalmars.D - Calling C function with static array includes length and pointer

reply mwarning <moritzwarning web.de> writes:
Hi,

I try to pass a static array to a variadic C function.
Looks like the array is passed by values as expected,
but the length and pointer are prepended, too.
Is this intentional or a bug?

http://pastebin.com/6ejFF37j
Jun 21 2010
next sibling parent reply =?UTF-8?B?QWxpIMOHZWhyZWxp?= <acehreli yahoo.com> writes:
mwarning wrote:
 Hi,
 
 I try to pass a static array to a variadic C function.
 Looks like the array is passed by values as expected,
 but the length and pointer are prepended, too.
 Is this intentional or a bug?
 
 http://pastebin.com/6ejFF37j
Fixed sized arrays don't have ptr and length members: import std.stdio; void main() { int[5] array; writeln(array.sizeof); // prints 20 writeln(array.ptr, ' ', &array); // prints the save value } The code you've pasted has this: extern(C) void* foo(uint x, ...) { Stdout("x: ")(x).nl; Stdout("y: ")(*(&x + 1)).nl; //outputs 64! return null; } The expression *(&x + 1) is undefined behavior, because (&x + 1) is not valid, i.e. not specified to be accessible by the language. Ali
Jun 21 2010
parent reply mwarning <moritzwarning web.de> writes:
On Mon, 21 Jun 2010 14:38:50 -0700, Ali Çehreli wrote:

 mwarning wrote:
 Hi,
 
 I try to pass a static array to a variadic C function. Looks like the
 array is passed by values as expected, but the length and pointer are
 prepended, too. Is this intentional or a bug?
 
 http://pastebin.com/6ejFF37j
Fixed sized arrays don't have ptr and length members: import std.stdio; void main() { int[5] array; writeln(array.sizeof); // prints 20 writeln(array.ptr, ' ', &array); // prints the save value }
Hm? You just have proved that they have. :> But those are not members of a struct/pair instance (as for dynamic arrays). They are compile time values. Whatever, it's me nitpicking. :)
 The code you've pasted has this:
 
 extern(C) void* foo(uint x, ...)
 {
      Stdout("x: ")(x).nl;
      Stdout("y: ")(*(&x + 1)).nl; //outputs 64! return null;
 }
 
 The expression *(&x + 1) is undefined behavior, because (&x + 1) is not
 valid, i.e. not specified to be accessible by the language.
 
 Ali
True, the D spec doesn't specify the memory layout. But the C calling convention does (depending on the platform). Anyway, the D spec says: "Static arrays are value types, but as in C static arrays are passed to functions by reference and cannot be returned from functions." (http://www.digitalmars.com/d/1.0/arrays.html#static-arrays) It seems that D does a little more then just pass by value. It includes the pointer and length value as well. Btw.: smth. told me workaround/solution: wrap the static array in a struct.
Jun 21 2010
parent =?UTF-8?B?QWxpIMOHZWhyZWxp?= <acehreli yahoo.com> writes:
mwarning wrote:

 Anyway, the D spec says:
 "Static arrays are value types, but as in C static arrays are passed to
 functions by reference and cannot be returned from functions."
 (http://www.digitalmars.com/d/1.0/arrays.html#static-arrays)
I've been thinking D2. :) In D2, fixed-sized arrays are value types and copied to and from functions: import std.stdio; int[2] foo(int[2] array) { writeln("in foo : ", &(array[0])); return array; } void main() { int[2] array; writeln("in main 1: ", &(array[0])); int[2] result = foo(array); writeln("in main 2: ", &(result[0])); } All three addresses are separate in D2. Ali
Jun 21 2010
prev sibling parent reply torhu <no spam.invalid> writes:
On 21.06.2010 23:30, mwarning wrote:
 Hi,

 I try to pass a static array to a variadic C function.
 Looks like the array is passed by values as expected,
 but the length and pointer are prepended, too.
 Is this intentional or a bug?

 http://pastebin.com/6ejFF37j
I believe this works as intended. And arrays in D 1 are *not* passed by value, ie. the data is not copied. From www.digitalmars.com/d/1.0/arrays.html: "a string literal is passed as a (length,pointer) combination to variadic parameters" In other words, use stack.ptr if you want just the pointer.
Jun 21 2010
parent mwarning <moritzwarning web.de> writes:
On Tue, 22 Jun 2010 00:00:27 +0200, torhu wrote:

 On 21.06.2010 23:30, mwarning wrote:
 Hi,

 I try to pass a static array to a variadic C function. Looks like the
 array is passed by values as expected, but the length and pointer are
 prepended, too. Is this intentional or a bug?

 http://pastebin.com/6ejFF37j
I believe this works as intended. And arrays in D 1 are *not* passed by value, ie. the data is not copied. From www.digitalmars.com/d/1.0/arrays.html: "a string literal is passed as a (length,pointer) combination to variadic parameters"
Thanks, I missed that section!
 In other words, use stack.ptr if you want just the pointer.
I wrap it into a struct, that will do it.
Jun 21 2010