Snackoverflow
Snackoverflow

Reputation: 6271

const void (* to function)

Is there any difference between:

void (* const algorithm)();

and

void const (* const algorithm)();

when dealing with const pointers to static methods?

I understand that it would make sense to use const if the pointer points to memory that should not be modified, in case of pointers to variables, as stated in this answer. However, are function addresses not effectively constant during run-time anyway?

The reason I am asking this is, the second option as a function parameter does not work.

EDIT

Here is the code that does not compile.

struct A {
    static void a() {}
};

void b(void const (* const callback)()) {}

int main() {
    b(&A::a); // No matching function for call to 'b'
}

The above example works, if function a() has a return type const void.

Upvotes: 1

Views: 1781

Answers (2)

eerorika
eerorika

Reputation: 238311

const after (or before) the return type applies to the return type. There is no such thing as a "pointer to const function" as there is no such thing as a const function. (Although, there is such thing as a pointer to const member function, as const member functions do exist. But there the constness applies to the object argument, not to the function itself. There the constness is expressed in the same way as in the declaration of a member function - after the parenthesized parameter list).

There is no difference between void() and void const() in the sense that both functions behave exactly the same because there is no behavioral difference between a const void return type and a non-const void return type. Object cannot be const when there is no object.

I would expect a compiler to issue a warning when a non-class return value is directly qualified with const.

However, void() and void const() are different in the sense that void and void const are technically separate types, as are all const qualified types different from their non-const counterpart. Therefore the function pointers to const returning and non-const returning functions are different function pointer types. As such, the standard won't allow a function pointer to one type be bound to a function of another type.

So, to fix your non-compiling code, simply replace void const which is nonsensical with void in the function pointer.

Upvotes: 4

Jarod42
Jarod42

Reputation: 217145

Start with the "inner" const :

using void_function = void();
void (*p1)() = nullptr;        // similar to `void_function* p1 = nullptr;`
void (* const p2)() = nullptr; // similar to `void_function* const p2 = nullptr;`

p2 is constant whereas p1 is mutable.

When moving const, as following:

const void_function* p3 = nullptr; // or void_function const* p3; // -> const has no effect
void (const* p4)() = nullptr;      // Invalid syntax

There are no "const function" vs "mutable function".

Now, looking at function return type:

Types void () (function returning void) and const void () (function returning const void !?) are different.

Even if const void make no real sense, it is a valid type.

It might make sense to return const object from function to disallow "direct" modification of the object:

const std::string make_const_string();

make_const_string().push_back('*'); // Doesn't work
std::string s = make_const_string(); // OK, create mutable copy.

So to fix your code:

struct A {
    static void a() {}
};

void b(void const (* const callback)()) {}

int main() {
    b(&A::a); // No matching function for call to 'b'
}

You have to make &A::a match b's argument type:

  • static const void a() {}
  • void b(void (*const callback)())

I suggest second one as const void make no real sense.

Upvotes: 0

Related Questions