用重复数据初始化aN数组

时间:2009-05-10 08:30:02

标签: c arrays linker memory-management

我想初始化一个结构数组,重复使用相同的元素,即

struct st ar[] = { {1,2}, {1,2}, {1,2} };

但是我不想为此运行任何代码,我希望在程序执行时内存的布局是这样的,不需要任何CPU指令(这将增加非常慢的CPU和相对较大的数组的启动时间)。

当使用数组作为迷你ad-hoc数据库(将id映射到struct)以及希望对所有数据库值使用默认值时,这是有道理的。

我最好的解决方案是使用

形式的东西
#define I {1,2}
struct st ar[SIZE_OF_ARRAY] = { I,I,I };

如果I太多或太少,编译器会警告我。但这远非理想。

我认为在ANSI-C中没有解决方案,但我认为可能有宏观滥用或gcc扩展可以完成这项工作。理想情况下,我想要一个标准的解决方案,但即使是编译器特定的解决方案就足够了。

我以为我会以某种方式递归地定义一个宏,以便I(27)被解析为27 {1,2} s,但我不认为这是可能的。但也许我错了,是否有任何黑客攻击?

也许inline assemby可以解决这个问题?使用MASM或TASM定义这样的内存布局非常容易,但我不确定是否可以在C代码中嵌入内存布局指令。

是否有任何链接技巧会引诱它根据我的命令初始化内存?

PS 我知道我可以使用一些脚本自动生成C文件。不希望使用自定义脚本。如果我使用自定义脚本,我将发明一个C-macro REP(count,exp,sep)并编写一个mini-C-preprocessor来替换为exp sep exp sep ... exp {exp appears count time}

5 个答案:

答案 0 :(得分:10)

boost preprocessor library(对C来说很好)可以提供帮助。

#include <boost/preprocessor/repetition/enum.hpp>

#define VALUE(z, n, text) {1,2}

struct st ar[] = {
    BOOST_PP_ENUM(27, VALUE, _)
};

#undef VALUE

如果你想使用它,你只需要来自boost的boost/preprocessor目录 - 它完全是自包含的。

虽然,它确实对元素数量有一些任意限制(我认为在这种情况下它重复256次)。有一个名为chaos的替代方法没有,但它是实验性的,只适用于精确遵循标准的预处理器(GCC的)。

答案 1 :(得分:5)

我能想到的最简单的方法是编写一个脚本来生成可以包含在C代码中的初始化程序:

{1,2},
{1,2},
{1,2}

然后在你的来源:

struct st ar[] = {
    #include "init.inc"
};

如果您愿意,可以安排Makefile自动生成此内容。

答案 2 :(得分:2)

我猜你可以在带有数组定义的文件中执行:

#include "rep_array_autogen.c"
struct st ar[SIZE_OF_ARRAY] = REPARRAY_DATA;

让Makefile生成rep_array_autogen.c格式为

#define SIZE_OF_ARRAY 3
#define REPARRAY_DATA {{1, 2}, {1, 2}, {1, 2}, }

由于rep_array_autogen.c是在您的计算机上构建的,因此它就像在那里手动编码一样快。

答案 3 :(得分:0)

I s形式的内容是标准C可以为您提供的最佳选择。我不明白你怎么能厌恶标准的初始化代码,但是对于汇编来说没问题。嵌入式组件必然是非标准的非便携式机制。

递归宏的问题在于你不知道在哪里停止。

答案 4 :(得分:0)

埃拉扎尔,

你能提供数据来支持你的观点,即预先初始化的数据比运行时初始化更快吗?

如果您在带有硬盘驱动器(HDD)的标准机器上运行代码并且您的程序驻留在HDD上,那么将数据从二进制映像的数据部分复制到RAM的时间基本上是相同的时间使用某种类型的运行时初始化。

Kip Leitner