-2

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])
15
  • 1
    int(int) is a function type? Commented Sep 3, 2017 at 20:40
  • 2
    @user0042 Why not? Commented Sep 3, 2017 at 20:41
  • 5
    A function is code, not data. C++ allows, however, arrays of pointers to functions. Commented Sep 3, 2017 at 20:41
  • 1
    You probably meant int(*)(int). Commented Sep 3, 2017 at 20:45
  • 2
    I believe the memory representation of a function type is not defined by the standard; sizeof a function type is illegal. Naturally you can't have an array of things with no size. Commented Sep 3, 2017 at 20:47

2 Answers 2

5

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.

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

6 Comments

I think it is the first time someone stated that simplicity was one of the most important C++ design goals.
Well, it was a design goal for C, LOL.
@VTT yes, i think it should have been 0-overhead abstraction and direct hardware mapping. Anyway this is a technical consideration to my question.
C certainly did simplify many aspects of software development back then, that is one of the reasons it got so wide speeded after all. However the simplicity of language itself seems to always been of the last concern. Just take a look at crazy spiral function pointers array declaration syntax.
I don't think that holds up as a good example. The syntax is simple and logical. It may be supposed that a simpler, less confusing syntax could have been devised, but that is a matter of over four decades’ hindsight.
|
-2

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);

}

9 Comments

I'm not the downvoter, but I suspect the reason is that the OP wants to have an array of functions, not pointers or references to functions.
Thanks but I do know how to fix my situation; I just want to know the underlying consideration of such language rule.
@Dúthomhas a function pointer is to all intents and purposes a function, and the second form captures function objects. People can downvote all they want, but I think I answered the question :)
@RichardHodges I'm going to disagree there. A function pointer is not a function. OP knows the difference between the two and is not asking how to do it, but why the standard forbids one.
@RichardHodges You’re arguing two halves in order to justify equating two different things. OP wasn’t asking what you are answering. And I’m not interested in arguing the details.
|

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.