2

In Xcode 7.2.1, I declare 3 C functions

double function1(double);
double function2(double);
double function3(double);

Now I declare a pointer to a function and define it.

double (*aFunctionPointer)(double)=function1;

No errors, as expected.

Now I declare an array of function pointers and fill it with my 3 functions.

double (*anArrayOfFunctionPointers[3])(double)={function1, function2, function3};

Again, no errors.

Now I define an array of function pointers, but do not fill it.

double (*anotherArrayOfFunctionPointers[3])(double);

Again, no errors.

Now I try to assign a function to one of the array elements.

anotherArrayOfFunctionPointers[1]=function2;

This time, warnings and errors:

  • Warning: Type specifier missing, defaults to int
  • Error: Redefinition of 'anotherArrayOfFunctionPointers' with a different type:'int [0]' vs 'double (*[3]) (double)'

I am stumped.

The background is that I am trying to write a program to convert between various units of measure. I thought I would use a two-dimensional array containing function pointers, in order to avoid a number of very lengthy switch statements.

To make a conversion, I would call a function as follows:

result=convert(someValueToConvert,yards,meters);

and the convert function would invoke the correct function from the array like so:

return conversionFunctionArray[yards, meters](someValue);

The array would be initialized like so:

conversionFunction[yards][meters]=yardsToMeters(somevalue);
conversionFunction[meters][yards]=metersToYards(somevalue);
conversionFunction[yards][feet]=yardsToFeet...
...

What am I missing as regards function pointers and arrays?

2
  • typedef is a very useful tool when dealing with function pointers. Try something like typedef double (*funcPtr_t)(double); to create a function pointer type, then something like funcPtr_t funcPtrArray[3]; for your array. Commented Feb 19, 2016 at 17:07
  • 1
    The error clearly states that you've redefined anotherArrayOfFunctionPointers. So somewhere in your test code you have an older definition of that array. Note that I followed all of your instructions line by line, and did not get any errors or warnings. That's why the site requires that debugging questions must include a Minimal Complete Verifiable Example. Commented Feb 19, 2016 at 17:22

2 Answers 2

4

Here's what a Minimal Complete Verifiable Example looks like for this question, based on the piecemeal instructions in the question.

#include <stdio.h>

double f1( double );
double f2( double );
double f3( double );

int main( void )
{
    // testing a single function pointer
    double (*ptr1)(double) = f1;
    printf( "%.0lf\n\n", (*ptr1)(5) );

    // testing an array of function pointers with an initializer list
    double (*array[3])(double) = { f1, f2, f3 };
    for ( int i = 0; i < 3; i++ )
        printf( "%.0lf\n", (*array[i])(6) );
    printf( "\n" );

    // testing an array of function pointers that is initialized by assignments
    double (*otherArray[3])(double);
    otherArray[0] = f1;
    otherArray[1] = f2;
    otherArray[2] = f3;
    for ( int i = 0; i < 3; i++ )
        printf( "%.0lf\n", (*otherArray[i])(7) );
    printf( "\n" );
}

double f1( double x ) { return 10+x; }
double f2( double x ) { return 20+x; }
double f3( double x ) { return 30+x; }

Note that this code compiles without any errors or warnings, and produces the expected output. Demonstrating once again why debugging questions must include a Minimal Complete Verifiable Example.

Sign up to request clarification or add additional context in comments.

Comments

2

One obvious problem is that you have not actually defined any of the functions function1 etc.

To see this, let's do this with just one function and with arrays of just one element. Put this at top level:

double function1(double);
double (*aFunctionPointer)(double)=function1;
double (*anArrayOfFunctionPointers[1])(double)={function1};
double (*anotherArrayOfFunctionPointers[1])(double);

And in actual executable code, do this:

anotherArrayOfFunctionPointers[0]=function1; // error

That's an error. But now let's actually define function1, like this:

double function1(double f) {return 3.0;};
double (*aFunctionPointer)(double)=function1;
double (*anArrayOfFunctionPointers[1])(double)={function1};
double (*anotherArrayOfFunctionPointers[1])(double);

And now let's try the same code:

anotherArrayOfFunctionPointers[0]=function1;

No error. The difference is that now we actually have a function1 to point to. With your code, there's no there there.

1 Comment

By the way, stylistically, when you are passing function pointers around, you might like to use the ampersand: &function1. This is absolutely not necessary, but I find it makes for clarity of intention.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.