-
Notifications
You must be signed in to change notification settings - Fork 28
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Function pointer casting #83
Comments
The main question is: how to write type-safe generic C procedure calling passed in procedure via a type-erasured function pointer? |
I believe this behavior is technically undefined behavior in C (e.g., see this StackOverflow question). Since we have proposed for Ivory to produce only well-defined C programs (when statically checkable), we should probably omit function pointer casts. |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
I'm trying to call a procedure and pass it a pointer to another procedure via some generic interface.
In real life it may be
qsort
or any other procedure with callback.Here is a simplified example.
In C it works like so:
(checked with
gcc -Wall -Wextra -Werror -ansi -pedantic
)Let's reproduce this in Ivory!
Works good with concrete type
uint32_t
. Now let's generalize it tovoid *
.But we can't
call_ apply (procPtr print) (constRef str)
,because Haskell can't unify
Uint32
inprint
's type and()
inapply
's type.In C we used type cast to solve this problem. Can we cast these types in Haskell/Ivory language?
We can't use
safeCast
, because there are noSafeCast
instances for anything like pointer types.Looks like casting pointers in considered unsafe. Seem rational.
Let's try unsafe
ivoryCast
.call_ apply (ivoryCast (procPtr print)) (ivoryCast str)
The cast for
str
works, but the first one throws an error:There is no IvoryExpr instance for ProcPtr!
Why? Because, unlike majority of Ivory types, ProcPtr is not a wrapper around Expr and so
cannot be constructed by wrapping around Expr.
A strange thing
Under some assumptions, we can cast to a secondary function pointer in Ivory.
Assumption 1. Make
apply
function external.(Unfortunately, we can't implement it in Ivory,
because there is no instance of IvoryStore neither for Def nor for ProcPtr.)
Assumption 2. Relax requirements of ivoryCast.
Now we can use pointers to function pointers!
And Ivory generates the following code:
The result is incorrect, but the
IvoryExpr
instance works as expected!Is primary function pointer cast impossible in Ivory when the secondary one is possible?
The text was updated successfully, but these errors were encountered: