How to translate typedef void * to Pascal? lazarus / 62-General ---------------------------------------------------------------------- jiaxing2 · 2020-05-12 17:34 Example: typedef void *my_annoying_c_function(size_t sz); ---------------------------------------------------------------------- JdeHaan · 2020-05-12 17:57 type   TMy_Annoying_C_Function = procedure(sz: QWord); ---------------------------------------------------------------------- jamie · 2020-05-12 18:01 Normally the compiler settings are set so that u can use a function like void. The code ignores the return. But if want a cleaner code base with less unneeded background code the use a procedure, which is the same basically. ---------------------------------------------------------------------- Thaddy · 2020-05-12 18:27 as jdehaan wrote typedef void * functions (literary ignore/don't use a result) indicates the same as a Pascal procedure, and although there are pascal modes that can ignore a Pascal function result, so in fact like a procedure, this is not quite the same: such code still assigns a result because the compiler can not know if another call uses the result and therefor a procedure is more efficient in such case. C works the same in the case of void * function.. it is C's haphazard notation for procedure.. jamie's answer is not correct. jdehaan's answer is correct. It is all about the generated assembler and you can easily verify that. ---------------------------------------------------------------------- 440bx · 2020-05-12 19:04 It's probably worth noting that size_t isn't qword. ---------------------------------------------------------------------- Thaddy · 2020-05-12 19:05 Quote from: 440bx on May 12, 2020, 09:04:43 pmIt's probably worth noting that size_t isn't qword. Well spotted! But the documentation lacks here. File a report against documentation. See https://www.freepascal.org/docs-html/rtl/unixtype/size_t.html It does not explain size_t is platform. E.g on 32 bit it is cuint which in turn is an alias for a pointer size of dword. So the mistake is easy to make. Note the compiler behaves properly. size_t is ptruint/nativeuint. type   TMy_Annoying_C_Function = procedure(sz: nativeuint); // or more fpc, ptruint Or: uses unixtypes; type   TMy_Annoying_C_Function = procedure(sz: size_t); ---------------------------------------------------------------------- tetrastes · 2020-05-12 19:54 Then how to translate Code: C  [Select][+][-]window.onload = function(){var x1 = document.getElementById("main_content_section"); if (x1) { var x = document.getElementsByClassName("geshi");for (var i = 0; i typedef void my_annoying_c_function(size_t sz); ---------------------------------------------------------------------- jamie · 2020-05-12 21:00 Quote from: Thaddy on May 12, 2020, 08:27:21 pmas jdehaan wrote typedef void * functions (literary ignore/don't use a result) indicates the same as a Pascal procedure, and although there are pascal modes that can ignore a Pascal function result, so in fact like a procedure, this is not quite the same: such code still assigns a result because the compiler can not know if another call uses the result and therefor a procedure is more efficient in such case. C works the same in the case of void * function.. it is C's haphazard notation for procedure.. jamie's answer is not correct. jdehaan's answer is correct. It is all about the generated assembler and you can easily verify that. And Please explain to me where I am incorrect?  You are a piece of work Thaddy in your own mind! ---------------------------------------------------------------------- PascalDragon · 2020-05-13 07:32 Quote from: jamie on May 12, 2020, 11:00:56 pmQuote from: Thaddy on May 12, 2020, 08:27:21 pmas jdehaan wrote typedef void * functions (literary ignore/don't use a result) indicates the same as a Pascal procedure, and although there are pascal modes that can ignore a Pascal function result, so in fact like a procedure, this is not quite the same: such code still assigns a result because the compiler can not know if another call uses the result and therefor a procedure is more efficient in such case. C works the same in the case of void * function.. it is C's haphazard notation for procedure.. jamie's answer is not correct. jdehaan's answer is correct. It is all about the generated assembler and you can easily verify that. And Please explain to me where I am incorrect?  You are a piece of work Thaddy in your own mind! Thaddy is right however. The declaration that jiaxing2 posted is essentially parsed like this: Code: C  [Select][+][-]window.onload = function(){var x1 = document.getElementById("main_content_section"); if (x1) { var x = document.getElementsByClassName("geshi");for (var i = 0; i typedef void (*my_annoying_c_function)(size_t sz); The correct translation of a C function having void as result type is to use a procedure. If you'd use a function the compiler would need to discard the result value (in most cases that is simply a register, but that doesn't have to be the case on all platforms) while for a procedure it doesn't need to do that, because it knows that there isn't one. Also if you'd implement a function that you'd assign to such a function variable you'd have do deal with Result while it wouldn't require one. Quote from: tetrastes on May 12, 2020, 09:54:40 pmThen how to translate Code: C  [Select][+][-]window.onload = function(){var x1 = document.getElementById("main_content_section"); if (x1) { var x = document.getElementsByClassName("geshi");for (var i = 0; i typedef void my_annoying_c_function(size_t sz);  In the end those are used like this: Code: C  [Select][+][-]window.onload = function(){var x1 = document.getElementById("main_content_section"); if (x1) { var x = document.getElementsByClassName("geshi");for (var i = 0; i my_annoying_c_function *func; Thus you translate them just as if they were a normal function pointer, because Pascal doesn't have that distinction. ---------------------------------------------------------------------- Thaddy · 2020-05-13 10:07 Quote from: jamie on May 12, 2020, 11:00:56 pmAnd Please explain to me where I am incorrect? I did: the code generation differs between a function and a procedure. typedef void * is optimized by a C compiler in the same way as a Pascal procedure and a both do not have to account for a return value. Even if  you can call a Pascal  function as a procedure, that function contains code for the return value, e.g. although you can it is not as efficient. I reprhase wrong in not complete, because it lacks essental information as I described. ---------------------------------------------------------------------- tetrastes · 2020-05-13 10:11 Quote from: PascalDragon on May 13, 2020, 09:32:24 am Thaddy is right however. The declaration that jiaxing2 posted is essentially parsed like this: Code: C  [Select][+][-]window.onload = function(){var x1 = document.getElementById("main_content_section"); if (x1) { var x = document.getElementsByClassName("geshi");for (var i = 0; i typedef void (*my_annoying_c_function)(size_t sz); Really? So Code: C  [Select][+][-]window.onload = function(){var x1 = document.getElementById("main_content_section"); if (x1) { var x = document.getElementsByClassName("geshi");for (var i = 0; i void *malloc(size_t size);returns nothing? And Code: C  [Select][+][-]window.onload = function(){var x1 = document.getElementById("main_content_section"); if (x1) { var x = document.getElementsByClassName("geshi");for (var i = 0; i char *strcpy(char *dest, const char *src);is parsed like Code: C  [Select][+][-]window.onload = function(){var x1 = document.getElementById("main_content_section"); if (x1) { var x = document.getElementsByClassName("geshi");for (var i = 0; i char (*strcpy)(char *dest, const char *src);and returns one char, not c-style string? QuoteQuote from: tetrastes on May 12, 2020, 09:54:40 pmThen how to translate Code: C  [Select][+][-]window.onload = function(){var x1 = document.getElementById("main_content_section"); if (x1) { var x = document.getElementsByClassName("geshi");for (var i = 0; i typedef void my_annoying_c_function(size_t sz);  In the end those are used like this: Code: C  [Select][+][-]window.onload = function(){var x1 = document.getElementById("main_content_section"); if (x1) { var x = document.getElementsByClassName("geshi");for (var i = 0; i my_annoying_c_function *func; Thus you translate them just as if they were a normal function pointer, because Pascal doesn't have that distinction. Where does pointer arrive from? Sorry, I misunderstood you. I mean that the code without pointer Code: C  [Select][+][-]window.onload = function(){var x1 = document.getElementById("main_content_section"); if (x1) { var x = document.getElementsByClassName("geshi");for (var i = 0; i typedef void my_annoying_c_function(size_t sz); my_annoying_c_function func;is absolutely legal. ---------------------------------------------------------------------- Thaddy · 2020-05-13 10:25 The pointer is simply the immediate address of the function itself, not a return value. ---------------------------------------------------------------------- jiaxing2 · 2020-05-13 11:24 So it's because C doesn't has procedure like Pascal so they used a trick to workaround the limitation? Could I just replace it with a Pascal procedure? Why don't they have to go through typedef and not use void in the place? I think C's void function is equivalent to Pascal's procedure. p/s: I found this: https://www.geeksforgeeks.org/return-void- functions-c/ So C's void function could return something too. ---------------------------------------------------------------------- Warfley · 2020-05-13 11:30 Quote from: jiaxing2 on May 12, 2020, 07:34:34 pmtypedef void *my_annoying_c_function(size_t sz); This is confusing, because who ever wrote that c code has forgotten the bracketing. Because there is a big difference between these two possibilities to bracket: Code: C  [Select][+][-]window.onload = function(){var x1 = document.getElementById("main_content_section"); if (x1) { var x = document.getElementsByClassName("geshi");for (var i = 0; i typedef void *(my_annoying_c_function)(size_t sz);which is a function returning a void pointer (i.e. the type Pointer in pascal) or Code: C  [Select][+][-]window.onload = function(){var x1 = document.getElementById("main_content_section"); if (x1) { var x = document.getElementsByClassName("geshi");for (var i = 0; i typedef void (*my_annoying_c_function)(size_t sz);which is a pointer to a returnless function (i.e. pascal procedure) The implicit bracketing of the function you've given is the first one, i.e. it is a function returning an untyped pointer, not a procedure. So the correct pascal implementation would be: Code: Pascal  [Select][+][-]window.onload = function(){var x1 = document.getElementById("main_content_section"); if (x1) { var x = document.getElementsByClassName("geshi");for (var i = 0; i type my_annoying_c_function = function(sz: SizeInt): Pointer; ---------------------------------------------------------------------- PascalDragon · 2020-05-13 11:37 Quote from: Thaddy on May 13, 2020, 12:07:38 pmQuote from: jamie on May 12, 2020, 11:00:56 pmAnd Please explain to me where I am incorrect? I did: the code generation differs between a function and a procedure. typedef void * is optimized by a C compiler in the same way as a Pascal procedure and a both do not have to account for a return value. You mean void, not void*. The * in the example is simply the notation for function pointer. A function pointer to a function returning a void* would be void* *func(). Quote from: tetrastes on May 13, 2020, 12:11:24 pmQuote from: PascalDragon on May 13, 2020, 09:32:24 am Thaddy is right however. The declaration that jiaxing2 posted is essentially parsed like this: Code: C  [Select][+][-]window.onload = function(){var x1 = document.getElementById("main_content_section"); if (x1) { var x = document.getElementsByClassName("geshi");for (var i = 0; i typedef void (*my_annoying_c_function)(size_t sz); Really? So Code: C  [Select][+][-]window.onload = function(){var x1 = document.getElementById("main_content_section"); if (x1) { var x = document.getElementsByClassName("geshi");for (var i = 0; i void *malloc(size_t size);returns nothing? And Code: C  [Select][+][-]window.onload = function(){var x1 = document.getElementById("main_content_section"); if (x1) { var x = document.getElementsByClassName("geshi");for (var i = 0; i char *strcpy(char *dest, const char *src);is parsed like Code: C  [Select][+][-]window.onload = function(){var x1 = document.getElementById("main_content_section"); if (x1) { var x = document.getElementsByClassName("geshi");for (var i = 0; i char (*strcpy)(char *dest, const char *src);and returns one char, not c-style string? These are not function pointers, but function declarations. You have a function pointer if you either have a typedef or declare a variable/field with a function header syntax. E.g. Code: C  [Select][+][-]window.onload = function(){var x1 = document.getElementById("main_content_section"); if (x1) { var x = document.getElementsByClassName("geshi");for (var i = 0; i struct Whatever{  void (*someproc)();} This is a struct with a pointer to void function as its only field. Your function declaration from earlier is essentially parsed like this: Code: C  [Select][+][-]window.onload = function(){var x1 = document.getElementById("main_content_section"); if (x1) { var x = document.getElementsByClassName("geshi");for (var i = 0; i char* strcpy(...); A function pointer to a strcpy compatible function would look like this: Code: C  [Select][+][-]window.onload = function(){var x1 = document.getElementById("main_content_section"); if (x1) { var x = document.getElementsByClassName("geshi");for (var i = 0; i typedef char* (*StrCpyFunc)(...); Quote from: tetrastes on May 13, 2020, 12:11:24 pmI mean that the code without pointer Code: C  [Select][+][-]window.onload = function(){var x1 = document.getElementById("main_content_section"); if (x1) { var x = document.getElementsByClassName("geshi");for (var i = 0; i typedef void my_annoying_c_function(size_t sz); my_annoying_c_function func;is absolutely legal. Yes, but you can't do anything with it: Code: C  [Select][+][-]window.onload = function(){var x1 = document.getElementById("main_content_section"); if (x1) { var x = document.getElementsByClassName("geshi");for (var i = 0; i int somefunc(){   return 42;} typedef int IntFunc(); int main(){   IntFunc func1 = somefunc;   IntFunc func2 = &somefunc;   IntFunc func;      func = somefunc;   func = &somefunc;    return func();} Code: [Select]PS X:\> clang.exe func.c func.c:10:12: error: illegal initializer (only variables can be initialized)    IntFunc func1 = somefunc;            ^ func.c:11:12: error: illegal initializer (only variables can be initialized)    IntFunc func2 = &somefunc;            ^ func.c:14:9: error: non-object type 'IntFunc' (aka 'int ()') is not assignable    func = somefunc;    ~~~~ ^ func.c:15:9: error: non-object type 'IntFunc' (aka 'int ()') is not assignable    func = &somefunc;    ~~~~ ^ 4 errors generated. ---------------------------------------------------------------------- Warfley · 2020-05-13 12:10 Quote from: PascalDragon on May 13, 2020, 01:37:29 pmYou mean void, not void*. The * in the example is simply the notation for function pointer. A function pointer to a function returning a void* would be void* *func(). No, because of the bracketing it is referring to void* ... not to void (*... To quote the C 2011 standard (page 134): http://www.open- std.org/jtc1/sc22/wg14/www/docs/n1570.pdf QuoteEXAMPLE 1 The declaration int f(void), *fip(), (*pfi)(); [...] The binding  of *fip() is *(fip()), so that  the declaration  suggests,  and  the  same  construction  in  an  expression  requires,  the  calling  of  a  function fip, [...].  In  the  declarator (*pfi)(),  the extra parentheses are necessary to indicate that indirection through a pointer to a function yields a function designator [...] ---------------------------------------------------------------------- tetrastes · 2020-05-13 12:10 Quote from: PascalDragon on May 13, 2020, 01:37:29 pm These are not function pointers, but function declarations. You have a function pointer if you either have a typedef You are wrong. See post of Warfley. If you need function pointer, you need explicitly use brackets, with or without typedef. QuoteYour function declaration from earlier is essentially parsed like this: Code: C  [Select][+][-]window.onload = function(){var x1 = document.getElementById("main_content_section"); if (x1) { var x = document.getElementsByClassName("geshi");for (var i = 0; i char* strcpy(...); A function pointer to a strcpy compatible function would look like this: Code: C  [Select][+][-]window.onload = function(){var x1 = document.getElementById("main_content_section"); if (x1) { var x = document.getElementsByClassName("geshi");for (var i = 0; i typedef char* (*StrCpyFunc)(...); Yes, but typedef does not make from Code: C  [Select][+][-]window.onload = function(){var x1 = document.getElementById("main_content_section"); if (x1) { var x = document.getElementsByClassName("geshi");for (var i = 0; i char* func(...);neither Code: C  [Select][+][-]window.onload = function(){var x1 = document.getElementById("main_content_section"); if (x1) { var x = document.getElementsByClassName("geshi");for (var i = 0; i char* (*func)(...);nor Code: C  [Select][+][-]window.onload = function(){var x1 = document.getElementById("main_content_section"); if (x1) { var x = document.getElementsByClassName("geshi");for (var i = 0; i char (*func)(...);as you write in yor previous post. QuoteQuote from: tetrastes on May 13, 2020, 12:11:24 pmI mean that the code without pointer Code: C  [Select][+][-]window.onload = function(){var x1 = document.getElementById("main_content_section"); if (x1) { var x = document.getElementsByClassName("geshi");for (var i = 0; i typedef void my_annoying_c_function(size_t sz); my_annoying_c_function func;is absolutely legal. Yes, but you can't do anything with it: Yes, of cause,it is only another way to declare Code: C  [Select][+][-]window.onload = function(){var x1 = document.getElementById("main_content_section"); if (x1) { var x = document.getElementsByClassName("geshi");for (var i = 0; i void func(size_t sz);  And now change your code as you believe it will work: Code: C  [Select][+][-]window.onload = function(){var x1 = document.getElementById("main_content_section"); if (x1) { var x = document.getElementsByClassName("geshi");for (var i = 0; i int somefunc(){   return 42;} typedef int *IntFunc();   //  ADD * HERE int main(){   IntFunc func1 = somefunc;   IntFunc func2 = &somefunc;   IntFunc func;      func = somefunc;   func = &somefunc;    return func();} Code: Bash  [Select][+][-]window.onload = function(){var x1 = document.getElementById("main_content_section"); if (x1) { var x = document.getElementsByClassName("geshi");for (var i = 0; i $ gcc test.c test.c: In function 'main':test.c:10:4: error: function 'func1' is initialized like a variable   10 |    IntFunc func1 = somefunc;    |    ^~~~~~~test.c:11:4: error: function 'func2' is initialized like a variable   11 |    IntFunc func2 = &somefunc;      |    ^~~~~~~test.c:14:9: error: lvalue required as left operand of assignment   14 |    func = somefunc;      |         ^test.c:15:9: error: lvalue required as left operand of assignment   15 |    func = &somefunc;      |         ^test.c:17:11: warning: returning 'int *' from a function with return type 'int' makes integer from pointer without a cast [-Wint-conversion]   17 |    return func();      |         ^~~~~~ ---------------------------------------------------------------------- jiaxing2 · 2020-05-13 16:17 C sucks. I hate C ---------------------------------------------------------------------- jamie · 2020-05-13 23:56 na, C is just fine... I have no issues with it... Your problem is you are getting confused from all this advice you are getting that is just talking you in all four directions..  How to tell who's advice and who's theories you want to believe! ---------------------------------------------------------------------- Warfley · 2020-05-14 00:38 Well function pointers in C are simply pretty bad. I mean the best indicator how bad they are is that C++ introduced a new type (std::function) so you never have to use that awful C-syntax anymore. There are only a few things where C++ decided to "replace" C features (of course C is still a subset of C++, but there are things you should not be using in C++ that are just there for C compatibility) like NULL-pointer, C-Strings or function pointers. Because C screwed that up really hard. I mean simply the fact that there is so much confusion about such an essential language feature as function pointers shows that they are not simple ---------------------------------------------------------------------- PascalDragon · 2020-05-14 08:30 Quote from: tetrastes on May 13, 2020, 02:10:02 pmQuote from: PascalDragon on May 13, 2020, 01:37:29 pm These are not function pointers, but function declarations. You have a function pointer if you either have a typedef You are wrong. See post of Warfley. If you need function pointer, you need explicitly use brackets, with or without typedef. Whatever. The point I was trying to make is that the following does not have a direct representation in Pascal and isn't really useable without a pointer to it in C either: Code: C  [Select][+][-]window.onload = function(){var x1 = document.getElementById("main_content_section"); if (x1) { var x = document.getElementsByClassName("geshi");for (var i = 0; i typedef int SomeFunc(); So in Pascal always a function or procedure variable needs to be used for this. ---------------------------------------------------------------------- tetrastes · 2020-05-14 12:00 Quote from: PascalDragon on May 14, 2020, 10:30:37 am The point I was trying to make is that the following does not have a direct representation in Pascal and isn't really useable without a pointer to it in C either: Code: C  [Select][+][-]window.onload = function(){var x1 = document.getElementById("main_content_section"); if (x1) { var x = document.getElementsByClassName("geshi");for (var i = 0; i typedef int SomeFunc(); So in Pascal always a function or procedure variable needs to be used for this. So the code from the first question Code: C  [Select][+][-]window.onload = function(){var x1 = document.getElementById("main_content_section"); if (x1) { var x = document.getElementsByClassName("geshi");for (var i = 0; i typedef void *my_annoying_c_function(size_t sz); also does not have a direct representation in Pascal. ---------------------------------------------------------------------- PascalDragon · 2020-05-15 08:06 Quote from: tetrastes on May 14, 2020, 02:00:50 pmQuote from: PascalDragon on May 14, 2020, 10:30:37 am The point I was trying to make is that the following does not have a direct representation in Pascal and isn't really useable without a pointer to it in C either: Code: C  [Select][+][-]window.onload = function(){var x1 = document.getElementById("main_content_section"); if (x1) { var x = document.getElementsByClassName("geshi");for (var i = 0; i typedef int SomeFunc(); So in Pascal always a function or procedure variable needs to be used for this. So the code from the first question Code: C  [Select][+][-]window.onload = function(){var x1 = document.getElementById("main_content_section"); if (x1) { var x = document.getElementsByClassName("geshi");for (var i = 0; i typedef void *my_annoying_c_function(size_t sz); also does not have a direct representation in Pascal. Yes, you're right. But as long as it is used as my_annoying_c_function *somevar translating it as a function pointer is legitimate. ---------------------------------------------------------------------- BrunoK · 2020-05-15 10:26 Would that be relevant for typing and use ? Code: Pascal  [Select][+][-]window.onload = function(){var x1 = document.getElementById("main_content_section"); if (x1) { var x = document.getElementsByClassName("geshi");for (var i = 0; i program Project1; type  // typedef void my_annoying_c_function(size_t sz)  TMy_annoying_c_function = function(sz: size_t): {void} intptr; function my_annoying_c_func(sz: size_t): intptr;begin  Result := sz;end; const  my_annoying_c_function: TMy_annoying_c_function = @my_annoying_c_func; begin  writeln(my_annoying_c_func(5));  readln;end. Edit : Replace  Code: [Select]  writeln(my_annoying_c_func(5));with Code: [Select]  writeln(my_annoying_c_function(5)); ---------------------------------------------------------------------- tetrastes · 2020-05-15 11:16 Code: C  [Select][+][-]window.onload = function(){var x1 = document.getElementById("main_content_section"); if (x1) { var x = document.getElementsByClassName("geshi");for (var i = 0; i #include  typedef long long (*Tmy_annoying_c_function)(size_t sz); long long my_annoying_c_func(size_t sz){  return sz;} const  Tmy_annoying_c_function my_annoying_c_function = my_annoying_c_func; void main(void){  printf("%d\n", my_annoying_c_function(5));  scanf("%*c");} ---------------------------------------------------------------------- Warfley · 2020-05-15 12:25 Quote from: tetrastes on May 15, 2020, 01:16:03 pm[...]Except "long long int" is not IntPtr, the corresponding c type would be intptr_t from stdint.h and printf does not replace WriteLn, which can be seen quite good here because your format string is broken (%d prints an int, to print long long int you need to use lld or lli. when you would be using intptr_t you would need to distinguish between 32 and 64 bit and use ld and lld respectively), which is not possible with WriteLn because there the compiler takes care of such things. Not all Pascal programs have a perfect C representation, as pretty well seen by your example. The other direction is much better (i.e. C to pascal) because nearly all C constructs have a representation in pascal and you can use the libc in pascal (while you can't use the RTL in C). That said, these are two different languages and not everything has a 1-1 translation and some problems are simply to be expected when trying to convert from one language to the other. But your chances are better when trying to convert C to Pascal than the other way around ---------------------------------------------------------------------- tetrastes · 2020-05-15 14:52 On my system IntPtr and intptr_t are long long , though in general you are right. But in more general you are not right: To quote the C 2011 standard (page 291) from your link: http://www.open-std.org/jtc1/sc22/wg14/www/docs/n1570.pdf Quote7.20.1.4 Integer types capable of holding object pointers 1 The following type designates a signed integer type with the property that any valid pointer to void can be converted to this type, then converted back to pointer to void, and the result will compare equal to the original pointer: intptr_t The following type designates an unsigned integer type with the property that any valid pointer to void can be converted to this type, then converted back to pointer to void, and the result will compare equal to the original pointer: uintptr_t These types are optional.Note the last line. So you may not only not find intptr_t in stdint.h (for example at gcc it is defined in crtdefs.h), but not find it at all. As for printf, you are right again in general, but in this specific example printf prints "5" and nothing else, and %d do it quite well, so you need not %lld here. And of cause I agree that "Not all Pascal programs have a perfect C representation" and with all other clever words.