Inconsistent gcc diagnostic for string initialization

后端 未结 3 909
小鲜肉
小鲜肉 2020-12-01 22:29

I\'m using gcc 4.9.1/Mingw and compiling the code with:

gcc test.c -otest.exe -std=c11 -pedantic-errors -Wall -Wextra

This code

相关标签:
3条回答
  • 2020-12-01 23:03

    In

    char b[5] = "hello";  
    

    \0 is not appended to the string because array b is of size 5. This is valid. Compiler think of it as

    char b[5] = {'h','e','l','l','o'};
    

    Here b is an array of chars. But, it can't be used in a place where a string literal is to be supposed. For example, You can't use b in printf with %s specifier or str family function.

    0 讨论(0)
  • 2020-12-01 23:08

    It's a weird quirk in the C Standard. Back in the day, people occasionally used fixed-length, non-null-terminated strings. (One example was the 14-character filenames in V7 Unix.) So to let those old programs to continue to compile, it's legal to initialize an explicitly-sized char array with a string constant that ends up scraping off the '\0', as you've just observed.

    I agree it's surprising that the {'h','e','l','l','o','\0'} initializer warned while the "hello" one did not. But these are two very different forms, and it turns out that the rules for them are different. When you give your array a size and you use the {} form, there must be room for all your initializers, period. But when you give a size and use the "" form, there's a special exception for that case and that case only.

    (It's also not legal in C++ for either form.)

    0 讨论(0)
  • 2020-12-01 23:09

    While:

     char a[5] = {'h','e','l','l','o','\0'};
    

    is invalid.

    (C11, 6.7.9p2) "No initializer shall attempt to provide a value for an object not contained within the entity being initialized."

    This:

    char b[5] = "hello";
    

    is explicitly allowed by C (emphasis mine):

    (C11, 6.7.9p14) "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."

    But

     char b[5] = "hello!";
    

    is invalid.

    0 讨论(0)
提交回复
热议问题