2

Possible Duplicate:
C++ return array from function

I am trying to declare a function that returns an array of void pointers. I have the following code:

void *[] get_functions();

However I get the compilation error: expected unqualified-id before '[' token

Is what I'm trying to do valid, and if so what is my syntax error?

EDIT In reply to some of the comments, I am trying to return an array (which now will probably be a vector) of functions, which I can then randomly select one and call it. What would you suggest instead of void *?

EDIT 2 The type of functions returned will have a fixed signature (not decided yet), Let's for arguments sake say the signature will be int f(int i, int j) what would the return of my get_functions function look like, or will vector<void*> still be appropriate?

Community
  • 1
  • 1
Aly
  • 15,865
  • 47
  • 119
  • 191
  • Just use `void *` or `std::vector`. The `[]` doesn't add anything. (Think about it. What difference would it make? Also, think about what would happen if you did a `sizeof` on the returned value.) – David Schwartz Oct 11 '12 at 11:50
  • 2
    Chances are, void pointers are the wrong thing to use here. Tell us more about your actual problem and we might be able to suggest a better solution. – Konrad Rudolph Oct 11 '12 at 11:51
  • If you need `void*`, you're probably doing something wrong. – Luchian Grigore Oct 11 '12 at 11:51
  • I agree. Most likely there's a better way to solve your outer problem. – David Schwartz Oct 11 '12 at 11:51
  • The correct syntax is `void * get_functions()[]`, but it's not valid C++ (you cannot return arrays). You can however return pointers or references to arrays, like `void * (& get_functions())[10]`. – Kerrek SB Oct 11 '12 at 12:01
  • or return a struct containing the array, since the compiler can generate a copy constructor for it and use a block memory copy. – Pete Oct 11 '12 at 12:14
  • In most cases you should not return arrays and you should not use `void*`. While you have a compiler error there that can be fixed the larger issue is the design in your application. Revisit it. – David Rodríguez - dribeas Oct 11 '12 at 12:52
  • After the **EDIT**: if the signature is fixed, an vector of pointers to the functions. Note that the conversion from function pointer to `void*` is not guaranteed. – David Rodríguez - dribeas Oct 11 '12 at 12:54
  • @DavidRodríguez-dribeas the signature is not fixed at all, its up for debate. I'm new to c++ so if there is a better way to do this I am happy to learn :) – Aly Oct 11 '12 at 12:56
  • @Aly: How will the caller know how many arguments to pass? The whole design is dangerous. (I am assuming that *not fixed* means that different entries in the array will have different signatures) – David Rodríguez - dribeas Oct 11 '12 at 12:58
  • @DavidRodríguez-dribeas oh sorry I misunderstood, the signature of the returned functions will be fixed (not decided yet as I was just trying to see how to return a vector of void *). Let's for arguments sake say the signature will be int f(int i, int j) what would my get_functions declaration look like? – Aly Oct 11 '12 at 13:02
  • I would use a typedef: `typedef int (*f_ptr)(int,int); std::vector get_functions();` But it can be done in one line: `std::vector get_functions();` (An advantage of the typedef approach is that if you consistently use the typedef, there is a single place to change the signature --of course you will have to also fix the calls). There are more generic approaches (if you need to adapt pointers to functions of different signatures), like using `std::function` instead of the function pointer – David Rodríguez - dribeas Oct 11 '12 at 13:07

4 Answers4

8

C++ doesn't allow a function to return an array. You should probably return a vector instead:

std::vector<void *> get_functions();
Jerry Coffin
  • 476,176
  • 80
  • 629
  • 1,111
  • 3
    Next up, get rid of the void pointers. – Konrad Rudolph Oct 11 '12 at 11:50
  • What is the advantage to returning std::vector rather than a void**? – Dasaru Oct 11 '12 at 11:55
  • 4
    @Dasaru: All the usual advantages of using `std::vector` over handling all the work on your own. Basically, if you use void **, you probably need to dynamically allocate the data. That means the caller needs to free the data. Making it exception safe without an RAII wrapper is difficult at best. Bottom line: dynamic allocation is one of the leading causes of problems in C. Automating it is one of the major advantages of C++. – Jerry Coffin Oct 11 '12 at 12:03
2

There are two issues with your approach. The first of which is that you cannot return arrays from functions. In C you would return a pointer to the elements in the array, but that implies that you need to manage the memory. In C++ you can use a container, like std::vector instead of the array, and that can be returned by value.

The second issue is that you are returning function pointers, and the conversion from function pointer to void* is not guaranteed by the standard. The alternatives here start with returning a function pointer of the appropriate type (i.e. std::vector<int (*)(int,int)>) or using higher level constructs like std::function (C++11, or boost::function in C++03): std::vector<std::function<int(int,int)>>. The first approach is better suited for the description you provided as the types of the functions seem to be fixed and there will be little overhead in using the function pointers. The second approach is more generic as it can encapsulate anything that is callable with two int and return an int, including function pointers and function objects. That in turn allows you to adapt the signatures of other functions by means of std::bind or create lambdas with the appropriate signature: [](int x, int y){ return x*y;}

David Rodríguez - dribeas
  • 204,818
  • 23
  • 294
  • 489
1
void **get_functions();

Later on you can then say:

void **pp = get_functions();
pp[5];     // This is the sixth pointer-to-void

If you don't already know the length of the array, you will need to pass it some other way -- for that reason, Jerry Coffin's answer is probably better.

j_random_hacker
  • 50,331
  • 10
  • 105
  • 169
0

you can just return void pointer to first element of the array. and you can cast it inside the calling function. the array itself is passed/returned as a pointer.

MSalah
  • 41
  • 2