指针可以声明为指向可变(非const)数据或指针常量数据。
指针可以被定义为指向的功能。
我的同事和我在讨论用指针和问题使用“常量”的想出了关于使用const
函数指针。
这里有一些问题:
- 什么是指向一个常数函数与指针的一个非恒定的功能是什么意思?
- 一个函数可以是const?
- 函数可以是非const的(可变的)?
- 什么是正确的(安全)语法传递一个函数指针?
编辑1:函数指针的语法
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.
上述声明是治疗一个函数指针等的指针的本征型的例子。
一种数据,变量或存储器指针允许上述的组合。
所以问题是:能函数指针具有相同的组合,什么是一个指针指到一个const函数(如例2)?
Answer 1:
在C语言中,有一个功能是没有这样的事情const
或以其他方式,所以指向一个const函数是没有意义的(不要编译,虽然我还没有与任何特定的编译器检查)。
需要注意的是,虽然它是不同的,你可以有一个const指针函数,指针函数返回常量等本质上的一切,但功能本身可以是常量。 考虑几个例子:
// 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.
至于指针传递给函数的参数去,这是很简单的。 通常你想的指针刚刚传递到正确的类型。 然而,指针的任何类型的功能可以被转换为一个指针到一些其他类型的功能,然后再返回到原来的类型,并保留原来的值。
Answer 2:
根据C时的参数( C99 ,部分6.7.3):
合格的类型相关的属性是有意义的,只是对于那些左值表达式。
当规范说“资格类型”,这意味着与定义的东西const
, restrict
或volatile
的关键字。 Snice函数不是左值的const
上的功能关键字是没有意义的。 您看到的可能是某种特定的编译器扩展。 如果您尝试声明函数,如一些编译器将抛出一个错误const
。
你确定你正在寻找一个指向一个恒定的功能,而不是一个常量指针的函数(即,它是那样的指针 const
,而不是功能)?
关于#4:见本指南 ,用于创建,传递和使用函数指针的有用的概述。
Answer 3:
在C,有没有这样的事,作为一个const
功能。 const
是一个类型限定符,因此只能用于限定一个类型,不是一个函数。 也许你的意思是一个const指针的函数或一个非const指针的函数?
在C ++中,方法可以是const
。 如果一个方法是const
,这意味着你调用该方法后,含该方法的对象将在相同的状态,然后调用的方法(所有的实例变量[1]的已被修改)。 因此,你可以指向一个const方法和一个非const方法,并且这些方法是不同的。
您可以在参数列表作为接受一个函数指针retType (*variableName)(arguments)
。
[1]除非它们是mutable
。
Answer 4:
在C语言中,函数可以是const
,如果你是在GCC的世界! 函数可以声明const
通过使用附连到的功能和其它符号声明属性。 它基本上是用来对功能做什么编译器提供的信息,尽管它的身体不适,这样编译器可以做一些与它的优化。
恒定函数在一个方面通常定义pure
函数。
纯函数是与基本上无副作用的功能。 这意味着纯函数返回一个基于给定的参数和全局存储器计算出的值,但不能影响任何其他全局变量的值。 纯函数不能合理缺少返回类型(即具有void返回类型)。
现在,我们可以定义什么是const函数,
不访问全局存储器纯函数,而只是它的参数,称为固定功能 。 这是因为该功能,是无关的全局存储器的状态,给予相同的参数时,将始终返回相同的值。 返回值因此从给定参数的值直接并且仅衍生。
这里const
并不意味着有关函数的可变性东西。 但它是不接触全局内存的功能。 您可以将正常的指针这样的功能。 反正代码区域将通常(忘记了一段程序自修改)是RO并且无法通过正常指针修改它。
阅读完整的见地的文章在这里。
因此,当涉及到GCC恒定功能 ,我们正在谈论的优化和不起作用的可变性。
Answer 5:
1.什么是一个指针的常数函数相对于指针的含义非恒定的功能?
有const和non-const的没有什么区别:函数本身是不可修改的
注意:在C ++中,如果函数是一个类的成员函数,常量表示该函数内的对象的状态不能被改变(转让给,称为非const memeber功能构件变量)。 在这种情况下const关键字是成员函数的签名的一部分,因此,使在指针方面的差异。
2.可函数是const?
往上看。
3.CAN函数是非const(可变)?
往上看
4.什么是传递一个函数指针的正确(安全)语法?
所有指针免费功能,可强制转换为任何其他指针免费功能(即它们的大小是一样的)。 所以,你可以定义一个类型为(假想)功能: void f();
和转换所有函数指针这种类型的存储。 请注意 ,你不应该从这个常见的类型调用函数:你需要BACT它转换到原来的指针到函数类型,否则,你得到了一个未定义的行为(最有可能崩溃)
对于C ++:指针成员函数,但不保证转换为指针自由函数
Answer 6:
1.在语法上是无处安放的“常量”,使函数的内容不变。
您将运行到不分“的功能是不是一个左值”的错误,如果你有const或没有。
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.功能pointers-是..功能的内容,看起来并不像。
4.我不认为有什么办法,使传递函数指针更安全。 随着世界上所有的consts,可以保护唯一的事情就是“SetCallback”不能更改参数的它自己的本地副本。
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)
}
文章来源: What is meaning of a pointer to a constant function?