Wformat-overflow warning with two-dimensional array

"Felix Windsheimer \(Fujitsu\) via Gcc-help" <[email protected]>
Newsgroups gmane.comp.gcc.help
Message-ID <FR5P281MB5448A1F603671965995E35C6FED6A@FR5P281MB5448.DEUP281.PROD.OUTLOOK.COM>
Hi,

The following code:

#include <stdio.h>
#include <string.h>

int main(void) {
        char names[1000][20];
        memset(names, 0, sizeof(names));

        for (unsigned int i = 0; i < 5; i++) {
                char s[40];
                sprintf(s, "/dev/%s", names[i]);
        }
}

Should - in our opinion - be correct as names[i] is guaranteed to be null-terminated due to the memset.
However, GCC 15.2 produces a warning:

~ gcc-15 -Wall -O1 bug.c
bug.c: In function 'main':
bug.c:10:34: warning: '%s' directive writing up to 19999 bytes into a region of size 35 [-Wformat-overflow=]
   10 |                 sprintf(s, "/dev/%s", names[i]);
      |                                  ^~
bug.c:10:17: note: 'sprintf' output between 6 and 20005 bytes into a destination of size 40
   10 |                 sprintf(s, "/dev/%s", names[i]);
      |                 ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

To us it seems like GCC misunderstands the size of a two-dimensional array, or rather, the size of a single element in this array.
Note that changing the sprintf to use a constant instead of `i` produces no warning:

        for (unsigned int i = 0; i < 5; i++) {
                char s[40];
                sprintf(s, "/dev/%s", names[0]); // any constant [0, 999] works
        }

Is this simply a compiler bug or are we misunderstanding something here?
Thanks!

Kind regards
Felix

~ gcc-15 -v
Using built-in specs.
COLLECT_GCC=gcc-15
COLLECT_LTO_WRAPPER=/usr/lib64/gcc/x86_64-suse-linux/15/lto-wrapper
OFFLOAD_TARGET_NAMES=nvptx-none
OFFLOAD_TARGET_DEFAULT=1
Target: x86_64-suse-linux
Configured with: ../configure CFLAGS=' -fmessage-length=0 -grecord-gcc-switches -O2 -funwind-tables -fasynchronous-unwind-tables -fstack-clash-protection -g' CXXFLAGS=' -fmessage-length=0 -grecord-gcc-switches -O2 -funwind-tables -fasynchronous-unwind-tables -fstack-clash-protection -g' XCFLAGS=' -fmessage-length=0 -grecord-gcc-switches -O2 -funwind-tables -fasynchronous-unwind-tables -fstack-clash-protection -g' TCFLAGS=' -fmessage-length=0 -grecord-gcc-switches -O2 -funwind-tables -fasynchronous-unwind-tables -fstack-clash-protection -g' GDCFLAGS=' -fmessage-length=0 -grecord-gcc-switches -O2 -funwind-tables -fasynchronous-unwind-tables -fstack-clash-protection -g' --prefix=/usr --infodir=/usr/share/info --mandir=/usr/share/man --libdir=/usr/lib64 --libexecdir=/usr/lib64 --enable-languages=c,c++,objc,fortran,obj-c++,ada,go,d,m2 --enable-host-pie --enable-offload-targets=nvptx-none, --enable-offload-defaulted --without-cuda-driver --enable-checking=release --disable-werror --with-gxx-include-dir=/usr/include/c++/15 --with-libstdcxx-zoneinfo=/usr/share/zoneinfo --enable-ssp --disable-libssp --disable-libvtv --enable-cet=auto --disable-libcc1 --disable-plugin --with-bugurl=https://bugs.opensuse.org/ --with-pkgversion='SUSE Linux' --with-slibdir=/
lib64 --with-system-zlib --enable-libstdcxx-allocator=new --disable-libstdcxx-pch --enable-libphobos --enable-version-specific-runtime-libs --with-gcc-major-version-only --enable-linker-build-id --enable-linux-futex --enable-gnu-indirect-function --program-suffix=-15 --without-system-libunwind --enable-multilib --with-arch-32=x86-64 -with-tune=generic --enable-link-serialization --build=x86_64-suse-linux --host=x86_64-suse-linux
Thread model: posix
Supported LTO compression algorithms: zlib
gcc version 15.2.0 (SUSE Linux)
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.