【问题标题】:How do I return an error code in C when the return type of the function doesn't allow me to do that?当函数的返回类型不允许我这样做时,如何在 C 中返回错误代码?
【发布时间】:2020-12-07 23:09:53
【问题描述】:

我知道标题不是自我解释的,但我无法用几句话来表达。 无论如何,问题是我有一个 C 函数,它返回一个由 3 个整数组成的结构。这是它的定义。

typedef struct {
  uint8_t r;
  uint8_t g;
  uint8_t b;
} Color;

这里是函数

Color PPMImage_getPixel(PPMImage *ppmImage, uint32_t x, uint32_t y) {
  // FIXME: Check if (x, y) is in bounds.

  return ppmImage->data[y * ppmImage->width + x];
}

现在,当特定条件失败时,我想返回一个错误值,告诉调用者该函数遇到错误,但我不能,因为返回值是一个具有 3 个无符号整数的结构,而我不能,因为例如,将每个字段设置为 -1 或返回 NULL 因为我没有返回指针。有没有一种优雅而有效的方法来做到这一点?

【问题讨论】:

    标签: c function error-handling return


    【解决方案1】:

    将返回值的类型改为函数的错误码,并传递一个要返回的struct color的指针

    即:

    int PPMImage_getPixel(PPMImage *ppmImage, uint32_t x, uint32_t y, Color * color)
    {
     // FIXME: Check if (x, y) is in bounds.
     // TODO: validate color isn't null and valid, otherwise return -1
    
     (*color) = ppmImage->data[y * ppmImage->width + x];
      return 0;
    }
    

    【讨论】:

      【解决方案2】:

      我宁愿有一个指向缓冲区的指针作为函数的输入参数并返回一个int

      int PPMImage_getPixel(Color* p_color, PPMImage *ppmImage, 
                            uint32_t x, uint32_t y) 
      {
          if (some error)
          {
              return 0;
          }
          
          // Copy the struct into buffer
          memcpy(p_color, &ppmImage->data[y * ppmImage->width + x], sizeof (Color));
      
          return 1;
      }
      

      假设一些你没有定义的结构,但你可以改变它。创建这个是为了有一些可以编译的东西。

      typedef struct PPMImage
      {
          uint8_t width;
          Color data[10];
      } PPMImage;
      

      main() 中创建缓冲区并将该缓冲区的地址作为输入。

      int main(void)
      {   
          PPMImage image;
      
          Color color_buf;
          uint32_t x = 5, y = 3;
      
          if (!PPMImage_getPixel(&color_buf, &image, x, y))
          {
              printf("ERROR PPMImage_getPixel()\n");
              exit(0);
          }
      
          printf("PPMImage_getPixel() returned no error.\n");
      
          return 0;
      }
      

      【讨论】:

        【解决方案3】:

        一种方法是将结果分配给输出参数并返回错误代码,如下所示:

        int PPMImage_getPixel(PPMImage *ppmImage, uint32_t x, uint32_t y, Color *result);
        

        但是,由于我是命令-查询分离的粉丝,我也会将错误代码分配给输出参数:

        void PPMImage_getPixel(PPMImage *ppmImage, uint32_t x, uint32_t y, Color *result, int *error);
        

        另一种方法是如果 x 或 y 太大,则通过返回最近的像素来定义错误不存在:

        Color PPMImage_getPixel(PPMImage *ppmImage, uint32_t x, uint32_t)
        {
            if (x < 0) {
                x = 0;
            } else if (x > xMax) {
                x = xMax;
            }
            if (y < 0) {
                y = 0;
            } else if (y > yMax) {
                y = yMax;
            }
            ...
        }
        

        【讨论】:

          猜你喜欢
          • 2021-12-15
          • 2015-06-17
          • 1970-01-01
          • 1970-01-01
          • 2013-04-17
          • 2021-07-16
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多