Re: exern (C) linkage problem

2010-07-19 Thread Lars T. Kyllingstad
On Sun, 18 Jul 2010 13:08:57 -0700, Charles Hixson wrote:

 I'm trying to link a C routine to a D program, passing string
 parameters, but I keep getting segmentation errors. As you can see,
 these are simple test routines, so the names don't reflect current
 status, but merely where I intend to arrive...but I've hit severe
 roadblocks.
 (FWIW, I've tried including -fpic in the gcc command, and it didn't
 appear to make any difference.)
 
 Makefile:
 biblio: biblio.d sqlitebase.o
   dmd biblio.d sqlitebase.o -ofbiblio
 
 sqlitebase.o: sqlitebase.c sqlitebase.h
   gcc -c sqlitebase.c
 
 biblio.d:
 import   std.stdio;
 
 //extern (C)   void   dbdefine (char[] str); extern (C)   void  
 dbdefine (char[] inStr, ref char[255] outStr);
 
 void   main()
 {  char[255]   retVal;
 char[]   msg   =   cast(char[])Hello from C\0; dbdefine   (msg,
 retVal);
 writeln (Hello, World);
 }
 
 sqlitebase.h:
 
 //void   dbdefine (char str[]);
 void   dbdefine (char inStr[], char outStr[255]);
 
 sqlitebase.c:
 
 #include   sqlitebase.h
 
 //void   dbdefine (char str[])
 void   dbdefine (char inStr[], char outStr[255]) {   //int   i   =   0;
 //while (str[i] != 0)   i++;
 //printStr   (i, str);
 //^^--segmentation fault--^^
 //   printf (%s/n, str);
 //^^--warning: incompatible implicit declaration of built-in
 function ‘printf’--^^
 //int   i   =   str[0];
 //putchar(i);
 //^^--segmentation fault--^^
 int   i   =   -1;
 while (++i  255)
 {   if (inStr[i] == 0)   break;
outStr[i]   =   inStr[i];
 }
 
 }


Since bearophile already answered with a solution to your problem, I'll 
just chime in with a few small tips (of which you may already be aware):

1. D string *literals* are already zero-terminated, so you don't need to 
add the \0 character explicitly.  Also, they cast implicitly to const
(char)*, so if your function doesn't change inStr, it's perfectly fine to 
do

  extern(C) void dbdefine (const char* inStr);
  dbdefine(Hello from C);

2. For D strings in general the \0 must be added, but this is very easy 
to forget.  Therefore, when passing strings to C functions I always use 
the std.string.toStringz() function.  It takes a D string, adds a \0 if 
necessary, and returns a pointer to the first character.

  string s = getAStringFromSomewhere();
  dbdefine(toStringz(s));

-Lars


Re: exern (C) linkage problem

2010-07-19 Thread bearophile
Lars T. Kyllingstad:
 2. For D strings in general the \0 must be added, but this is very easy 
 to forget.  Therefore, when passing strings to C functions I always use 
 the std.string.toStringz() function.  It takes a D string, adds a \0 if 
 necessary, and returns a pointer to the first character.
 
   string s = getAStringFromSomewhere();
   dbdefine(toStringz(s));

The C code has to use those string pointers with lot of care.
The D type system can help you remember to use the toStringz, this is just an 
idea:

import std.string: toStringz;

typedef char* Cstring;
extern(C) Cstring strcmp(Cstring s1, Cstring s2);

Cstring toCString(T)(T[] s) {
return cast(Cstring)toStringz(s);
}
void main() {
auto s1 = abba;
auto s2 = red;
// auto r = strcmp(toCString(s1), s2); // compile error
auto r = strcmp(toCString(s1), toCString(s2)); // OK
}
Unfortunately Andrei has killed the useful typedef. So you have to use a struct 
with alias this, that often doesn't work.

Bye,
bearophile


Is there a way to create compile-time delegates?

2010-07-19 Thread Simen kjaeraas

Yeah, what the subject says.

I want to have a default delegate for a struct, and without a default
constructor, this has to be a compile-time constant. Now, logically,
there should be nothing wrong with storing the function pointer and a
null context pointer at compile-time, but it seems there is. Any ideas?

struct foo {
void delegate( ) dg = () {}; // Error: non-constant expression
 // __dgliteral1
}

--
Simen


Detecting a property setter?

