我有这可能是一个声明问题:
我声明了一个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调用列表.
用于初始化数组的元素需要是常量表达式.这些在C99标准的 6.6节或C11中的相同位置中定义.见第7段:
初始化器中的常量表达式允许更大的纬度.这样的常量表达式应为或评估为以下之一:
- 算术常量表达式,
- 空指针常量,
- 地址常数,或
- 对象类型的地址常量加上或减去整数常量表达式.
现在my_array是一个地址常量,但你可以做的就是加或减一个整数常量.通过移位或屏蔽,您创建的内容不再是常量表达式,因此在初始化程序中是不允许的.
我想这个限制的基本原理是C可用于可重定位代码,其中程序在内存中的位置在加载以准备执行之前可能是不可知的.在这样的系统上,程序中的地址引用必须由加载程序填写,基于它在加载时读取的二进制文件中的表(例如"在程序中的相对地址0x12345678,填写绝对地址my_array一旦知道")的对象.该表通常具有相当严格的格式,并且可能有一种表达常量偏移的方法("填充对象的绝对地址my_array,加上42"),但通常不支持任意算术.
也许你最简单的办法就是让my_other_array不const和在运行时填充它,通过编写提取的地址的必要位的功能my_array,并将它们插入my_other_array,并需要使用之前调用这个函数my_other_array.
如果由于某些原因my_other_array在加载程序时已经填写,并且您的目标平台是您知道程序将在内存中的位置,那么您可能能够使用汇编程序或链接程序的设施实现你想要的.但当然这将是系统特定的.
(编辑:你在另一个评论中已经提到过这个阵列需要进入ROM.如果是这样,那么我认为我的最后一个建议是你唯一的希望.你可能想发布另一个问题,关于如何/是否可以用你正在使用的特殊工具链.)
"我究竟做错了什么?"
我看到的最直接的事情是....
这不是一个数组:
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"将计算为指向数组第一个元素的指针,并且在编译时不知道该值.