c - 请批评 C 中的错误报告方法

标签 c idioms

今天在工作中处理相对简单的 C 代码时,我开始做白日梦并编写了以下库以有效地生成错误消息。陪审团仍然不在 - 至少在我看来 - 这是否是一种比简单地将 perrorerrno 适应你的目的更有效的方法......它不是甚至需要成为一个“库”,而不仅仅是一组宏。

现在,我调用库elib:

elib.h

#ifndef _ELIB_H_
#define _ELIB_H_

struct ErrorMap {
    void (*fp);
    int errorCode;
    char * message;
};

#define eperror(...) fprintf(stderr,  ##__VA_ARGS__)
char * getErrorMsg(struct ErrorMap *, void (*fp), int);

#endif /* _ELIB_H_ */

elib.c

#include <stdlib.h>
#include "elib.h"

char * getErrorMsg(struct ErrorMap * errorMap, void (*fp), int code)
{
    int i;
    // TODO: Replace naive search
    for (i=0; errorMap[i].fp != NULL; i++)
    {
        if (errorMap[i].fp == fp && errorMap[i].errorCode == code)
        {
            return errorMap[i].message;
        }
    }
    return NULL;
}

test.c(示例应用“xyzlib”)

#include <stdio.h>
#include <string.h>

#include "elib.h"

int xyzlib_openFile(int);
int xyzlib_putStuff(char *);

static struct ErrorMap xyzlib_ErrorMap [] = {
    {xyzlib_openFile, -1, "Argument is less than 3"},
    {xyzlib_putStuff, -1, "Argument is NULL"},
    {xyzlib_putStuff, -2, "Length of argument is 0"},
    {xyzlib_putStuff, -3, "Stuff is too long"},
    {NULL, 0, NULL}
};


int xyzlib_openFile(int fd)
{
    if (fd > 3)
    {
        return (-1);
    }

    // open a file.. or something.

    return 0;
}

int xyzlib_putStuff(char * stuff)
{
    if (stuff == NULL)
    {
        return (-1);
    }

    if (strlen(stuff) == 0)
    {
        return (-2);
    }

    if (strlen(stuff) > 3)
    {
        return (-3);
    }

    // do something ...

    return (0);
}


int main(int argc, char ** argv)
{
    int code;

    if (argc != 2)
    {
        printf("Usage: %s <arg>\n", argv[0]);
        return 1;
    }

    code = xyzlib_putStuff(argv[1]);

    if (code < 0)
    {
        eperror("Error: %s\n", getErrorMsg(xyzlib_ErrorMap, xyzlib_openFile, code));    
    }
}

基本上,您在 ErrorMap 表中定义/注册返回代码,如果您收到错误指示(响应值 < 0),则 getErrorMsg 将查看已注册的表相应的代码和函数来获取正确的消息。我认为其值(value)在于,对于采用这种错误报告方法的给定库,可以为每个函数定义错误代码(而不是全局定义)——简化所有代码的管理。

但是,除了查找适当消息的小开销外,所有采用这种方法的 C 代码都需要每个函数(不返回非负整数)返回 int,然后使用第一个参数作为指向返回值的指针——有点不合惯用但很常用。

假设目标市场是用于高可靠性嵌入式设备的软件(但不是非常受资源限制)。

有什么想法吗?提前致谢。

最佳答案

抱歉,我真的看不出这有什么意义。也许那是因为我在 C 中处理错误代码的方式。基本上我将错误值定义为单个模块接口(interface)的一部分。模块之间的错误确实会发生冲突,即我不在乎两个模块的不同错误代码是否具有相同的数值。为了对不同的枚举进行强类型检查,我通常将它们包装到一个结构中。但我从不真正关心为每个函数制作唯一的错误代码,这似乎是您的方法。

同样,这是我的具体情况,但我从来没有真正觉得有必要做其他事情。为整个模块定义的错误代码通常适合在实现该模块的过程之间传递。现在,如果您的方法实际上可以映射到模块边界而不是函数怎么办? :)

关于c - 请批评 C 中的错误报告方法,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/10592010/

相关文章:

git - 如何将 git 分支声明为 merge 而不采用其中的更改?

c++ - 使用指针时的注意事项?

c - 我试图使用一个函数将文本文件的每 3 个字符放入一个数组指针中。

awk - awk 中的小窍门

java - 为什么 Execute Aroud 习语不被视为策略设计模式?

C Variadic Macro 简化对 fprintf 的调用

c - PBC element_to_bytes错误 "prints garbage"无法将元素转换为字符串

c - fprintf 在将其发送到文件时给出意外的输出

c - 结构声明

javascript - `new Error()` 什么时候比 `Error()` 好?