今日、職場で比較的単純な C コードに取り組んでいるときに、少し空想にふけるようになり、エラー メッセージを効果的に生成する次のライブラリを作成しました。perror陪審員はまだ出ていません-少なくとも私の心では-これが単に目的に適応するよりも効果的なアプローチであるかどうかerrno...それは「ライブラリ」である必要さえまったくなく、むしろ単なるセットですマクロ。
今のところ、私はライブラリを呼び出しています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は登録されたテーブルを調べて対応するコードと関数を探し、適切なメッセージを取得します。エラー報告にこのアプローチを採用している特定のライブラリの場合、(グローバルではなく) 関数ごとにエラー コードを定義できるため、すべてのコードの管理が簡素化されます。
ただし、適切なメッセージを検索するための小さなオーバーヘッドに加えて、このアプローチを採用するすべての C コードでは、すべての関数 (非負の整数を返さない) がints を返し、最初の引数をへのポインターとして使用する必要があります。戻り値 -- 少し慣用的ではありませんが、一般的に使用されます。
ターゲット市場が信頼性の高い組み込みデバイス用のソフトウェアであるとしましょう (ただし、リソースの制約はそれほど大きくありません)。
何かご意見は?前もって感謝します。