声明一系列常量

T. *_*sol 10 c arrays const

我有这可能是一个声明问题:

我声明了一个const int数组:

const int my_array[] = {
    // data...
}
Run Code Online (Sandbox Code Playgroud)

然后我需要声明窗体的另一个字节数组:

00 aa 01 bb 02 cc
Run Code Online (Sandbox Code Playgroud)

其中aabbcc是const int内存中的24位地址(我精确地为一个非常特殊的平台编写代码,这解释了这一点),所以我写道:

const char my_other_array[] = {
    00, (my_array >> 16) & 0xFF, 01, (my_array >> 8) & 0xFF, 02, my_array & 0xFF
}
Run Code Online (Sandbox Code Playgroud)

但我得到这个错误:

error: invalid operands to binary >>
error: initializer element is not constant
Run Code Online (Sandbox Code Playgroud)

我考虑过铸造my_array:

const char my_other_array[] = {
    00, (((const u32) my_array) >> 16) & 0xFF, 01, (((const u32) my_array) >> 8) & 0xFF, 02, ((const u32) my_array) & 0xFF
}
Run Code Online (Sandbox Code Playgroud)

但后来我收到警告+错误:

warning: initializer element is not computable at load time
error: initializer element is not computable at load time
Run Code Online (Sandbox Code Playgroud)

我究竟做错了什么 ?

这是实际的代码,对于那些要求(我削减不相关的部分):

#include <genesis.h>
#include "snake.h"

const u32 snake_patterns[] = {
    0x00024666,
    // ... some 100ths of lines
};

const u16 temp[] = {
    1, 0x9370, 0x9400, ((const u32) snake_patterns) & 0xFF, (((const u32) snake_patterns) >> 8) & 0xFF, (((const u32) snake_patterns) >> 16) & 0xFF
};
Run Code Online (Sandbox Code Playgroud)

您会注意到事情有点复杂,但我认为之前的基本示例(使用适当的括号修复)以更清晰的方式显示问题.有些人可能会识别Genesis VDP的DMA调用列表.

Nat*_*dge 7

用于初始化数组的元素需要是常量表达式.这些在C99标准的 6.6节或C11中的相同位置中定义.见第7段:

初始化器中的常量表达式允许更大的纬度.这样的常量表达式应为或评估为以下之一:

  • 算术常量表达式,
  • 空指针常量,
  • 地址常数,或
  • 对象类型的地址常量加上或减去整数常量表达式.

现在my_array是一个地址常量,但你可以做的就是加或减一个整数常量.通过移位或屏蔽,您创建的内容不再是常量表达式,因此在初始化程序中是不允许的.

我想这个限制的基本原理是C可用于可重定位代码,其中程序在内存中的位置在加载以准备执行之前可能是不可知的.在这样的系统上,程序中的地址引用必须由加载程序填写,基于它在加载时读取的二进制文件中的表(例如"在程序中的相对地址0x12345678,填写绝对地址my_array一旦知道")的对象.该表通常具有相当严格的格式,并且可能有一种表达常量偏移的方法("填充对象的绝对地址my_array,加上42"),但通常不支持任意算术.

也许你最简单的办法就是让my_other_arrayconst和在运行时填充它,通过编写提取的地址的必要位的功能my_array,并将它们插入my_other_array,并需要使用之前调用这个函数my_other_array.

如果由于某些原因my_other_array在加载程序时已经填写,并且您的目标平台是您知道程序将在内存中的位置,那么您可能能够使用汇编程序或链接程序的设施实现你想要的.但当然这将是系统特定的.

(编辑:你在另一个评论中已经提到过这个阵列需要进入ROM.如果是这样,那么我认为我的最后一个建议是你唯一的希望.你可能想发布另一个问题,关于如何/是否可以用你正在使用的特殊工具链.)


Eri*_*ist 6

"我究竟做错了什么?"

我看到的最直接的事情是....

这不是一个数组:

const int my_array = { /* elements */ }
Run Code Online (Sandbox Code Playgroud)

这是一个数组:

const int my_array[N] = { /* N elements */ };
Run Code Online (Sandbox Code Playgroud)

此外,不要忽略该错误消息!它讲真话!

error: initializer element is not constant
Run Code Online (Sandbox Code Playgroud)

您正在使用不是常量的东西,即"my_array"来初始化数组元素."my_array"将计算为指向数组第一个元素的指针,并且在编译时不知道该值.