函数指针在未被调用的情况下转换为 void
Function pointer cast as void without being called
在仔细阅读一些 STM32 中间件代码时,我遇到了这个非常奇怪的行并且无法解析它。基本上,
(void)(foo);
这不是空指针转换 - 这很简单。它不是调用函数并将其 return 值转换为 void - 这将需要更多的括号。它看起来像一个没有左值的右值。这只是一个空操作,以防止功能被优化掉吗?或者它真的有作用吗?
这是上下文。
// SVCCTL_EvtAckStatus_t is just an enum typedef
typedef SVCCTL_EvtAckStatus_t (*SVC_CTL_p_EvtHandler_t)(void *p_evt);
void SVCCTL_RegisterCltHandler( SVC_CTL_p_EvtHandler_t pfBLE_SVC_Client_Event_Handler )
{
#if (BLE_CFG_CLT_MAX_NBR_CB > 0)
// Ignore all this
SVCCTL_CltHandler.SVCCTL_CltHandlerTable[SVCCTL_CltHandler.NbreOfRegisteredHandler] = pfBLE_SVC_Client_Event_Handler;
SVCCTL_CltHandler.NbreOfRegisteredHandler++;
#else
// This is the weird stuff
(void)(pfBLE_SVC_Client_Event_Handler);
#endif
return;
}
它什么都不做,除了一件事。阻止编译器抱怨未使用的变量。它实际上被推荐在这里,在 SO 上,作为一种可移植的方式:Portable UNUSED parameter macro used on function signature for C and C++
示例:
int somefunction(int a, int b, int c)
{
(void)(c); // c is reserved for future usage,
//stop the compiler from issuing "unused parameter" warning
return a+b;
}
这是做什么的:
(void)(foo);
将表达式 foo
转换为类型 void
。这是一种表示表达式未被明确使用的方式。
如果您查看函数 SVCCTL_RegisterCltHandler
的定义,您会发现它有一个名为 pfBLE_SVC_Client_Event_Handler
的参数。此参数用于 #if
预处理器块。如果 #if
条件为假,则此参数将未被使用,编译器将发出警告,指出参数 pfBLE_SVC_Client_Event_Handler
未被使用。
通过将此参数转换为 #else
块中的 void
,它会使用该值并消除编译器警告。
这是为了防止编译器抱怨 foo 未被使用。就是这样。这就像 C++ 中的 maybe_unused
属性。
在仔细阅读一些 STM32 中间件代码时,我遇到了这个非常奇怪的行并且无法解析它。基本上,
(void)(foo);
这不是空指针转换 - 这很简单。它不是调用函数并将其 return 值转换为 void - 这将需要更多的括号。它看起来像一个没有左值的右值。这只是一个空操作,以防止功能被优化掉吗?或者它真的有作用吗?
这是上下文。
// SVCCTL_EvtAckStatus_t is just an enum typedef
typedef SVCCTL_EvtAckStatus_t (*SVC_CTL_p_EvtHandler_t)(void *p_evt);
void SVCCTL_RegisterCltHandler( SVC_CTL_p_EvtHandler_t pfBLE_SVC_Client_Event_Handler )
{
#if (BLE_CFG_CLT_MAX_NBR_CB > 0)
// Ignore all this
SVCCTL_CltHandler.SVCCTL_CltHandlerTable[SVCCTL_CltHandler.NbreOfRegisteredHandler] = pfBLE_SVC_Client_Event_Handler;
SVCCTL_CltHandler.NbreOfRegisteredHandler++;
#else
// This is the weird stuff
(void)(pfBLE_SVC_Client_Event_Handler);
#endif
return;
}
它什么都不做,除了一件事。阻止编译器抱怨未使用的变量。它实际上被推荐在这里,在 SO 上,作为一种可移植的方式:Portable UNUSED parameter macro used on function signature for C and C++
示例:
int somefunction(int a, int b, int c)
{
(void)(c); // c is reserved for future usage,
//stop the compiler from issuing "unused parameter" warning
return a+b;
}
这是做什么的:
(void)(foo);
将表达式 foo
转换为类型 void
。这是一种表示表达式未被明确使用的方式。
如果您查看函数 SVCCTL_RegisterCltHandler
的定义,您会发现它有一个名为 pfBLE_SVC_Client_Event_Handler
的参数。此参数用于 #if
预处理器块。如果 #if
条件为假,则此参数将未被使用,编译器将发出警告,指出参数 pfBLE_SVC_Client_Event_Handler
未被使用。
通过将此参数转换为 #else
块中的 void
,它会使用该值并消除编译器警告。
这是为了防止编译器抱怨 foo 未被使用。就是这样。这就像 C++ 中的 maybe_unused
属性。