https://gcc.gnu.org/bugzilla/show_bug.cgi?id=90005
--- Comment #5 from Jonathan Wakely <redi at gcc dot gnu.org> --- (In reply to Andrew Pinski from comment #3) > Because GCC allows passing non pods via varargs now. This is an explicit > change due to newer c++ changes. Right. The C++ standard says: "Passing a potentially-evaluated argument of class type (Clause 11) having a non-trivial copy constructor, a non-trivial move constructor, or a non-trivial destructor, with no corresponding parameter, is conditionally-supported with implementation-defined semantics." GCC supports passing a non-trivial type such as std::string to "...", with implementation-defined semantics. Some other compilers do not support it. But printf still requires a char* for a %s argument, which is what -Wformat will warn about. Passing invalid arguments to printf often results in complete garbage, e.g. printf("%s", &printf). That's not specific to passing a std::string, it's just how printf works: you need to pass the right arguments.