Behaviour of const qualified function in C

Viewed 240

I was wondering if const qualifying function pointers makes any difference, since the only meaning i could think of is auto const-qualifying its parameters, which is of course not the case.

I created a little example file (test.c):

typedef void* vop(void*);

vop  fn;
const vop cfn;

int main(void){
    vop *p_fn = fn;
    const vop *cp_fn = fn;  // <- gives compiler warning
    vop *p_cfn = cfn;
    const vop *cp_cfn = cfn;
}

and ran

gcc -Wall -Wno-unused-variable -c test.c

which yields the following warning:

warning: initialization makes '__attribute__((const))' qualified function pointer from unqualified [-Wdiscarded-qualifiers]

So it is "ok" to assign a "pointer to const vop" to a variable of type "pointer to vop" which, if it was not a function pointer would yield something like:

warning: initialization discards 'const' qualifier from pointer target type [-Wdiscarded-qualifiers]

But now it warns for the opposite case. So the question arises: What is the difference between const qualified function pointers and those that are not const qualified?


Note: The cppreference has the following paragraph:

If a function type is declared with the const type qualifier (through the use of typedef), the behavior is undefined.

Is the warning i saw a result of that "undefined behaviour" or does this paragraph not apply in this case (and if not, in what case can it be applied)?

2 Answers

What is the difference between const qualified function pointers and those that are not const qualified?

const has the usual meaning - one can be modified, the const one may not. Example:

void something();
void something_else();
int main() {
    void (*normal_pointer)() = something;
    normal_pointer = something_else; // all fine

    void (*const const_qualified_pointer)() = something;
    const_qualified_pointer = something_else; // error

    // for fun, let's aad typedef examples
    // similar with a typedef, if you want to
    typedef void functype();
    functype *pnt = something;
    pnt = something_else; // all fine

    functype *const cpnt = something;
    cpnt = something_else; // error

    // note that if typedef is already a pointer... then it's already a pointer
    typedef void (*functypepnt)();
    functypepnt pnt2 = something;
    pnt2 = something_else; // all fine

    const functypepnt cpnt2 = something;
    cpnt2 = something_else; // error
}

Is the warning i saw a result of that "undefined behaviour" or does this paragraph not apply in this case (and if not, in what case can it be applied)?

Yes. vop is a function type. const vop is undefined behavior. gcc issues a warning and ignores the qualifier.

You may want to const-qualify the pointer itself instead, not the pointed-to-type:

vop *const cp_cfn = fn;

A function type cannot have any type qualifier on it, including const. Doing so it undefined behavior.

From section 6.7.3p9 of the C standard:

If the specification of an array type includes any type qualifiers, the element type is so-qualified, not the array type. If the specification of a function type includes any type qualifiers, the behavior is undefined.

This declares a const function type:

const vop cfn;

And this declares a pointer to a const function type:

const vop *cp_fn;

Both of which violate 6.7.3p9.

Related