且构网

分享程序员开发的那些事...
且构网 - 分享程序员编程开发的那些事

C struct 初始化 编译时初始化的数组元素数

更新时间:2022-05-09 22:01:38

一个不可移植的技巧是使用 __COUNTER__ 预处理器扩展.这不是标准的 C 特性,但应该在最近的 gcc、clang 和 msvc 编译器中得到支持.

A not portable hack would be to use the __COUNTER__ preprocessor extension. It's not a standard C feature, but should be supported in recent gcc, clang and msvc compilers.

预处理器在每次求值后递增计数器的值,因此您必须使用以下内容强制求值:

The preprocessor increments the value of the counter after each evaluation, so you have to force evaluation using something like:

// in case __COUNTER__ was previously used in a different header
const static int initial_counter = __COUNTER__; 

#ifdef ITEM1 
  const static int item1_defined = __COUNTER__; // +1
#endif
#ifdef ITEM2
  const static int item2_defined = __COUNTER__; // +1
#endif
#ifdef ITEM3
  const static int item3_defined = __COUNTER__; // +1
#endif

// must subtract 1 because this line also evaluates __COUNTER__
const static int total_item_count = (__COUNTER__) - initial_counter - 1;

然后:

items_list_t item_list = 
{
    .items = { ... },
    .num_items = total_item_count
}

更便携的预处理器替代方法是使用 Boost 应该更便携(但它是为 C++ 编写的,所以你可能需要自己将一些细节移植到 C),或者使用代码生成器(推荐).

A more portable preprocessor alternative is to use Boost which should be more portable (but it's written for C++ so you might have to port some of the details to C yourself), or use a code generator (recommended).

在您的构建脚本中使用代码生成器将生成实际的源代码,您可以在需要时介入和调试.预处理器黑客很容易失控.

Involving a code generator into your build scripts will generate actual source code you can step in and debug if needed. Preprocessor hacks can easily get out of hand.