digitalmars.D.learn - Translation of C function pointer.
- Yao G. (10/12) Sep 15 2010 Hello gentlemen:
- Steven Schveighoffer (12/22) Sep 15 2010 D supports C-style function pointers. See here:
- Steven Schveighoffer (4/27) Sep 15 2010 BTW, not sure why the const const(char*)...
- Yao G. (5/15) Sep 15 2010 Thanks Steve!
- BCS (4/11) Sep 16 2010 D, now with C type un-garbleing!
- Steven Schveighoffer (6/14) Sep 16 2010 I'd have to say, if I wasn't able to use D to do this, it would have tak...
- BCS (4/21) Sep 16 2010 The trick is that function pointers are best read from the inside out.
- Kagamin (2/4) Sep 16 2010 All C declarations are read from inside out, postfixes take precedence, ...
- Jonathan M Davis (6/13) Sep 17 2010 It's essentially the same principle that makes it so that the D declarat...
- Simen kjaeraas (6/20) Sep 17 2010 I've always been confused by C in this regard. It seems to logical to me
- Jonathan M Davis (7/30) Sep 17 2010 You're going to have to elaborate on that. I'm not quite sure what you'r...
- Simen kjaeraas (8/17) Sep 17 2010 You know, after reading your post to Ali, and trying to come up with a
- Jonathan M Davis (4/21) Sep 17 2010 Well, it's easy to get the type in D, but C is not so enlightened. That'...
- =?UTF-8?B?QWxpIMOHZWhyZWxp?= (29/41) Sep 17 2010 columns like
- Jonathan M Davis (33/73) Sep 17 2010 e,
- Jesse Phillips (9/21) Sep 17 2010 That isn't how you read it.
-
Stewart Gordon
(21/35)
Sep 16 2010
- Stewart Gordon (7/16) Sep 16 2010 Perhaps the only excuse for keeping C-style function pointer
Hello gentlemen: I'm trying to translate the newest SQLite C header to D, and I stumbled unto this gem:void (*(*xDlSym)(sqlite3_vfs*,void*, const char *zSymbol))(void);What's that? A function pointer that takes another function pointer as its name? I'm stuck at this and I don't know how to convert it to a D function pointer. Certainly, the inner pointer is easy:void (* function(sqlite3_vfs*,void*, const(char) *zSymbol) xDlSym)();But what about the outer one? I am missing something? Thanks in advance. -- Yao G.
Sep 15 2010
On Wed, 15 Sep 2010 17:05:24 -0400, Yao G. <yao.gomez spam.gmail.com> wrote:Hello gentlemen: I'm trying to translate the newest SQLite C header to D, and I stumbled unto this gem:D supports C-style function pointers. See here: typedef char sqlite3_vfs; // note you can't use void as a parameter type in D void (*(*xDlSym)(sqlite3_vfs*,void*, const char *zSymbol))(/*void*/); pragma(msg, typeof(xDlSym).stringof); outputs: void function() function(sqlite3_vfs*, void*, const const(char*) zSymbol) so I think it's a function pointer that takes those parameters and returns a function pointer that takes no parameters and returns nothing. -Stevevoid (*(*xDlSym)(sqlite3_vfs*,void*, const char *zSymbol))(void);What's that? A function pointer that takes another function pointer as its name? I'm stuck at this and I don't know how to convert it to a D function pointer. Certainly, the inner pointer is easy:void (* function(sqlite3_vfs*,void*, const(char) *zSymbol) xDlSym)();But what about the outer one? I am missing something? Thanks in advance.
Sep 15 2010
On Wed, 15 Sep 2010 17:15:12 -0400, Steven Schveighoffer <schveiguy yahoo.com> wrote:On Wed, 15 Sep 2010 17:05:24 -0400, Yao G. <yao.gomez spam.gmail.com> wrote:BTW, not sure why the const const(char*)... -SteveHello gentlemen: I'm trying to translate the newest SQLite C header to D, and I stumbled unto this gem:D supports C-style function pointers. See here: typedef char sqlite3_vfs; // note you can't use void as a parameter type in D void (*(*xDlSym)(sqlite3_vfs*,void*, const char *zSymbol))(/*void*/); pragma(msg, typeof(xDlSym).stringof); outputs: void function() function(sqlite3_vfs*, void*, const const(char*) zSymbol)void (*(*xDlSym)(sqlite3_vfs*,void*, const char *zSymbol))(void);What's that? A function pointer that takes another function pointer as its name? I'm stuck at this and I don't know how to convert it to a D function pointer. Certainly, the inner pointer is easy:void (* function(sqlite3_vfs*,void*, const(char) *zSymbol) xDlSym)();But what about the outer one? I am missing something? Thanks in advance.
Sep 15 2010
On Wed, 15 Sep 2010 16:15:12 -0500, Steven Schveighoffer <schveiguy yahoo.com> wrote:D supports C-style function pointers. See here: typedef char sqlite3_vfs; // note you can't use void as a parameter type in D void (*(*xDlSym)(sqlite3_vfs*,void*, const char *zSymbol))(/*void*/); pragma(msg, typeof(xDlSym).stringof); outputs: void function() function(sqlite3_vfs*, void*, const const(char*) zSymbol) so I think it's a function pointer that takes those parameters and returns a function pointer that takes no parameters and returns nothing. -SteveThanks Steve! -- Yao G.
Sep 15 2010
Hello Steven,// note you can't use void as a parameter type in D void (*(*xDlSym)(sqlite3_vfs*,void*, const char *zSymbol))(/*void*/); pragma(msg, typeof(xDlSym).stringof); outputs: void function() function(sqlite3_vfs*, void*, const const(char*) zSymbol)D, now with C type un-garbleing! -- ... <IXOYE><
Sep 16 2010
On Thu, 16 Sep 2010 10:06:24 -0400, BCS <none anon.com> wrote:Hello Steven,I'd have to say, if I wasn't able to use D to do this, it would have taken me hours to figure this one out. Even knowing what it is now, I still can't read it :) D is a huge leap ahead of C in this regard! -Steve// note you can't use void as a parameter type in D void (*(*xDlSym)(sqlite3_vfs*,void*, const char *zSymbol))(/*void*/); pragma(msg, typeof(xDlSym).stringof); outputs: void function() function(sqlite3_vfs*, void*, const const(char*) zSymbol)D, now with C type un-garbleing!
Sep 16 2010
Hello Steven,On Thu, 16 Sep 2010 10:06:24 -0400, BCS <none anon.com> wrote:The trick is that function pointers are best read from the inside out. -- ... <IXOYE><Hello Steven,I'd have to say, if I wasn't able to use D to do this, it would have taken me hours to figure this one out. Even knowing what it is now, I still can't read it :)// note you can't use void as a parameter type in D void (*(*xDlSym)(sqlite3_vfs*,void*, const char *zSymbol))(/*void*/); pragma(msg, typeof(xDlSym).stringof); outputs: void function() function(sqlite3_vfs*, void*, const const(char*) zSymbol)D, now with C type un-garbleing!
Sep 16 2010
BCS Wrote:The trick is that function pointers are best read from the inside out. --All C declarations are read from inside out, postfixes take precedence, that's why you have to use braces to give pointer higher precedence. One of the earlier books by Stroustroup gives a nice monster of arrays, pointers and functions to master understanding of declarations.
Sep 16 2010
On Thursday 16 September 2010 23:50:16 Kagamin wrote:BCS Wrote:It's essentially the same principle that makes it so that the D declaration int[4][3] a; is an array with 3 rows and 4 columns rather than 4 rows and 3 columns like you'd expect. - Jonathan M DavisThe trick is that function pointers are best read from the inside out.All C declarations are read from inside out, postfixes take precedence, that's why you have to use braces to give pointer higher precedence. One of the earlier books by Stroustroup gives a nice monster of arrays, pointers and functions to master understanding of declarations.
Sep 17 2010
On Fri, 17 Sep 2010 10:12:34 +0200, Jonathan M Davis <jmdavisProg gmx.com> wrote:On Thursday 16 September 2010 23:50:16 Kagamin wrote:I've always been confused by C in this regard. It seems to logical to me that T[3] works the same whether T is U[4] or U. -- SimenBCS Wrote:It's essentially the same principle that makes it so that the D declaration int[4][3] a; is an array with 3 rows and 4 columns rather than 4 rows and 3 columns like you'd expect.The trick is that function pointers are best read from the inside out.All C declarations are read from inside out, postfixes take precedence, that's why you have to use braces to give pointer higher precedence. One of the earlier books by Stroustroup gives a nice monster of arrays, pointers and functions to master understanding of declarations.
Sep 17 2010
On Friday, September 17, 2010 05:00:55 Simen kjaeraas wrote:On Fri, 17 Sep 2010 10:12:34 +0200, Jonathan M Davis <jmdavisProg gmx.com> wrote:You're going to have to elaborate on that. I'm not quite sure what you're talking about. And the syntax int[4][3] isn't legal C anyway. It just does what C would likely have done had it put the brackets with the type rather than the variable name, since D uses pretty much the same syntax for variable declarations and therefore pretty much the same rules. - Jonathan M DavisOn Thursday 16 September 2010 23:50:16 Kagamin wrote:I've always been confused by C in this regard. It seems to logical to me that T[3] works the same whether T is U[4] or U.BCS Wrote:It's essentially the same principle that makes it so that the D declaration int[4][3] a; is an array with 3 rows and 4 columns rather than 4 rows and 3 columns like you'd expect.The trick is that function pointers are best read from the inside out.All C declarations are read from inside out, postfixes take precedence, that's why you have to use braces to give pointer higher precedence. One of the earlier books by Stroustroup gives a nice monster of arrays, pointers and functions to master understanding of declarations.
Sep 17 2010
Jonathan M Davis <jmdavisProg gmx.com> wrote:You know, after reading your post to Ali, and trying to come up with a reason why I felt the way I did, I have found enlightenment. Limited, yes, but I now see that C's order is also good. Now if only there were a reasonable way to extricate the type from the variable name... -- SimenI've always been confused by C in this regard. It seems to logical to me that T[3] works the same whether T is U[4] or U.You're going to have to elaborate on that. I'm not quite sure what you're talking about. And the syntax int[4][3] isn't legal C anyway. It just does what C would likely have done had it put the brackets with the type rather than the variable name, since D uses pretty much the same syntax for variable declarations and therefore pretty much the same rules.
Sep 17 2010
On Friday, September 17, 2010 17:07:15 Simen kjaeraas wrote:Jonathan M Davis <jmdavisProg gmx.com> wrote:Well, it's easy to get the type in D, but C is not so enlightened. That's what happens when you compare languages which have about a 25 year difference in age. - Jonathan M DavisYou know, after reading your post to Ali, and trying to come up with a reason why I felt the way I did, I have found enlightenment. Limited, yes, but I now see that C's order is also good. Now if only there were a reasonable way to extricate the type from the variable name...I've always been confused by C in this regard. It seems to logical to me that T[3] works the same whether T is U[4] or U.You're going to have to elaborate on that. I'm not quite sure what you're talking about. And the syntax int[4][3] isn't legal C anyway. It just does what C would likely have done had it put the brackets with the type rather than the variable name, since D uses pretty much the same syntax for variable declarations and therefore pretty much the same rules.
Sep 17 2010
Jonathan M Davis wrote:On Thursday 16 September 2010 23:50:16 Kagamin wrote:declarationBCS Wrote:It's essentially the same principle that makes it so that the DThe trick is that function pointers are best read from the inside out.All C declarations are read from inside out, postfixes take precedence, that's why you have to use braces to give pointer higher precedence. One of the earlier books by Stroustroup gives a nice monster of arrays, pointers and functions to master understanding of declarations.int[4][3] a; is an array with 3 rows and 4 columns rather than 4 rows and 3columns likeyou'd expect. - Jonathan M DavisI don't see it that D's declaration follows C's at least in array declarations: int[4] is an array of 4 ints; like Simen, let's call it U. Now U[3] is an array of 3 Us; i.e. 3 int[4]s I read that from left to right, not inside out. The equivalent C declaration has the opposite type: int a[4][3]; Now that is 4 arrays of 3 ints. D wins big time here! :) Two programs to test: #include <stdio.h> int main() { int a[4][3]; printf("%u\n", sizeof(a[0])); return 0; } Outputs 12. import std.stdio; void main() { int[4][3] a; writeln(typeof(a[0]).sizeof); } Outputs 16. Ali
Sep 17 2010
On Friday, September 17, 2010 10:43:12 Ali =C3=87ehreli wrote:Jonathan M Davis wrote: > On Thursday 16 September 2010 23:50:16 Kagamin wrote: >> BCS Wrote: >>> The trick is that function pointers are best read from the inside ou=t.>>=20 >> All C declarations are read from inside out, postfixes take precedenc=e,>> that's why you have to use braces to give pointer higher precedence. >> One of the earlier books by Stroustroup gives a nice monster of >> arrays, pointers and functions to master understanding of >> declarations. >=20 > It's essentially the same principle that makes it so that the D =20 declaration =20 > int[4][3] a; >=20 > is an array with 3 rows and 4 columns rather than 4 rows and 3 =20 columns like =20 > you'd expect. >=20 > - Jonathan M Davis =20 I don't see it that D's declaration follows C's at least in array declarations: =20 int[4] is an array of 4 ints; like Simen, let's call it U. Now U[3] is an array of 3 Us; i.e. 3 int[4]s =20 I read that from left to right, not inside out.No, no. You read it outwards from the variable name (which is essentially w= hat=20 you're doing in C), so you read it from right to left. If you read it from = left=20 to right it would be an integer of arrays, which makes no sense. It's just = like=20 how int* is a pointer to an int, not an int to a pointer. Declarations are = read=20 outwards from the variable name (which is usually right to left).=20 The equivalent C declaration has the opposite type: =20 int a[4][3]; =20 Now that is 4 arrays of 3 ints. =20 D wins big time here! :)Again, you're reading outwards from the variable name. That means that you = read=20 this one left to right, though it gets a bit weird because the type is on b= oth=20 sides of the variable name (though you get the same problem with function=20 pointers). Both int[3][4] a; and int a[4][3]; are 4 arrays of 3 ints, and both read outwards from the variable name. And= =20 because when you index them, the max indices would be a[3][2], it totally t= hrows=20 people off to declare them the D way because the order is reversed from whe= re it=20 was declared (since you're using the brackets on the opposite side of the=20 variable name now). The fact that int[3][4] a; is 4 arrays of 3 ints is _exactly_ the same as h= ow it=20 works with C declarations. You read outward from the variable name. =2D Jonathan M Davis
Sep 17 2010
Jonathan M Davis Wrote:On Friday, September 17, 2010 10:43:12 Ali Çehreli wrote:That isn't how you read it. int* b; int pointer b. int[4][3] a; int array of 4, array of 3 a. This isn't exactly grammatically clear English. But it isn't English it is D. int c[3][4]; c is array of 3 int arrays of 4 int. Definitely not left to right.int[4] is an array of 4 ints; like Simen, let's call it U. Now U[3] is an array of 3 Us; i.e. 3 int[4]s I read that from left to right, not inside out.No, no. You read it outwards from the variable name (which is essentially what you're doing in C), so you read it from right to left. If you read it from left to right it would be an integer of arrays, which makes no sense. It's just like how int* is a pointer to an int, not an int to a pointer. Declarations are read outwards from the variable name (which is usually right to left).
Sep 17 2010
On 16/09/2010 15:37, Steven Schveighoffer wrote:On Thu, 16 Sep 2010 10:06:24 -0400, BCS <none anon.com> wrote:<snip> It took me a moment as well. Basically, the C declaration ReturnType (*Name)(Parameters); becomes in D ReturnType function(Parameters) Name; Where you've got one inside another, you try to apply the same principle. So void (*(*xDlSym)(sqlite3_vfs*,void*, const char *zSymbol))(void); starting with the outermost level, you end up with (note (void) becomes ()) void function() (*xDlSym)(sqlite3_vfs*,void*, const char *zSymbol); instead of Name, you've got this funny thing. You're left with a function pointer declaration where void function() is the ReturnType, so transforming it again you get void function() function(sqlite3_vfs*, void*, char* zSymbol) xDlSym; or in D2, void function() function(sqlite3_vfs*, void*, const(char)* zSymbol) xDlSym; Whoever wrote the C declaration must have had an even harder job getting it right! I wouldn't have hesitated to use a typedef, if ever I had reason to do C stuff as complicated as this. Stewart.Hello Steven,I'd have to say, if I wasn't able to use D to do this, it would have taken me hours to figure this one out. Even knowing what it is now, I still can't read it :)// note you can't use void as a parameter type in D void (*(*xDlSym)(sqlite3_vfs*,void*, const char *zSymbol))(/*void*/); pragma(msg, typeof(xDlSym).stringof); outputs: void function() function(sqlite3_vfs*, void*, const const(char*) zSymbol)D, now with C type un-garbleing!
Sep 16 2010
On 16/09/2010 15:06, BCS wrote:Hello Steven,Perhaps the only excuse for keeping C-style function pointer declarations in D. But since we have htod, we could just as well use it and leave D free to get rid of this fossil that leads to a syntactic ambiguity. Except that I've just found htod has a bug meaning it rejects this code. Stewart.// note you can't use void as a parameter type in D void (*(*xDlSym)(sqlite3_vfs*,void*, const char *zSymbol))(/*void*/); pragma(msg, typeof(xDlSym).stringof); outputs: void function() function(sqlite3_vfs*, void*, const const(char*) zSymbol)D, now with C type un-garbleing!
Sep 16 2010