I'm writing an assembler for a language I'm making up as I go along, and I'm parsing labels.
Labels start with an octothorpe, and end with a whitespace character, so as I parse, if I encounter an #, I call my make_label
function.
make_label
looks something like:
uint32_t make_label(FILE f) {
uint8_t i=0;
char c;
char buffer[64];
while ( (c = fgetc(f)) != ' ') {
buffer[i++] = c;
}
// Do thing with label
return 1
}
There's a bit more to it, but that's the general gist. There's a bug as written, which uncovered some weird behaviour I don't quite understand.
I forgot to '\0'
terminate the buffer. When I examined the labels, given an input like:
#start
...
#loop
...
#ignore
...
#end
...
I would see the labels:
start
loopt
ignore
endore
The buffer
variable was keeping its value between calls.
I'm not sure it really matters, because I realise I should have been adding the null terminator, but I was curious as to why this is happening? I was using printf
to output the buffer, and it didn't seem to care that there was no terminator, which is why I didn't notice immediately.
Is this all just dumb luck? The array as declared just happened to be zeroed, and each call just happened to allocate the same block on the stack?