1

I have a function that takes a parameter of type function (uint256) view returns (uint256).

I want to pass it a pointer to a function of type function (uint256) pure returns (uint256).

Obviously there shouldn't be a problem with passing this pure function into a parameter that expects a view function, because the parameter and returns types are the same and pure is even more limiting than view. However, I get this TypeError:

TypeError: Invalid type for argument in function call. Invalid implicit conversion from function (uint256) pure returns (uint256) to function (uint256) view returns (uint256) requested.

Things I've tried:

Assigning the function to a local variable gives a similar TypeError:

function(uint256) view returns(uint256) a = func;

TypeError: Type function (uint256) pure returns (uint256) is not implicitly convertible to expected type function (uint256) view returns (uint256)

The usual type-casting syntax of Solidity gives a ParserError at the function keyword

function(uint256) view returns(uint256) a = function(uint256) view returns(uint256)  (func);

ParserError: Expected primary expression

-------

I've noticed that the TypeError's keep telling me that the function pointer is not implicitly convertible. Is there a way to explicitly convert it?

  • What operation do you want to do that this work is necessary for it? – Alireza Zojaji Feb 9 at 23:06
  • I have a higher-order function that takes a view function as parameter. I want to pass it a pure function. – Jesse Busman Feb 10 at 14:39
  • The main question is that what operation makes you to pass a function as a parameter to another function? Isn't it possible to do it in ordinary methods? – Alireza Zojaji Feb 10 at 15:47
  • Yes, I could inline the code of my higher order function wherever it is called, but I don't want to duplicate that code everywhere. My situation is: I have a non-fungible token with a bunch of dynamically calculated properties (implemented as view or pure functions). Some of those properties are actually just combinations of other properties. For example, property G might be true only if ((A or B) and (C+D+E+F >= 6)) is true. To compute G I don't necessarily need all of A-F, so I combine the property functions using higher-order functions that implement short-cutting behaviour. – Jesse Busman Feb 10 at 17:36
1

Update: In recent Solidity versions, pure function pointers are now implicitly convertible to view function pointers.

I did not find a solution to this problem, so I submitted an issue on Github: https://github.com/ethereum/solidity/issues/4349

I did find two ways to work around the problem:

1: Downgrade all my pure functions to view.

2: Use inline assembly to assign to a local variable, thereby circumventing the Solidity type system:

function(uint256)view returns(uint256) a;
assembly { a := func }
-2

I cannot understand your point.

In solidity they do not exist function pointers, because the calling mechanism is to pass the control to the smart contract which owns the function and to use ABI table to jump there to the function first instruction.

So there is not a pointer to a function you can use like you do in C!

In Solidity the address of any function IS the ethereum addess of its smart contract

I.e. in a qualitative way, the address (function foo()) is the address of the smart contract implementing foo()

May be I did not understand properly your question!


EDIT AFTER COMMENTS

Typecast cannot be applied to function type, as far as I know only implicit conversion can be done and this IS the demonstration that the function pointer as lvalue DO NOT EXISTS.

From solidity docs:

"A value of external function type can be explicitly converted to address resulting in the address of the contract of the function.

A function type A is implicitly convertible to a function type B if and only if their parameter types are identical, their return types are identical, their internal/external property is identical and the state mutability of A is not more restrictive than the state mutability of B. In particular:

pure functions can be converted to view and non-payable functions view functions can be converted to non-payable functions payable functions can be converted to non-payable functions

No other conversions between function types are possible."

Anyway if we are here to learn, so I hope to learn something new from you soon.

Check also function as parameter

  • You are talking about external functions, my question is about function pointers for internal functions. For those, there certainly are pointers to internal functions like in C. – Jesse Busman Mar 13 at 10:40
  • Yes, they exist local addresses equal to the first instruction of any function, but you cannot extract them by high level language (Solidity), neither use typecast on them! – Rick Park Mar 13 at 10:41
  • Suppose you have an internal pure function: function testFunc(uint256 x) internal pure returns (uint256 y) { return x+5; } Now you can put its function pointer in a local variable with the appropriate type: function(uint256) internal pure returns (uint256) func = testFunc; And you can call the function via its function pointer: func(345) – Jesse Busman Mar 13 at 10:50
  • My question is about the ability to cast a function pointer of type function (uint256) internal pure returns (uint256) to type function (uint256) internal view returns (uint256). Do you understand now? – Jesse Busman Mar 13 at 10:56
  • Also, please don't speak so certainly about something you don't know. It's very rude. – Jesse Busman Mar 13 at 11:00

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.