This page is a mirror of Tepples' nesdev forum mirror (URL TBD).
Last updated on Oct-18-2019 Download

cc65 acting weird again

cc65 acting weird again
by on (#169454)
Or maybe I'm doing something wrong.

It seems that the latest snapshot still creates some initialized variables in RAM, no matter if they are 100% constant. I've hit this in the past, with the old 2.13 version, and I believed it was already fixed, but in a project where most of my RAM is in use, this:

Code:
const unsigned char *map_2 [] = {
   0, 0, 0, 0, 0, 0
};


won't let me compile ( Segment `BSS' overflows memory area `RAM' by X bytes ). If I remove the line it compiles, so that implies the compiler is, for some reason, allocating such space in RAM.

Maybe I'm doing something wrong, is there a different syntax for a constant array of constant pointers? In other compilers such as SDCC, I have to write this:

Code:
const unsigned char * const unsigned char spr_enems [] = {


But cc65 doesn't like that and throws a syntax error.

Any pointers? Or have I hit another bug/unimplemented feature?
Re: cc65 acting weird again
by on (#169458)
na_th_an wrote:
const unsigned char *map_2 []
Did you mean to make an array of pointers?
cdecl wrote:
cdecl> explain const unsigned char *map_2 []
declare map_2 as array of pointer to const unsigned char
Re: cc65 acting weird again
by on (#169459)
The correct form is
Code:
const unsigned char * const foo[] = {
  0, 1, 2, 3
};

(From right to left: "foo is a (array of) const pointer to unsigned char that is const")

The SDCC example you gave is not valid C.
Re: cc65 acting weird again
by on (#169461)
Shouldn't pointers be 16-bit 'int' ?
Re: cc65 acting weird again
by on (#169462)
I know about the SDCC example, but that's what that compiler needs for such a task.

Thanks for the solution to my problem :) I will try ASAP.

Cheers!
Re: cc65 acting weird again
by on (#169463)
dougeff: The pointer takes 16 bits to hold it, yes, but it's a pointer to an 8-bit type.

q.v.:
Code:
static const unsigned char * map_2 [] = { 1, 2 };
static const unsigned char * const map_3 [] = { 3, 4 };
static const unsigned char map_4 [] = { 5, 6 };
generates
Code:
.segment   "DATA"
_map_2:
   .word   $0001
   .word   $0002
.segment   "RODATA"
_map_3:
   .word   $0003
   .word   $0004
_map_4:
   .byte   $05
   .byte   $06
Note that there's some type coercion ("Warning: Converting integer to pointer without a cast") going on here. If you tried to index into map_2 you'd get pointers out, not unsigned chars out.
Re: cc65 acting weird again
by on (#169470)
I use arrays of pointers quite a lot in my code to save lots of code and branching, and as direct indexes to mixed data. Now I understand that my syntax was plain wrong. I just read a bit ago that cc65 had problems with recognizing const arrays when they were defined inline and contained variables, no matter if they were const or not.

Thanks for the insight!
Re: cc65 acting weird again
by on (#169474)
There are a couple replies here that provide insight into the declaration differences, in case you want to understand fully: http://stackoverflow.com/questions/2276 ... nters-in-c
Re: cc65 acting weird again
by on (#169477)
Learning to correctly specify const on arrays and nested arrays can be a little bit tricky, especially because in PC contexts that execute from RAM anyway the distinction usually isn't critical (code will still run, you're just not getting a compile-time check against modifications). On the NES, though, it becomes critical, because unless it's exactly correct you won't get read-only data.

The music data from my Giant Steps ROM is an example:
Code:
// individual bars of notes
const uint8 saxU0[] = {Fs2, 22,D_2,  2,TIE, 22,B_1,  2,TIE, 22,G_1,  2,TIE, 19,As1,  5,BAR};
const uint8 saxU1[] = {TIE, 36,RES, 12,B_1, 19,A_1,  5,TIE, 19,RES,  5,BAR};
// etc ...
// 8 bar collections
const uint8* const saxU[] = { saxU0, saxU1, saxU2, saxU3, saxU4, saxU5, saxU6, saxU7, };
// the whole tune
const uint8* const * const sax[] = { saxA, saxB, saxC, saxD, saxE, saxF, saxG, saxH, saxI, saxJ, saxK, saxL, saxM, saxN, saxO, saxP, saxQ, saxR, saxS, saxT, saxU, };

I think it takes a little bit of practice to really get the hang of how to specify constness on multi-level arrays.
Re: cc65 acting weird again
by on (#169482)
na_th_an wrote:
I know about the SDCC example, but that's what that compiler needs for such a task.

You might want to try the way I posted in SDCC, it sounds like it might be a bug in that it accepts the type specifier (unsigned char) twice.
Re: cc65 acting weird again
by on (#169485)
@koitsu - Good resource. Thank you.

@thefox - I will try, thank you.

@rainwarrior - I had to extend the syntax to such cases, I have several const unsigned char * const * const a [] = { ... } :-)