Good Morning, I have come across something that I feel a shortcoming in the warnings that gcc issues when compiling some C++ code. Calling it a bug seems a bit harsh so I thought I would ask this mailing list of their opinion before raising an issue. When I use a template to perform some sscanf work on a string I loose some of the -Wformat warnings about the expected argument types. Here is a set of C++ code that demonstrates the warnings occurring for sscanf and not happening for the template. ----- #include <stdio.h> template<class...Ts> bool message_scanner(const char *message, const char *format, Ts const&...ts) { size_t num_scanned(sscanf(message,format,ts...)); bool got_them_all(num_scanned == sizeof...(ts)); return got_them_all; } int main () { bool correct(false); short int anInt(0); char aChar('c'); float aFloat(0.0); char* message = "EXAMPLE001:01,02"; // No warnings are given about expected argument types for the template if(message_scanner(message,"<EXAMPLE%x:%x,%i",&anInt,&aChar,&aFloat)) { correct = true; } // Warnings are given about expected argument types if(2==sscanf(message,"<EXAMPLE%x:%x,%i",&anInt,&aChar,&aFloat)) { correct = true; } return correct?0:1; } ----- Perhaps I am doing something wrong with the way I am handling this template. There is probably a macro equivalent or some other way this could be handled and retain the warnings but I found it interesting they were lost here. I assume that is because templates are handled not by code substitution but at a later stage so there is never a sscanf function produced for GCC to check. When I compile the above with GCC 4.8.4 I get: $ gcc sscanf_template_warnings_example.cpp sscanf_template_warnings_example.cpp:3:15: warning: variadic templates only available with -std=c++11 or -std=gnu++11 [enabled by default] template<class...Ts> ^ sscanf_template_warnings_example.cpp:4:75: warning: variadic templates only available with -std=c++11 or -std=gnu++11 [enabled by default] bool message_scanner(const char *message, const char *format, Ts const&...ts) ^ sscanf_template_warnings_example.cpp: In function ‘bool message_scanner(const char*, const char*, const Ts& ...)’: sscanf_template_warnings_example.cpp:7:42: warning: variadic templates only available with -std=c++11 or -std=gnu++11 [enabled by default] bool got_them_all(num_scanned == sizeof...(ts)); ^ sscanf_template_warnings_example.cpp: In function ‘int main()’: sscanf_template_warnings_example.cpp:18:19: warning: deprecated conversion from string constant to ‘char*’ [-Wwrite-strings] char* message = "EXAMPLE001:01,02"; ^ sscanf_template_warnings_example.cpp:27:64: warning: format ‘%x’ expects argument of type ‘unsigned int*’, but argument 3 has type ‘short int*’ [-Wformat=] if(2==sscanf(message,"<EXAMPLE%x:%x,%i",&anInt,&aChar,&aFloat)) ^ sscanf_template_warnings_example.cpp:27:64: warning: format ‘%x’ expects argument of type ‘unsigned int*’, but argument 4 has type ‘char*’ [-Wformat=] sscanf_template_warnings_example.cpp:27:64: warning: format ‘%i’ expects argument of type ‘int*’, but argument 5 has type ‘float*’ [-Wformat=] Note that all the warnings are about line 27, the sscanf line but none are given about the templated version. Do people think this is worthy of me raising a bug? Is there a better way I could be handling the sscanf work without making it so that the developer has to correct tally up the number of items that should be scanned? There are a couple of dozen items in some of the strings I must parse, so the odds of a mistake now or in a future update are high. -- Thomas Thorne <tafthorne@xxxxxxxxxxxxxx>
Attachment:
signature.asc
Description: This is a digitally signed message part