簡體   English   中英

c 中的常量數組 - 檢查是否在編譯期間定義了所有元素

[英]constant array in c - check if all elements are defined during compile time

我正在 C 中尋找一種方法,以在編譯時檢查是否設置了常量數組的所有元素。 背景是,我想要一個帶有命名行的查找表,它必須是完整的。

例子:

typedef enum [foo, bar, bla, max_value} rowNames;

static const uint32 LookupTable[max_value] =
{
    [foo] = 123,
    [bla] = 456, // oops, someone forgot to define the value for [bar]
}

retval = LookupTable[bar]; //this is to read out the value of the lookup table at a certain position

在此示例中,有人忘記定義數組元素 #1 [bar] 的值。 我想確保在編譯期間定義了所有值,並且錯誤會破壞構建。

當然,實際上表格會更大更復雜,但我認為這足以了解情況。 特別是如果枚舉稍后將被編輯,很可能枚舉和表定義可能會不一致。

問候,阿恩斯基

由於您希望它在編譯時發生,我認為您唯一的選擇是創建一個 static 代碼分析器來執行此檢查,並將其添加到您的工具鏈中,以便在每次構建時完成驗證。

在運行時,只要將表定義更改為

static const uint32 LookupTable[] =
{
    /*[foo] = */123,
    /*[bla] = */456
}

這樣,數組是自動調整大小的,並且可以使用 sizeof 來查看其中有多少條目,因此一旦有人更改了枚舉,他們至少會在下次運行時得到運行時錯誤

這可以很容易地完成,只需對您的代碼進行一些修改。

將數組更改為static const uint32 LookupTable[] ,使其大小取決於初始化的項目數。 然后在沒有指定初始化器的情況下初始化數組,只需:

static const uint32 LookupTable[] =
{
  123, // foo
  456, // bla
  ...
};

現在您的標准 C 編譯器可以使用編譯時斷言檢查數組的完整性:

_Static_assert(sizeof LookupTable / sizeof *LookupTable == max_value, 
               "LookupTable wrong number of items");

編輯:

為了嚴格控制數據,有一個“X 宏”技巧,它創建了非常丑陋的代碼,但將所有數據集中到源中的一個位置。 在下面的示例中,所有數據信息都存儲在宏ARRAY_LIST

#include <stdio.h>

#define ARRAY_LIST(X) \
  X(foo, 1)           \
  X(bar, 2)           \
  X(bla, 3)           \

typedef enum
{
  #define FOO_ENUM(name,val) name,
  ARRAY_LIST(FOO_ENUM)
  foo_n
} foo_t;

const int array[] =
{
  #define ARRAY_INIT(name,val) [name] = val,
  ARRAY_LIST(ARRAY_INIT)
};

_Static_assert(sizeof array / sizeof *array == foo_n, 
               "LookupTable wrong number of items");

int main (void)
{
  #define PRINT_ITEM(name,val) printf("%s: %d\n",#name, array[name]);
  ARRAY_LIST(PRINT_ITEM)
}

預處理器 output 然后給出:

typedef enum
{
  foo, bar, bla,
  foo_n
} foo_t;

const int array[] =
{
  [foo] = 1, [bar] = 2, [bla] = 3,
};

_Static_assert(sizeof array / sizeof *array == foo_n,
               "LookupTable wrong number of items");

int main (void)
{
  printf("%s: %d\n","foo", array[foo]); 
  printf("%s: %d\n","bar", array[bar]); 
  printf("%s: %d\n","bla", array[bla]);
}

並編程 output:

foo: 1
bar: 2
bla: 3

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM