迫使GCC放弃归零某些全局变量

时间:2012-06-24 20:14:50

标签: c gcc

有没有办法告诉GCC不要将特定的全局数组初始化为零?

我想保留一大块内存来存储我的代码管理的大型数据结构,所以我说:

#define SIZE_16_MB 0x01000000
BYTE mChunkSpace[SIZE_16_MB];

问题在于crtinit()需要一百万年才能将此空间初始化为零,并且根本不需要。

有什么方法可以强迫它不要初始化那个空间?

目前我正在硬编码一个超出链接器知道的内存地址,但这并不是一种特别强大的做事方式。

此外,这是一个缓慢的嵌入式proc(50MHz Microblaze),所以不要以为我在谈论PC。确实需要很长时间才能将该空间归零。

5 个答案:

答案 0 :(得分:6)

您可以使用gcc属性将对象存储在另一个新的内存部分中,例如.noinit内存部分。

 BYTE mChunkSpace[SIZE_16_MB] __attribute__ ((section (".noinit")));

答案 1 :(得分:4)

尝试动态初始化:

BYTE* mChunkSpace = (BYTE*)malloc(SIZE_16_MB * sizeof(BYTE));

然后这些数据未初始化并等待您初始化它。

答案 2 :(得分:2)

你将在SO上获得的大多数答案将倾向于Visual Studio或GCC,无论是在通用平台(即PC,无论是Windows还是Linux)上,都会对“标准说... “引用,除了恰好运行嵌入式Linux或Windows CE之外,其中任何一个都不适用于小型嵌入式系统。

ouah的回答可能是最接近你需要的......如果你真正使用GCC,也许你需要的确切。由于您想要的内存块太大,可能占用系统内存的大部分内容,因此最好的办法是在构建的链接器命令文件中定义一个特殊部分,或者在C,C ++或汇编文件中定义链接器指令。 。这样做的语法因编译器而异。如果在源/汇编文件中使用链接器指令,则可能需要指定关于内存区域的读/写能力等的属性...或者如果Microblaze没有MMU / Memory-controller则可能不需要。您需要在该部分的开头添加一个链接器符号,并在您的C代码中使用“extern char symName []”指令,这样您的C代码就可以在relocs中编译,链接器将使用实际的地址覆盖这部分。根据编译器和体系结构的不同,您可能还需要使用某种“far”属性声明symName [] extern;我不太了解Microblaze对此有何说法。

答案 3 :(得分:0)

我实际上认为非静态内存默认情况下不会初始化为零?

答案 4 :(得分:-2)

该标准规定,在声明点未明确初始化的静态数据将被零初始化。您可以通过自己将第一个元素初始化为非零值来避免运行时初始化:

#define SIZE_16_MB 0x01000000
BYTE mChunkSpace[SIZE_16_MB] = {1};

请注意,如果指定0,编译器可能只会将其存储在.bss部分中,即它仍将在运行时初始化。它不必这样做,但它不是愚蠢的。所以现在你的数组被抛入.data段。

当然,这会使得到的可执行文件更大(确切地说大约16MB),但内存不会在运行时初始化。所以问题归结为对你有什么影响;将内存归零所需的时间,或者生成的可执行文件大小?