On 02/21/2017 05:07 AM, Basin Ilya wrote:
Hi. Here's a small piece of code: static struct { const char fmt[10]; } const x = { "%d\n" }; static const char * const fmt = "%d\n"; printf(fmt, 1); printf(x.fmt, 1); The second `printf` produces a warning: test.c:105:10: warning: format string is not a string literal [-Wformat-nonliteral] printf(x.fmt, 1); ^~~~~ From my point of view both format strings are identical. Why can't gcc deduce the format string in the second case?
Strictly speaking, in neither printf call is the argument a string literal so the warning is a bit misleading in this case. The limitation is due to the difference between the representation GCC uses for the initializer of the struct and that of the pointer. There's a level of non-trivial indirection in the struct case that the format checker doesn't handle even though in this case it seems that it could. The format checker runs very early on, during parsing. At that stage, the representation of even constant data is fairly cumbersome to work with. It gets easier as the AST is transformed by various passes and some of the language-specific differences between data representation have been obviated. Bug 79554 points out a similar limitation. I'm hoping to move some of the -Wformat checking to a later stage in GCC 8 where the -Wformat-overflow and -Wformat-truncation are implemented and where where this limitation (and others) isn't so much an issue anymore. Martin