首页 > 解决方案 > Warning 'return' with no value, in function returning non-void - What should it return?

问题描述

How do I solve the following throwing the warning in the title?

struct Nodes* InsertNode(unsigned int IP, unsigned short Port)
{
    if (!IP)
       return;
    if (!Port)
       return;
    // Above is what chucks the warnings
    {
        // do stuff & conditionally
           return &List[x];
    }
    // Different conditions & stuff
    {
       return &List[Other];
    }
}

In other words, in the case of giving up through missing data, what should it return? Or do I need to trawl through the entire body of code and have checks every time to see if it should be called or not? The program functions as intended just returning at that point, if I'm to continue using it (or upgrade the OS it's running on), fixing compiler warnings seems like a good idea, they tend to turn into errors when compiler versions get bumped.

There's a clue in this answer which answers someone asking about the same warning, the answer doesn't give me quite enough info to proceed though, nor do the other's I've read.

Extra information: The check on the values of IP & Port are there to sanitize the content of &List, such cases indicate datagrams from misconfigured clients or traffic from persons with malicious intent, sad but it happens. It's invalid data we don't care about at all, logging it seems pointless, it shouldn't delay processing the next one, and absolutely not halt the program. Until the switch from gcc 4.9 to 6.3 I didn't see a warning. The current return; appears to simply black-hole it, but I only understand bits of the code's intent.

标签: cerror-handlingcompiler-warningsgcc-warning

解决方案


在通过丢失数据放弃的情况下,它应该返回什么?

通常取决于。

有几种情况

  1. 该函数并非旨在NULL作为有效值返回。

    代替

    if (!IP)
      return;
    if (!Port)
      return;
    

    经过

    if (!IP || !Port)
    {
      errno = EINVAL; /* Setting errno, allows the caller to log 
                         the failure using the perror() function. */
      return NULL;
    }
    

    像这样使用它:

    struct Nodes * p = InsertNode (...);
    if (NULL == p)
    {
       perror("InsertNode() failed");
       /* exit or error logging/handling */
    }
    
  2. IP并且Port永远不会处于0正常运行状态。因此,如果它们是,那将是一个编程错误。

    在这些情况下,您可能不会不返回而是结束程序。

    所以而不是

    if (!IP)
      return;
    if (!Port)
      return;
    

    利用

    assert((IP) && (Port));
    

    这里不需要特定的用法,因为如果不满足断言,程序将简单地结束。

    注意,这种方法需要大量测试,因为测试通常会在生产/发布版本中删除!

  3. 该函数可能NULL作为有效值返回 IP/或Port 可能处于0正常运行状态。

    重新设计函数以以一种或另一种方式返回单独的错误状态。

    这通常可以通过两种方式完成:

    • 使用函数的返回值并通过作为参数传递的指针传回结果

      int InsertNode(unsigned int IP, unsigned short Port, struct Nodes** ppresult)
      {
        int error_state = 0;
      
        if (!IP || !Port || !ppresult)
        {
          errno = EINVAL; /* Setting errno, allows the caller to log 
                         the failure using the perror() function. */
          error_state = -1;
        }
        else
        {
          if (...)
          {
            *ppresult = &List[x];
          }
      
          ...
      
        }
      
        return error_state;
      }
      

      像这样使用它:

      struct Nodes * p;
      if (-1 == InsertNode (..., &p))
      {
         perror("InsertNode() failed");
        /* exit or error logging/handling */
      }
      
    • 通过作为参数传递的指针传回错误状态结果

      struct Nodes * InsertNode(unsigned int IP, unsigned short Port, int * perror_state)
      {
        int error_state = 0;
      
        if (!IP || !Port || !perror_state)
        {
          errno = EINVAL; /* Setting errno, allows the caller to log 
                         the failure using the perror() function. */
          error_state = -1;
        }
        else
        {
          if (...)
          {
            *ppresult = &List[x];
          }
      
          ...
      
        }
      
        *perror_state = error_state;
      
        return NULL;
      }
      

      像这样使用它:

      int result;
      struct Nodes * p = InsertNode (..., &result))
      if (-1 == result)
      {
        perror("InsertNode() failed");
        /* exit or error logging/handling */
      }
      

推荐阅读