0
int main(void)
{

    char s[4] = "heloo"; // The character array is initialized with more data than its size

    printf("%s",s);  
}

The output is: helo�[�G�.

Why is the output in this format?

Vlad from Moscow
  • 301,070
  • 26
  • 186
  • 335
Shiva
  • 21
  • 1
  • 5
  • 1
    better dupe -all explained there https://stackoverflow.com/questions/1675477/why-doesnt-the-compiler-detect-out-of-bounds-in-string-constant-initialization/1675519#1675519 – 0___________ Feb 17 '20 at 12:13
  • Eh turns out I've written a community wiki dupe target for this myself. Which has an answer by Vlad as well, heh... I'll pick this wiki I just found. – Lundin Feb 17 '20 at 12:13
  • @Lundin: The question shows output from executing the program, indicating that it did compile, and hence the statement that it “won’t compile” is false. The C standard only requires C implementations to issue diagnostics for constraint violations; it does not require them not to translate the program. – Eric Postpischil Feb 17 '20 at 12:47

1 Answers1

5

The compiler shall issue an error because there are more initializers than the number of elements of the array and the redundant initializer is not the terminating zero of the string literal.

From the C Standard (6.7.9 Initialization)

2 No initializer shall attempt to provide a value for an object not contained within the entity being initialized.

The one exclusion of this rule is regards character arrays when the terminating zero of a string literal can be excluded from initializers if the character array does not have a corresponding element.

14 An array of character type may be initialized by a character string literal or UTF−8 string literal, optionally enclosed in braces. Successive bytes of the string literal (including the terminating null character if there is room or if the array is of unknown size) initialize the elements of the array.

If the program was run then it has undefined behavior. The character array does not contain a string that is required when the conversion specifier %s is used.

Vlad from Moscow
  • 301,070
  • 26
  • 186
  • 335
  • There are no errors, only warning from compilers. Could you please explain why the below O/P: The outputis: helo�[�G� – Shiva Feb 17 '20 at 11:55
  • 1
    @Suri Heed the warnings, treat them as errors (because that’s what they actually are). – Konrad Rudolph Feb 17 '20 at 11:57
  • `s` lives on the stack and contains `"helo"` *without a null terminator*. You pass `printf` a pointer to `s` and, not knowing how large `s` is, it continues printing after it reaches the end of the array using whatever bytes happen to be on the stack. It stops when it reaches a `NUL` byte (or gets a memory fault). – Dan Robertson Feb 17 '20 at 12:06
  • This is a good answer but it turns out we've already answered this before. Maybe you could merge the answer here into [this answer](https://stackoverflow.com/a/58526329/584518)? – Lundin Feb 17 '20 at 12:15
  • @Suri -- "_There are no errors, only warning from compilers._": the rule quoted above (6.7.9p2) is a _constraint_ in C Standard terminology, and the Standard requires that compilers issue _diagnostics_ for constraint violations. It does not say anything about warnings or errors (either would suffice as a diagnostic). Unless you know exactly what a warning means and exactly what you are doing, treat warnings as mistakes to be fixed, i.e. errors, as Konrad Rudolph said. Use the `-Werror` option in Clang or GCC to disallow compilation when warnings occur. – ad absurdum Feb 17 '20 at 15:54
  • @KonradRudolph can please elaborate on `Heed the warnings, treat them as errors (because that’s what they actually are)` Warnings are not errors for sure. But how is one supposed to interpret them? Can you please elaborate on this? – Abhishek Ghosh Dec 22 '21 at 14:35
  • 1
    @AbhishekGhosh No, they’re (in this case) *errors*. Namely, errors in the logic of the code that is causing bugs. Anyway, what do you mean by “how is one supposed to interpret them”? The warning messages in the case of OP’s code couldn’t be clearer, e.g. “initializer-string for array of 'char' is too long” and “ include '' or provide a declaration of 'printf'”. – Konrad Rudolph Dec 22 '21 at 14:44
  • @KonradRudolph `how is one supposed to interpret them?` As a programmer how is one supposed to interpret warnings? Consider them as errors? That is what I wanted to ask.I mean warnings do not prevent the programs from being compiled, but since the compiler is making the effort to inform us against a possible flaw or sloppiness in the code [might be due to old coding style or something else], so in that case how to interpret them...Be serious about warning and try to write warning free codes? Or just ignore them as they are just "warnings" but produces perfect working executable or object codes – Abhishek Ghosh Dec 22 '21 at 15:04
  • 1
    @AbhishekGhosh Ah, got you. Unfortunately there is no general guidance, since different warnings have different interpretations. However, *in general*, with GCC and clang you can/should compile with `-pedantic-errors -Wall -Wextra -Werror`. That is, enable additional warnings and treat all of them as errors. This is a safe default: these are virtually always actual errors. Beyond this, there are more warning flags but some of these are less black-and-white, and some are experimental (i.e. future compilers might change how they are reported) so I tend not to use them. – Konrad Rudolph Dec 22 '21 at 15:33