cowgol
                                
                                 cowgol copied to clipboard
                                
                                    cowgol copied to clipboard
                            
                            
                            
                        Strings can't be const? Duplicate strings go unnoticed.
Hello --
I wrote an 8080 disassembler in Cowgol: https://github.com/ibara/cowgol-utilities/blob/main/cowdis.cow
I was a little hesitant to write a massive array in Cowgol, so I opted for a big switch statement. Originally, for the OneByte(), TwoByte(), and ThreeByte() calls within Disassemble() I wrote the strings in directly as arguments. But I noticed the generated CP/M binary was larger than anticipated, so I ran my hexdump utility on it. I discovered that Cowgol was unable to notice that I was using the same strings over and over again (e.g., "mov", "add", etc.) and so it had many copies of the strings in the binary. So I figured I would turn them into variables. But then I thought it would make more sense to mark them const. However, Cowgol forbids marking strings const, giving an error saying "only constant values are allowed here."
Just making sure I didn't miss anything. It's ok if these items are future planned or not slated for development. I really just want to make sure I'm writing Cowgol code best practice.
Yeah, const variables have to be untyped, which is why they can't be string constants --- they're expanded inline during compilation (similar to #defines). Strings aren't deduped because that require keeping every string in memory to do so, although thinking about it maybe that could be done in cowlink, where there's plenty of room.
The cheapest way of making a string constant should be:
var something[] := "String here";
...but I don't recall off the top of my head whether that's actually implemented or not yet.
I figured that was the reason for no dedup. I'm ok with the way I did it. I was mainly just curious.
var something[] := "String here";
seems not to be working, I get an error unexpected OPENSQ when I try it.
My
var something: [uint8] := "String here";
solution is fine for me. It brought the size of the disassembler down 1.5 KB (9 KB when using hardcoded non-deduped strings to 7.5 KB with variable strings) which is more than enough for my needs.
Okay, that's something I need to fix.
The reason why the former's preferable is that the second is a pointer to a string, and so to get the string address the pointer needs to be dereferenced. Getting the address of an array is a simple constant load, as in C.
That makes sense, thanks.