2

While perusing some STM32 middleware code, I came across this very odd line and can't parse it. It's basically,

(void)(foo);

It's not a void pointer cast - that would be straightforward. It's not calling a function and casting its return value as void - that would require a couple more parentheses. It looks like an rvalue without an lvalue. Is this just a no-op to prevent the function from being optimized away? Or does it actually do anything?

Here it is in context.

// 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;
}

  • Do you have any reference of `SVC_CTL_p_EvtHandler_t`? It might help to solve this query. – Sourabh Choure Aug 06 '20 at 00:55
  • I think this has an answer here: https://stackoverflow.com/questions/34288844/. Although that question is for C++ I think the answers are applicable to C as well. – augurar Aug 06 '20 at 01:08
  • My guess is that (1) the line itself is there to suppress a warning about `pfBLE_SVC_Client_Event_Handler ` not being used, and (2) as @augurar suggests, the `(void)` is there to suppress some other warning. – Howlium Aug 06 '20 at 01:11

3 Answers3

5

It doesn't do anything, except one thing. Stopping the compiler from complaining about unused variables. It is actually being recommended here, on SO, as a portable way of doing it: Portable UNUSED parameter macro used on function signature for C and C++

Example:

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;
}
Boris Lipschitz
  • 1,514
  • 8
  • 12
3

What this does:

(void)(foo);

Is cast the expression foo to type void. It's a way of saying that an expression is explicitly not being used.

If you look at the definition of the function SVCCTL_RegisterCltHandler, you'll see that it takes a parameter named pfBLE_SVC_Client_Event_Handler. This parameter is used in the #if preprocessor block. If the #if condition is false, this parameter would otherwise be unused and the compiler would emit a warning that the parameter pfBLE_SVC_Client_Event_Handler is unused.

By casting this parameter to void in the #else block it uses the value and silences the compiler warning.

dbush
  • 205,898
  • 23
  • 218
  • 273
0

It's to prevent the compiler from complaining about foo being unused. That's literally it. It's like the maybe_unused attribute in C++.

BidoTeima
  • 490
  • 1
  • 4
  • 13