Pregunta

Pointers can be declared as pointing to mutable (non-const) data or pointer to constant data.
Pointers can be defined to point to a function.

My coworkers and I were discussing the use of "const" with pointers and the question came up regarding the use of const with function pointers.

Here are some questions:

  1. What is the meaning of a pointer to a constant function versus a pointer to a non-constant function?
  2. Can a function be const?
  3. Can a function be non-const (mutable)?
  4. What is the proper (safe) syntax for passing a function pointer?

Edit 1: Function pointer syntax

typedef void (*Function_Pointer)(void); // Pointer to void function returning void.

void function_a(Function_Pointer p_func); // Example 1.
void function_b(const Function_Pointer p_func); // Example 2.
void function_c(Function_Pointer const p_func); // Example 3.
void function_d(const Function_Pointer const p_func); // Example 4.

The above declarations are examples of treating a function pointer like a pointer to an intrinsic type.

A data, variable or memory pointer allows for the above combinations.
So the questions are: can a function pointer have the same combinations and what is meant by a pointer to a const function (such as Example 2)?

¿Fue útil?

Solución

In C, there's no such thing as a function being const or otherwise, so a pointer to a const function is meaningless (shouldn't compile, though I haven't checked with any particular compiler).

Note that although it's different, you can have a const pointer to a function, a pointer to function returning const, etc. Essentially everything but the function itself can be const. Consider a few examples:

// normal pointer to function
int (*func)(int);

// pointer to const function -- not allowed
int (const *func)(int);

// const pointer to function. Allowed, must be initialized.          
int (*const func)(int) = some_func;

// Bonus: pointer to function returning pointer to const
void const *(*func)(int);

// triple bonus: const pointer to function returning pointer to const.
void const *(*const func)(int) = func.

As far as passing a pointer to a function as a parameter goes, it's pretty simple. You normally want to just pass a pointer to the correct type. However, a pointer to any type of function can be converted to a pointer to some other type of function, then back to its original type, and retain the original value.

Otros consejos

According to the C spec (C99, section 6.7.3):

The properties associated with qualified types are meaningful only for expressions that are lvalues.

When the spec says "qualified types", it means things defined with the const, restrict, orvolatile keyword. Snice functions are not lvalues, the const keyword on a function isn't meaningful. You may be looking at some sort of compiler-specific extension. Some compilers will throw an error if you try to declare a function as const.

Are you sure that you're looking at a pointer to a constant function and not a constant pointer to a function (that is, it's the pointer that's const, not the function)?

Regarding #4: see this guide for a helpful overview of creating, passing, and using function pointers.

Under C, there is no such thing as a const function. const is a type-qualifier, and so can only be used to qualify a type, not a function. Maybe you mean a const pointer to a function or a non-const pointer to a function?

In C++, methods can be const. If a method is const, it means that after you call that method, the object containing the method will be in the same state as before you called the method (none of the instance variables[1] have been modified). Thus, you can point to a const method and a non-const method, and those methods are different.

You can accept a function pointer in an argument list as retType (*variableName)(arguments).

[1] Unless they are mutable.

In C, functions can be const if you are in the world of GCC! Functions can be declared const through the use of attributes attached to declarations of functions and other symbols. It is basically used to provide information to the compiler on what the function does, even though its body is not available so that the compiler can do some kind of optimizations with it.

A constant function is generally defined in terms of a pure function.

A pure function is a function with basically no side effect. This means that pure functions return a value that is calculated based on given parameters and global memory, but cannot affect the value of any other global variable. Pure functions cannot reasonably lack a return type (i.e. have a void return type).

And now we can define what is a const function,

A pure function that does not access global memory, but only its parameters, is called a constant function. This is because the function, being unrelated to the state of global memory, will always return the same value when given the same parameters. The return value is thus derived directly and exclusively from the values of the parameters given.

Here const doesn't imply anything about function mutability. But it is a function which doesn't touch global memory. You can assign normal pointers to such functions. Anyways the code region will generally ( forgetting self modifying code for a while ) be RO and you cannot modify it through the normal pointer.

Read the full insightful article here.

So when it comes to GCC Constant functions we are talking about optimizations and not function mutability.

1.What is the meaning of a pointer to a constant function versus a pointer to a non-constant function?

There is no difference between const and non-const: the function itself is not modifiable

Note: In C++ if the function is a member function of a class, const means that the state of the object within this function cannot be changed (member variables assigned to, non-const memeber functions called). In this case the const keyword is part of the member function's signature and therefore makes a difference in terms of the pointer.

2.Can a function be const?

See above.

3.Can a function be non-const (mutable)?

See above

4.What is the proper (safe) syntax for passing a function pointer?

All pointers to free functions can be cast to any other pointer to free function (i.e. their size is the same). So you could define a type for a (hypothetical) function: void f(); and convert all function pointers to this type to store. Note that you should not call the function via this common type: you need to cast it bact to its original pointer-to-function type, otherwise you get undefined behavior (and most likely crash)

For C++: pointers to member functions are not guaranteed to be convertible to pointers to free functions

1. There is syntactically nowhere to place 'const' to make a function's contents constant.

You will run into 'function is not an l-value' error regardless if you have const or not.

typedef void (* FUNC)(void);
FUNC pFunc;
pFunc = 0;     // OK
*pFunc = 0;    // error:  Cannot assign to a function (a function is not an l-value)

typedef void (* const FUNC)(void);
FUNC pFunc;
pFunc = 0;     // error  (const)
*pFunc = 0;    // error:  Cannot assign to a function (a function is not an l-value)

typedef void (const * FUNC)(void);   // error:  <cv-qualifier>  (lol?)

2 & 3. Function pointers- yes.. Function contents, doesn't look like.

4. I don't think there is any way to make passing a function pointer safer. With all the consts in the world, the only thing you can protect is that 'SetCallback' can't change it's own local copy of the parameter.

typedef void (* const FUNC)(void);
void SetCallback(const FUNC const pCallback)
{
  FUNC pTemp = pCallback;   // OK  (even though pTemp is not const!!)
  pCallback = 0;            // error  (const)
}
Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top