> it means that my compiler mingw added the null terminator automatically.
The compiler didn't add a \0 automatically.
The \0 was already there in memory. Maybe by accident or maybe by design.
Many operating systems erase memory to zeros before starting a program, so if you don't write anything to some memory, chances are it will read as zero.
> Could I say that this is consistent in all compilers?
Well all compilers are consistent in that they wouldn't have written data[5] = '\0' for you.
But as for whether you'd always get lucky and find a \0 just in the right place, there is nothing consistent about that.
> What if I used an arduino compiler?
Same thing - whether it works or not is just dumb luck.
> the letter 'o' is printed twice and the last value indeed is a 0 or null terminator.
> So how does strcmp value becomes 0, if this is the case?
Well the compiler knows that the memory associated with data[5] doesn't exist as far as your program is concerned. So it's free to use that memory for any other purpose as it sees fit.
Anything after line 16 could have changed that memory location (like declaring additional variables), so by the time you printed that location, it was no longer a \0.
> Based on my reading we should always set the null terminator in any c style string
That's generally true if you use the double quote route to creating your string constants.
If you're doing single character assignments or single character initialisers, then you're on your own and you have to make sure you add the \0.
But even double quoted strings have a trap.
1 2 3 4 5 6 7 8 9 10 11
|
$ cat foo.c
int main ( ) {
char a[] = "test"; // always has a \0
char c[4] = "test"; // doesn't have a \0 (valid only in C, broken in C++)
}
$ gcc foo.c
$ g++ foo.c
foo.c: In function ‘int main()’:
foo.c:3:17: error: initializer-string for array of chars is too long [-fpermissive]
3 | char c[4] = "test"; // doesn't have a \0 (valid only in C, broken in C++)
| ^~~~~~
|