Recent

Author Topic: How to translate typedef void * to Pascal?  (Read 6322 times)

jiaxing2

  • Full Member
  • ***
  • Posts: 164
How to translate typedef void * to Pascal?
« on: May 12, 2020, 07:34:34 pm »
Example: typedef void *my_annoying_c_function(size_t sz);

JdeHaan

  • Full Member
  • ***
  • Posts: 118
Re: How to translate typedef void * to Pascal?
« Reply #1 on: May 12, 2020, 07:57:08 pm »
type
  TMy_Annoying_C_Function = procedure(sz: QWord);

jamie

  • Hero Member
  • *****
  • Posts: 6130
Re: How to translate typedef void * to Pascal?
« Reply #2 on: May 12, 2020, 08:01:29 pm »
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.
The only true wisdom is knowing you know nothing

Thaddy

  • Hero Member
  • *****
  • Posts: 14373
  • Sensorship about opinions does not belong here.
Re: How to translate typedef void * to Pascal?
« Reply #3 on: May 12, 2020, 08:27:21 pm »
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.
« Last Edit: May 12, 2020, 09:04:59 pm by Thaddy »
Object Pascal programmers should get rid of their "component fetish" especially with the non-visuals.

440bx

  • Hero Member
  • *****
  • Posts: 4029
Re: How to translate typedef void * to Pascal?
« Reply #4 on: May 12, 2020, 09:04:43 pm »
It's probably worth noting that size_t isn't qword.
(FPC v3.0.4 and Lazarus 1.8.2) or (FPC v3.2.2 and Lazarus v3.2) on Windows 7 SP1 64bit.

Thaddy

  • Hero Member
  • *****
  • Posts: 14373
  • Sensorship about opinions does not belong here.
Re: How to translate typedef void * to Pascal?
« Reply #5 on: May 12, 2020, 09:05:37 pm »
It'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);
« Last Edit: May 12, 2020, 09:27:00 pm by Thaddy »
Object Pascal programmers should get rid of their "component fetish" especially with the non-visuals.

tetrastes

  • Sr. Member
  • ****
  • Posts: 481
Re: How to translate typedef void * to Pascal?
« Reply #6 on: May 12, 2020, 09:54:40 pm »
Then how to translate
Code: C  [Select][+][-]
  1. typedef void my_annoying_c_function(size_t sz);
  2.  

jamie

  • Hero Member
  • *****
  • Posts: 6130
Re: How to translate typedef void * to Pascal?
« Reply #7 on: May 12, 2020, 11:00:56 pm »
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.

And Please explain to me where I am incorrect?

 You are a piece of work Thaddy in your own mind!

The only true wisdom is knowing you know nothing

PascalDragon

  • Hero Member
  • *****
  • Posts: 5481
  • Compiler Developer
Re: How to translate typedef void * to Pascal?
« Reply #8 on: May 13, 2020, 09:32:24 am »
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.

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][+][-]
  1. 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.

Then how to translate
Code: C  [Select][+][-]
  1. typedef void my_annoying_c_function(size_t sz);
  2.  


In the end those are used like this:

Code: C  [Select][+][-]
  1. 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

  • Hero Member
  • *****
  • Posts: 14373
  • Sensorship about opinions does not belong here.
Re: How to translate typedef void * to Pascal?
« Reply #9 on: May 13, 2020, 12:07:38 pm »
And 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.
Object Pascal programmers should get rid of their "component fetish" especially with the non-visuals.

tetrastes

  • Sr. Member
  • ****
  • Posts: 481
Re: How to translate typedef void * to Pascal?
« Reply #10 on: May 13, 2020, 12:11:24 pm »

Thaddy is right however. The declaration that jiaxing2 posted is essentially parsed like this:

Code: C  [Select][+][-]
  1. typedef void (*my_annoying_c_function)(size_t sz);


Really? So
Code: C  [Select][+][-]
  1. void *malloc(size_t size);
returns nothing?

And
Code: C  [Select][+][-]
  1. char *strcpy(char *dest, const char *src);
is parsed like
Code: C  [Select][+][-]
  1. char (*strcpy)(char *dest, const char *src);
and returns one char, not c-style string?

Quote
Then how to translate
Code: C  [Select][+][-]
  1. typedef void my_annoying_c_function(size_t sz);
  2.  


In the end those are used like this:

Code: C  [Select][+][-]
  1. 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][+][-]
  1. typedef void my_annoying_c_function(size_t sz);
  2.  
  3. my_annoying_c_function func;
is absolutely legal.
« Last Edit: May 13, 2020, 01:13:19 pm by tetrastes »

Thaddy

  • Hero Member
  • *****
  • Posts: 14373
  • Sensorship about opinions does not belong here.
Re: How to translate typedef void * to Pascal?
« Reply #11 on: May 13, 2020, 12:25:22 pm »
The pointer is simply the immediate address of the function itself, not a return value.
Object Pascal programmers should get rid of their "component fetish" especially with the non-visuals.

jiaxing2

  • Full Member
  • ***
  • Posts: 164
Re: How to translate typedef void * to Pascal?
« Reply #12 on: May 13, 2020, 01:24:28 pm »
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.
« Last Edit: May 13, 2020, 01:27:14 pm by jiaxing2 »

Warfley

  • Hero Member
  • *****
  • Posts: 1499
Re: How to translate typedef void * to Pascal?
« Reply #13 on: May 13, 2020, 01:30:42 pm »
typedef 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][+][-]
  1. 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][+][-]
  1. 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][+][-]
  1. type my_annoying_c_function = function(sz: SizeInt): Pointer;

PascalDragon

  • Hero Member
  • *****
  • Posts: 5481
  • Compiler Developer
Re: How to translate typedef void * to Pascal?
« Reply #14 on: May 13, 2020, 01:37:29 pm »
And 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().


Thaddy is right however. The declaration that jiaxing2 posted is essentially parsed like this:

Code: C  [Select][+][-]
  1. typedef void (*my_annoying_c_function)(size_t sz);


Really? So
Code: C  [Select][+][-]
  1. void *malloc(size_t size);
returns nothing?

And
Code: C  [Select][+][-]
  1. char *strcpy(char *dest, const char *src);
is parsed like
Code: C  [Select][+][-]
  1. 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][+][-]
  1. struct Whatever
  2. {
  3.   void (*someproc)();
  4. }

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][+][-]
  1. char* strcpy(...);

A function pointer to a strcpy compatible function would look like this:

Code: C  [Select][+][-]
  1. typedef char* (*StrCpyFunc)(...);

I mean that the code without pointer
Code: C  [Select][+][-]
  1. typedef void my_annoying_c_function(size_t sz);
  2.  
  3. my_annoying_c_function func;
is absolutely legal.

Yes, but you can't do anything with it:

Code: C  [Select][+][-]
  1. int somefunc()
  2. {
  3.    return 42;
  4. }
  5.  
  6. typedef int IntFunc();
  7.  
  8. int main()
  9. {
  10.    IntFunc func1 = somefunc;
  11.    IntFunc func2 = &somefunc;
  12.    IntFunc func;
  13.    
  14.    func = somefunc;
  15.    func = &somefunc;
  16.  
  17.    return func();
  18. }

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.

 

TinyPortal © 2005-2018