Menu

FP uninitvar on getsockopt()

2025-10-01
2025-10-16
  • David Gibson

    David Gibson - 2025-10-01

    I just encountered an odd false positive on uninitvar. cppcheck is detecting an variable as uninitialized, although it has been set as the result of a getsockopt(). Specifically, with the attached example file:

    $ cppcheck --enable=all --library=posix --suppress=missingIncludeSystem --suppress=unusedStructMember --suppress=unusedFunction --include=/usr/include/linux/tcp.h cppcheck-getsockopt-uninitvar.c
    Checking cppcheck-getsockopt-uninitvar.c ...
    Checking cppcheck-getsockopt-uninitvar.c: __BIG_ENDIAN_BITFIELD...
    cppcheck-getsockopt-uninitvar.c:21:2: warning: Assignment of function parameter has no effect outside the function. Did you forget dereferencing it? [uselessAssignmentPtrArg]
     tinfo = &tinfo_new;
     ^
    cppcheck-getsockopt-uninitvar.c:19:24: warning: Uninitialized variable: tinfo->tcpi_retransmits [uninitvar]
     printf("%u\n", tinfo->tcpi_retransmits);
                           ^
    cppcheck-getsockopt-uninitvar.c:13:6: note: Assuming condition is false
     if (!tinfo) {
         ^
    cppcheck-getsockopt-uninitvar.c:19:24: note: Uninitialized variable: tinfo->tcpi_retransmits
     printf("%u\n", tinfo->tcpi_retransmits);
                           ^
    Checking cppcheck-getsockopt-uninitvar.c: __LITTLE_ENDIAN_BITFIELD...
    nofile:0:0: information: Unmatched suppression: unusedStructMember [unmatchedSuppression]
    
    nofile:0:0: information: Active checkers: 110/966 (use --checkers-report=<filename> to see details) [checkersReport]
    

    The FP appears to be quite sensitive to the particulars:
    * Removing the final pointless assignment of tinfo (correctly warned by cppcheck) removes the uninitvar warning
    * Setting tinfo = NULL rather than passing as a parameter removes the warning

     

    Last edit: David Gibson 2025-10-02
  • David Gibson

    David Gibson - 2025-10-01

    Sorry, forgot to mention, this occurred with cppcheck 2.18.3 (installed from Fedora package cppcheck-2.18.3-1.fc42.x86_64).

     
  • CHR

    CHR - 2025-10-01

    Does this happen without --include=/usr/include/linux/tcp.h?

     
    • David Gibson

      David Gibson - 2025-10-02

      It does not. It does appear if I replace the --include with -I /usr/include so cppcheck can find the header that way. That also triggers a bunch of other warnings from headers, though.

      The warning also appears if I don't include that header, but locally define struct tcp_info. The bug originally appeared that way, but it's a large structure, so I used the header for brevity,

      The warning does not appear if I use the version of the structure defined in /usr/include/netinet/tcp.h instead of the one in the Linux header. The Linux one is different, because it includes extension fields. I originally found the problem in an example using one of those extension fields, but the warning persists if I use one of the base fields that's common between the POSIX and Linux versions.

       

      Last edit: David Gibson 2025-10-02
  • CHR

    CHR - 2025-10-02

    Please include the struct definition that reproduces the error.

     
    • David Gibson

      David Gibson - 2025-10-10

      Sorry, it took me a while to look at this again. Here's the revised source including the struct definition.

      $ cppcheck --enable=all --library=posix --suppress=missingIncludeSystem --suppress=unusedStructMember --suppress=unusedFunction cppcheck-getsockopt-uninitvar.c
      Checking cppcheck-getsockopt-uninitvar.c ...
      cppcheck-getsockopt-uninitvar.c:111:2: warning: Assignment of function parameter has no effect outside the function. Did you forget dereferencing it? [uselessAssignmentPtrArg]
       tinfo = &tinfo_new;
       ^
      cppcheck-getsockopt-uninitvar.c:109:24: warning: Uninitialized variable: tinfo->tcpi_retransmits [uninitvar]
       printf("%u\n", tinfo->tcpi_retransmits);
                             ^
      cppcheck-getsockopt-uninitvar.c:103:6: note: Assuming condition is false
       if (!tinfo) {
           ^
      cppcheck-getsockopt-uninitvar.c:109:24: note: Uninitialized variable: tinfo->tcpi_retransmits
       printf("%u\n", tinfo->tcpi_retransmits);
                             ^
      nofile:0:0: information: Active checkers: 110/966 (use --checkers-report=<filename> to see details) [checkersReport]
      
       
  • CHR

    CHR - 2025-10-10

    Thanks for reporting, ticket is here: https://trac.cppcheck.net/ticket/14191

     
  • Oliver Stöneberg

    FYI -include is to always include into a file which is probably not what you want - see https://gcc.gnu.org/onlinedocs/gcc-15.2.0/gcc/Preprocessor-Options.html#index-include. This is usually used for something like precompiled headers.

     
    • David Gibson

      David Gibson - 2025-10-16

      I'm aware that's a weird use of -include. The difficulty was that to trigger the bug I needed to really include that specific header - not use cppcheck's built in knowledge of standard headers. But using -I would cause it to really process all the other headers too, which I didn't want to do, and those headers triggered some additional spurious warnings that aren't relevant to this case. -include was a workaround to accomplish that. Just including the structure definition inline was a better approach, though.

       

Log in to post a comment.