2010-07-19 Thread Rory McGuire

Hi,

Does anyone know how to detect if there is a setter for a property? The  
code below prints the same thing for both
the setter and the getter of front:

==
import std.traits;

class Foo {
 uint num;

 @property ref uint front() {
 return num;
 }
 @property void front(uint i) {
 num = i;
 }

 ref uint front2() {
return num;
 }
}

template isProperty(alias func) if (isCallable!(func)) {
enum isProperty = (functionAttributes!(func)   
FunctionAttribute.PROPERTY)==0 ? false : true;
}

template hasSetter(alias func) if (isCallable!(func)) {
enum hasSetter = (isProperty!(func)  ParameterTypeTuple!(func).length 
  
0  ReturnType!(func).stringof != void) ? true : false;
}

void main() {
 Foo foo;
pragma(msg, hasSetter!(foo.front));

static if (isProperty!(foo.front)) {
pragma(msg, property);
} else {
pragma(msg, not a property);
}

alias MemberFunctionsTuple!(Foo,front) fronts;
foreach (s; fronts) {
pragma(msg, ReturnType!(s)); // this line just prints uint 
for both  
front properties!
}
}



Is this a compiler bug? Or am I wrong again?

Thanks
Rory


www.neonova.co.za: http://cf.neonova.co.za/9YXp
View: https://mail1.clearformat.com/vcard.php?uid=11pid=10
Beta Test Advert: http://fwd.clearformat.com/9YXn
inline: logo.jpginline: ff2d54b.jpg

Re: Is there a way to create compile-time delegates?

2010-07-19 Thread torhu

On 19.07.2010 21:06, Simen kjaeraas wrote:

Yeah, what the subject says.

I want to have a default delegate for a struct, and without a default
constructor, this has to be a compile-time constant. Now, logically,
there should be nothing wrong with storing the function pointer and a
null context pointer at compile-time, but it seems there is. Any ideas?

struct foo {
  void delegate( ) dg = () {}; // Error: non-constant expression
   // __dgliteral1
}



I wasn't able to make it work.  The compiler probably sees delegates as 
something that just can't be created at compile time, since no runtime 
contexts exist then.  Which is reasonable.


Maybe one of those templates that turn functions into delegates will 
work?  Otherwise I guess you're back to using a factory function for 
initializing instances.


Maybe just checking for null pointers before calling those delegates 
ends up being the easiest solution.


Re: Detecting a property setter?

2010-07-19 Thread Simen kjaeraas

Rory McGuire rmcgu...@neonova.co.za wrote:


Does anyone know how to detect if there is a setter for a property? The
code below prints the same thing for both
the setter and the getter of front:

==
import std.traits;

class Foo {
 uint num;

 @property ref uint front() {
 return num;
 }
 @property void front(uint i) {
 num = i;
 }

 ref uint front2() {
return num;
 }
}

template isProperty(alias func) if (isCallable!(func)) {
enum isProperty = (functionAttributes!(func) 
FunctionAttribute.PROPERTY)==0 ? false : true;
}

template hasSetter(alias func) if (isCallable!(func)) {
	enum hasSetter = (isProperty!(func)  ParameterTypeTuple!(func).length  


0  ReturnType!(func).stringof != void) ? true : false;
}


For what it's worth, I would simply check if the property allows  
assignment. i.e.:


template hasSetter(alias func) if (isCallable!(func)) {
enum hasSetter = isProperty!(func) 
is( typeof( (){ func = ReturnType!(func).init; } ) );
}

--
Simen


Re: Is there a way to create compile-time delegates?

2010-07-19 Thread Philippe Sigaud
On Mon, Jul 19, 2010 at 22:01, torhu n...@spam.invalid wrote:



 I wasn't able to make it work.


