marsh
marsh

Reputation: 2720

Calling Const function pointer

First off I would like to mention that this works with MSVC but not with clang. I am using Clang with c++11.

I have a function pointer:

typedef void (*Log) (const char* title, const char* msg, const char* file, int line);

I have this struct:

 struct FunctionList
    {
    protected:
        static const int kNbrMax = 32;
        FunctionList();
        bool Add(const void* f);
        bool Remove(const void* f);

        const void*     m_functions[kNbrMax];
    };

And this class:

template<typename T>
struct MessageFunctionList
    : public FunctionList
{
public:
    MessageFunctionList(T defaultFunction)  
    {
        Add(defaultFunction);
    }

    void Call(const char* title,const char* cause,const char* file,int line)
    {
        for (unsigned long i = 0;i < m_nbrUsed;++i)
        {
            reinterpret_cast<T>(m_functions[i])(title,cause,file,line);
        }
    }
}

I am creating it like so:

static void DefaultLogMessageFunction(const char* title,const char* msg,const char* file,int line)
{

}

MessageFunctionList<Log> functionList(DefaultLogMessageFunction)

But I get the compile time error:

reinterpret_cast from 'const void ' to 'void ()(const char *, const char *, const char *, int)' casts away qualifiers for line: reinterpret_cast(m_functions[i])(title,cause,file,line);

So as far as I understand I am trying to cast my const list of functions to a non const value. That is not allowed which makes sense. So I tried the following:

const void* funcPtr = m_functions[i];
const T call = reinterpret_cast<const T>(funcPtr);
call(title, cause, file, line);

But that does not work either.

This works:

void* funcPtr = const_cast<void*>(m_functions[i]);
T call = reinterpret_cast<T>(funcPtr);
call(title,cause,file,line);

But I would like to avoid using a const cast. What am I doing wrong? How can I call this const function? Or is it simply not allowed because it does not know if the function being called is a const function or not? Or perhaps it is because my static function is not a member of a class so it can not be declared const?

Upvotes: 0

Views: 1928

Answers (1)

Fatih BAKIR
Fatih BAKIR

Reputation: 4715

You are storing the function pointers as const void*:

const void*     m_functions[kNbrMax];

And you are trying to cast them to T and call it using reinterpret_cast:

reinterpret_cast<T>(m_functions[i])(title,cause,file,line);

However, reinterpret_cast cannot remove const qualifier from a type, therefore, you should first remove the const using const_cast:

reinterpret_cast<T>(const_cast<void*>(m_functions[i]))(title,cause,file,line);
                    ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

However, please note that const_cast engenders undefined behavior and is unsafe. So is calling a function pointer returned from reinterpret_cast if the original pointer was not actually a T.

Edit: You can call a const qualified function pointer, however, then the reinterpret_cast should contain the const qualifier:

reinterpret_cast<const T>(m_functions[i])(title,cause,file,line);

Upvotes: 3

Related Questions