What is the underlying rationale (technical or conceptual) that C++ does not allow defining array of function type? E.g.
using fn_t = int(int);
fn_t ary[2]; // ERROR (ref: ISO/IEC-14882 [dcl.array])
Given two random functions I just made up:
int a( int x, int y )
{
return x * y;
}
int b( int x, int y )
{
int result = 0;
for (int xi = 1; xi <= x; xi++)
for (int yi = y; yi > 0; yi--)
result += xi * xi;
return result;
}
How do you suggest I put them in an array?
I could compile them, I suppose, then just have an array of max( sizeof(a’s bytecode), sizeof(b’s bytecode) ). But now I have some additional considerations:
Where does this array go?
Some processors can run code from anywhere in memory. Some cannot.
What about security attributes for the code?
What about relocation considerations?
How do I call this function?
Can I use the processor’s usual calling conventions?
Or will this require extra behind-the-scenes magic?
What happens when I want a pointer to the array?
What happens if I move the array and then call the pointer?
What about exceptions and other abnormal signal considerations?
This is just the tip of the iceberg. There are a lot of technical considerations to doing this kind of thing.
Which leads to the main consideration:
What advantage would this give over pointers to functions?
With a pointer to a function, I can do everything I otherwise wanted to do:
int (*fs)(int,int)[] = { a, b };
int x = fs[0]( 10, 10 );
int y = fs[1]( 10, 10 );
The language is designed with several goals — two of the most important being simplicity and flexibility.
Doing what you would reduces both simplicity and flexibility for everyone: compiler writers, compilers themselves, runtime management, speed, safety, etc.
EDIT: tl;dr Because it offers no advantage over pointers or references to functions, but plenty of drawbacks.
What is the underlying rationale (technical or conceptual) that C++ does not allow defining array of function type?
What is a function? It's just some code at an address. Conceptually it's a singleton, since there is no reasonable way to copy one or allocate one on the heap. Why would you? It already exists. It has a name, and that name yields a function pointer - the address of the code.
There is a concept of a 'function object', which is more equivalent to the 'first class function' of high level languages like python or javascript.
But under the hood it's modelled as a structure containing the address of code (a function pointer) and some state.
There are a few ways to create an array of functions: (this code is c++14)
#include <functional>
#include <iostream>
int a(int i) {
std::cout << "called a with " << i << std::endl;
return i;
}
int b(int i) {
std::cout << "called b with " << i << std::endl;
return i + 1;
}
int c(int i) {
std::cout << "called c with " << i << std::endl;
return i + 2;
}
int main()
{
// make life easier by creating a typedef
using raw_fptr = int (*)(int);
// an array of function pointers
raw_fptr raw_ptrs[] =
{
a, b, c
};
// a typedef of a std::function object
using fobject = std::function<int(int)>;
// an array of function objects
fobject fobjects [] = {
&a, // can capture a function pointer
[](int i) -> int { // or a lambda
return b(i);
},
std::bind(&c, std::placeholders::_1) // or a binder
};
for (auto&& f : raw_ptrs)
f(0);
for (auto&& f : fobjects)
f(1);
}
int(int)is a function type?int(*)(int).sizeofa function type is illegal. Naturally you can't have an array of things with no size.