I have been reading C Primer Plus (5th edition) by Stephen Prata. The Program listing 11.9 is a program to show what may the puts() function do if we declare a string and assign a value without an ending null character. (Of course this is viewed as a grammar mistake, but I want to know what error will this bug cause.) I experimented on my computer (with CodeBlocks my ide) a similar program, and tried different ways to declare the string.
For the program
#include <stdio.h>
int main()
{
char a[]={'a','b','c','d'};
char b[100]="Stack Overflow";
puts(a);
return 0;
}
in which I used a[] to declare the string, the program indeed output some thing other than abcd . I tried several times, and it always output abcd< and an empty line:
output:
abcd<
If I declare the string by a[100] , i.e. the program
#include <stdio.h>
int main()
{
char a[100]={'a','b','c','d'};
char b[100]="Stack Overflow";
puts(a);
return 0;
}
Then it seems quite normal. The program always output abcd and an empty line after I have repeated several times:
output:
abcd
If I use the pointer to declare the string:
#include <stdio.h>
int main()
{
char *a={'a','b','c','d'};
char b[100]="Stack Overflow";
puts(a);
return 0;
}
Then it only output an empty line:
output:
Why different ways of declaring the string, which is assigned a value without an ending '\0' yields different outputs?
If an aggregate (an array or structure) is explicitly initialized but not completely, the elements or members without initializers are implicitly initialized the same way as objects with static storage duration (per C 2018 6.7.9 21). For
charelements, that means they are initialized to zero (per 6.7.9 10). So, aftera[0]througha[3]are initialized with the given character codes,a[4]is initialized to zero. So the string beginning at the start ofais null terminated, by the null character ina[4], and passing that string toputsprints a string in the ordinary way.This is not a proper way to initialize
a.{'a','b','c','d',}does not represent an array; it is a list of initial values. Sinceais declared as a pointer, it should be initialized with a single value that is a pointer.When you compiled this, the compiler warned you that
'a'was the wrong type to initializea, and it warned you there were excess initializers in the list.When the compiler proceeded after this warning, it converted
'a'to a pointer, which typically yields an invalid address. It is surprising thatputs(a)did not cause the program to crash in attempting to access that address. (Perhaps you are running in a GUI, saw an empty output window, and did not notice a separate message about the program crashing?) If the program did not crash, there could have been a zero byte at the addressawas initialized with, so passingatoputsprinted nothing.