Why does gcc allow char array initialization with string literal larger than array?

前端 未结 4 2046
攒了一身酷
攒了一身酷 2020-12-03 21:15
int main()
{
    char a[7] = \"Network\";
    return 0;
}

A string literal in C is terminated internally with a nul charac

4条回答
  •  生来不讨喜
    2020-12-03 21:46

    While unwind's answer explains why gcc doesn't warn about this, it doesn't say what you can do about it.

    gcc's -Wc++-compat warning option will detect this particular issue with the message:

    foo.c: In function ‘main’:
    foo.c:3:17: warning: initializer-string for array chars is too long for C++ [-Wc++-compat]
    

    That's the only option that will cause gcc to warn about this problem. You can write a short script to quickly grep the warning options out of gcc's man page, try compiling with each, and see if it complains.

    $ time for F in $(man gcc | grep -o -- '-W[^= ]*')
        do if gcc -c "${F}" foo.c |& grep :3 >& /dev/null; then
             echo "${F}"; gcc -c "${F}" foo.c
        fi
      done
    man gcc | grep -o -- '-W[^= ]*')
    man gcc | grep -o -- '-W[^= ]*'
    -Wall
    foo.c: In function ‘main’:
    foo.c:3:10: warning: unused variable ‘a’ [-Wunused-variable]
    -Wc++-compat
    foo.c: In function ‘main’:
    foo.c:3:17: warning: initializer-string for array chars is too long for C++ [-Wc++-compat]
    -Wunused
    foo.c: In function ‘main’:
    foo.c:3:10: warning: unused variable ‘a’ [-Wunused-variable]
    -Wunused-variable
    foo.c: In function ‘main’:
    foo.c:3:10: warning: unused variable ‘a’ [-Wunused-variable]
    -Wtraditional
    foo.c: In function ‘main’:
    foo.c:3:5: warning: traditional C rejects automatic aggregate initialization [-Wtraditional]
    -Wall
    foo.c: In function ‘main’:
    foo.c:3:10: warning: unused variable ‘a’ [-Wunused-variable]
    -Wall
    foo.c: In function ‘main’:
    foo.c:3:10: warning: unused variable ‘a’ [-Wunused-variable]
    -Wunused-variable
    foo.c: In function ‘main’:
    foo.c:3:10: warning: unused variable ‘a’ [-Wunused-variable]
    -Wunused
    foo.c: In function ‘main’:
    foo.c:3:10: warning: unused variable ‘a’ [-Wunused-variable]
    -Wunused
    foo.c: In function ‘main’:
    foo.c:3:10: warning: unused variable ‘a’ [-Wunused-variable]
    -Wall
    foo.c: In function ‘main’:
    foo.c:3:10: warning: unused variable ‘a’ [-Wunused-variable]
    -Wall
    foo.c: In function ‘main’:
    foo.c:3:10: warning: unused variable ‘a’ [-Wunused-variable]
    -Wall
    foo.c: In function ‘main’:
    foo.c:3:10: warning: unused variable ‘a’ [-Wunused-variable]
    -Wunused
    foo.c: In function ‘main’:
    foo.c:3:10: warning: unused variable ‘a’ [-Wunused-variable]
    -Wunused-variable
    foo.c: In function ‘main’:
    foo.c:3:10: warning: unused variable ‘a’ [-Wunused-variable]
    -Wunused
    foo.c: In function ‘main’:
    foo.c:3:10: warning: unused variable ‘a’ [-Wunused-variable]
    -Wunused
    foo.c: In function ‘main’:
    foo.c:3:10: warning: unused variable ‘a’ [-Wunused-variable]
    -Wunused
    foo.c: In function ‘main’:
    foo.c:3:10: warning: unused variable ‘a’ [-Wunused-variable]
    -Wall
    foo.c: In function ‘main’:
    foo.c:3:10: warning: unused variable ‘a’ [-Wunused-variable]
    -Wall
    foo.c: In function ‘main’:
    foo.c:3:10: warning: unused variable ‘a’ [-Wunused-variable]
    -Wall
    foo.c: In function ‘main’:
    foo.c:3:10: warning: unused variable ‘a’ [-Wunused-variable]
    -Wall
    foo.c: In function ‘main’:
    foo.c:3:10: warning: unused variable ‘a’ [-Wunused-variable]
    -Wtraditional
    foo.c: In function ‘main’:
    foo.c:3:5: warning: traditional C rejects automatic aggregate initialization [-Wtraditional]
    -Wtraditional
    foo.c: In function ‘main’:
    foo.c:3:5: warning: traditional C rejects automatic aggregate initialization [-Wtraditional]
    -Wc++-compat
    foo.c: In function ‘main’:
    foo.c:3:17: warning: initializer-string for array chars is too long for C++ [-Wc++-compat]
    -Wall
    foo.c: In function ‘main’:
    foo.c:3:10: warning: unused variable ‘a’ [-Wunused-variable]
    -Wtraditional
    foo.c: In function ‘main’:
    foo.c:3:5: warning: traditional C rejects automatic aggregate initialization [-Wtraditional]
    -Wall
    foo.c: In function ‘main’:
    foo.c:3:10: warning: unused variable ‘a’ [-Wunused-variable]
    -Wall
    foo.c: In function ‘main’:
    foo.c:3:10: warning: unused variable ‘a’ [-Wunused-variable]
    -Wall
    foo.c: In function ‘main’:
    foo.c:3:10: warning: unused variable ‘a’ [-Wunused-variable]
    -Wall
    foo.c: In function ‘main’:
    foo.c:3:10: warning: unused variable ‘a’ [-Wunused-variable]
    -Wall
    foo.c: In function ‘main’:
    foo.c:3:10: warning: unused variable ‘a’ [-Wunused-variable]
    -Wtraditional
    foo.c: In function ‘main’:
    foo.c:3:5: warning: traditional C rejects automatic aggregate initialization [-Wtraditional]
    
    real    0m26.399s
    user    0m5.128s
    sys 0m15.329s
    

    In general, a lint-like tool such as splint will warn you about all sorts of potential issues. In this case, it will say:

    foo.c:3:17: String literal with 8 characters is assigned to char [7] (no room
                   for null terminator): "Network"
      A string literal is assigned to a char array that is not big enough to hold
      the null terminator. (Use -stringliteralnoroom to inhibit warning)
    foo.c:3:10: Variable a declared but not used
    

提交回复
热议问题