Passing a function as parameter in ROBOTC

Hi guys, I was trying the example from the following site:

Is it possible to do it in robotC?, I’ve tried the following, but the compiler didn’t let me:

void print (int x ) {
  int a=x;
}
void func ( void (*f)(int)){
	 print();
}

task main(){
	func(print);
}

I compiled in RobotC v4.10
and RobotC v3.61

Okay so based off the stack overflow page it looks like your are trying to use pointers.

I would suggest reading this page on RobotC API because robotC have different syntax.

http://www.robotc.net/wiki/Pointers

Also just for when this discussion gets more advanced can you specify what version of robotc you are running?

Not possible to use function pointers in ROBOTC. Other uses of pointers are supported.

Firstly, your code is not actually using the functionality that you are trying to implement. I’ve added comments to your code to explain:

Here is an example of what your code should look like:

void print (int x) {
  int a=x;
}
void func (void (*f)(int)) {
  int val = 5;
  (*f)(val);
}

task main() {
  func(print);
}

Theoretically, this would work. The function “func” would be run with the “print” function as the input, so “print” would be run with the integer “5” as the input, and therefore the local variable “a” would be set equal to the integer “5”. Unfortunately, it appears that RobotC does not have this ability. Perhaps you could suggest this to them as an addition.

~Jordan

Does anyone know if this works in PROS? It could be very useful for choosing multiple autonououses (or is it autonomice) without eternal, long if statements.

A pointer to a function is pretty standard C, it will work in both PROS and ConVEX (and EasyC if you know what to do).

I already use them in the ConVEX library, for example in the vexMotorPositionGet function I use a function pointer like this.

Notice I check for a NULL pointer before using it (as well as bounds checking the index parameter), this is important, a call to a NULL pointer will crash the code, leave the motors running and upset event organizers.


int32_t
vexMotorPositionGet( int16_t index )
{
    int32_t     position;

    if( (index < kVexMotor_1) || (index >= kVexMotorNum))
        return(0);

    if( vexMotors index ].motorPositionGet != NULL )
        {
        position = vexMotors index ].motorPositionGet( vexMotors index ].port );

        // 269 needs reversing
        if( vexMotors index ].type == kVexMotor269 )
            position = -position;

        if(!vexMotors index ].reversed )
            return( position );
        else
            return( -position );
        }
    else
        return(0);
}

motorPositionGet is a pointer to a function declared like this.

    int32_t            (*motorPositionGet)( int16_t port );

which I set during initialization using a call to this code.

void
vexMotorPositionGetCallback( int16_t index, int32_t (*cb)(int16_t), int16_t port )
{
    if( (index < kVexMotor_1) || (index >= kVexMotorNum))
        return;

    vexMotors index ].motorPositionGet = cb;
    vexMotors index ].port = port;
}

here is the call to the above function if the encoder is a quad encoder

// set the get position callback
vexMotorPositionGetCallback( _cfg->port, vexEncoderGet, _cfg->channel );

or an IME

// set the get position callback
vexMotorPositionGetCallback( _cfg->port, vexImeGetCount, _cfg->channel );

So either vexEncoderGet or vexImeGetCount will be called when I want motor position depending on how the motor has been configured.