Me too :(


 The compiler probably sees delegates as something that just can't be
 created at compile time, since no runtime contexts exist then.  Which is
 reasonable.


Can you initialize pointers in general, at compile-time?



 Maybe one of those templates that turn functions into delegates will work?



I had the same idea and tried to use std.functional.toDelegate, but to no
avail.

enum moo = ()  {return 1;};

struct foo {
   int delegate( ) dg = toDelegate(moo);
}

Error: forward reference to inferred return type of function call
toDelegate(delegate int()|

int moo() { return 1;}

struct foo {
   int delegate( ) dg = toDelegate(moo);
}

Error: forward reference to inferred return type of function call
toDelegate(( moo))|

'auto' strikes again :(
I came to hate these forward reference errors. That and the fact that auto
functions do not appear in the docs, that's enough for me to avoid auto as
much as possible for functions.



 Otherwise I guess you're back to using a factory function for initializing
 instances.

 Maybe just checking for null pointers before calling those delegates ends
 up being the easiest solution.



Philippe


Re: Detecting a property setter?

2010-07-19 Thread Jonathan M Davis
On Monday, July 19, 2010 13:42:51 Philippe Sigaud wrote:
 On Mon, Jul 19, 2010 at 22:06, Simen kjaeraas simen.kja...@gmail.comwrote:
  template hasSetter(alias func) if (isCallable!(func)) {
  
 enum hasSetter = isProperty!(func) 
 
 is( typeof( (){ func = ReturnType!(func).init; } ) );
  
  }
 
 In that case, for the second func, the one you call ReturnType on, how does
 the compiler knows it must take the ref uint one (the getter) and not the
 void func() one?
 
 
 Philippe

I don't think that you're supposed to be able to have a getter property 
returning a ref at the same time that you have a setter property with the same 
name. It certainly sounds like it should be a bug in any case.

- Jonathan M Davis


Re: Detecting a property setter?

2010-07-19 Thread Rory McGuire
On Mon, 19 Jul 2010 22:06:14 +0200, Simen kjaeraas  
simen.kja...@gmail.com wrote:



Rory McGuire rmcgu...@neonova.co.za wrote:


Does anyone know how to detect if there is a setter for a property? The
code below prints the same thing for both
the setter and the getter of front:

==
import std.traits;

class Foo {
 uint num;

 @property ref uint front() {
 return num;
 }
 @property void front(uint i) {
 num = i;
 }

 ref uint front2() {
return num;
 }
}

template isProperty(alias func) if (isCallable!(func)) {
enum isProperty = (functionAttributes!(func) 
FunctionAttribute.PROPERTY)==0 ? false : true;
}

template hasSetter(alias func) if (isCallable!(func)) {
	enum hasSetter = (isProperty!(func)   
ParameterTypeTuple!(func).length 

0  ReturnType!(func).stringof != void) ? true : false;
}


For what it's worth, I would simply check if the property allows  
assignment. i.e.:


template hasSetter(alias func) if (isCallable!(func)) {
 enum hasSetter = isProperty!(func) 
 is( typeof( (){ func = ReturnType!(func).init; } ) );
}



Hehe good solution, never even crossed my mind.
And it doesn't match ref return types such as the following signature.

ref uint front() { return num; }

My test code below:
===
import std.traits;

class Foo {
uint num;

@property ref uint front() {
return num;
}
/+@property void front(uint i) {
num = i;
}+/

ref uint front2() {return num;}
}

template isProperty(alias func) if (isCallable!(func)) {
	enum isProperty = (functionAttributes!(func)   
FunctionAttribute.PROPERTY)==0 ? false : true;

}

template hasSetter(alias func) if (isCallable!(func)) {
enum hasSetter = isProperty!(func) 
is( typeof( (){ func = ReturnType!(func).init; } ) );
}

void main() {
Foo foo;
pragma(msg, hasSetter!(foo.front)); // is the return type null (setter)

static if (isProperty!(foo.front)) {
pragma(msg, property);
} else {
pragma(msg, not a property);
}

alias MemberFunctionsTuple!(Foo,front) fronts;
foreach (s; fronts) {
pragma(msg, hasSetter!(s));
}

}


Could be used in a GUI library for checking which properties of a class  
are editable and which are only for display.

And tell you about it at compile time.


Thanks!


Re: Detecting a property setter?

2010-07-19 Thread Rory McGuire
On Mon, 19 Jul 2010 23:25:01 +0200, Jonathan M Davis  
jmdavisp...@gmail.com wrote:



On Monday, July 19, 2010 13:42:51 Philippe Sigaud wrote:
On Mon, Jul 19, 2010 at 22:06, Simen kjaeraas  
simen.kja...@gmail.comwrote:

 template hasSetter(alias func) if (isCallable!(func)) {

enum hasSetter = isProperty!(func) 

is( typeof( (){ func = ReturnType!(func).init; } ) );

 }

In that case, for the second func, the one you call ReturnType on, how  
does
the compiler knows it must take the ref uint one (the getter) and not  
the

void func() one?


Philippe


I don't think that you're supposed to be able to have a getter property
returning a ref at the same time that you have a setter property with  
the same

name. It certainly sounds like it should be a bug in any case.

- Jonathan M Davis


I suppose it would be seen as a bug because it possibly circumvents the  
getter/setter

philosophy (If you return the internal value anyway).


Re: Detecting a property setter?

2010-07-19 Thread Rory McGuire



On Mon, 19 Jul 2010 22:42:51 +0200, Philippe Sigaud philippe.sig...@gmail.com wrote:On Mon, Jul 19, 2010 at 22:06, Simen kjaeraas simen.kja...@gmail.com wrote:
template hasSetter(alias func) if (isCallable!(func)) {
    enum hasSetter = isProperty!(func) 
        is( typeof( (){ func = ReturnType!(func).init; } ) );
}In that case, for the second func, the one you call ReturnType on, how does the compiler knows it must take the ref uint one (the getter) and not the void func() one?Philippe

Simen is using the fact that the compiler already has to figure out if there is an overload that matches the requirements. So it ends uptaking the only one that works. Since it seems to ignore the ref return type property, the property that takes an uint argument must have ahigher precedence (gets checked if it works first).I wonder if its because Walter probably implemented function overloading before properties and ref return types. Hopefully its a languagefeature and not just a implementation side effect.-Rory

Re: Detecting a property setter?

2010-07-19 Thread Jonathan M Davis
On Monday, July 19, 2010 14:37:22 Rory McGuire wrote:
 I suppose it would be seen as a bug because it possibly circumvents the
 getter/setter
 philosophy (If you return the internal value anyway).

No, the problem is that you have _both_ a getter returning a ref and a setter. 
So, which does the compiler use? Returning a ref isn't a problem - phobos does 
it with ranges. Doing that, you basically user the getter for setting the 
property also. However, with both a getter returning a ref and a setter, then 
the compiler is going to have to choose which to use if you use the property as 
a setter. It's an ambiguity and thus shouldn't compile. If it does, then that's 
a bug.

- Jonathan M Davis


Re: exern (C) linkage problem

2010-07-19 Thread bearophile
 typedef char* Cstring;
 extern(C) Cstring strcmp(Cstring s1, Cstring s2);
 ...

You can use just a struct too:

import std.string: toStringz;

struct Cstring {
const(char)* ptr;
}

extern(C) Cstring strcmp(Cstring s1, Cstring s2);

Cstring toCString(T)(T[] s) {
return Cstring(toStringz(s));
}
void main() {
auto s1 = abba;
auto s2 = red;
// auto r = strcmp(toCString(s1), s2); // compile error
auto r = strcmp(toCString(s1), toCString(s2)); // OK
}

Bye,
bearophile


Re: Is there a way to create compile-time delegates?

2010-07-19 Thread Don

Philippe Sigaud wrote:

On Mon, Jul 19, 2010 at 22:01, torhu n...@spam.invalid wrote:



I wasn't able to make it work.  



Me too :(
 


The compiler probably sees delegates as something that just can't be
created at compile time, since no runtime contexts exist then.
 Which is reasonable.


Can you initialize pointers in general, at compile-time?


You cannot initialize a pointer to runtime-allocated data at 
compile-time, and will never be able to. This particular example cannot 
ever work.
You should be able to initialize pointers to static data at 
compile-time, but currently you can't.




 


Maybe one of those templates that turn functions into delegates will
work?  



I had the same idea and tried to use std.functional.toDelegate, but to 
no avail.


enum moo = ()  {return 1;};

struct foo {
   int delegate( ) dg = toDelegate(moo);
}

Error: forward reference to inferred return type of function call 
toDelegate(delegate int()|


int moo() { return 1;}

struct foo {
   int delegate( ) dg = toDelegate(moo);
}

Error: forward reference to inferred return type of function call 
toDelegate(( moo))|


'auto' strikes again :(
I came to hate these forward reference errors. That and the fact that 
auto functions do not appear in the docs, that's enough for me to avoid 
auto as much as possible for functions.


 


Otherwise I guess you're back to using a factory function for
initializing instances.

Maybe just checking for null pointers before calling those delegates
ends up being the easiest solution.



Philippe