Quick Links: |
Provide a macro to indicate that a return value is a format string. More...
BSLA_FORMAT(FMT_IDX) | validate printf -style format spec. in n th arg. |
BSLA_FORMAT_IS_ACTIVE | 1 if BSLA_FORMAT is active and 0 otherwise |
printf
-style format specification, and that the function will return a printf
-style format string with an equivalent specification. BSLA_FORMAT(FMT_IDX)
This annotation specifies that the so-annotated function takes an argument that is a valid format string for a printf
-style function and returns a format string that is consistent with that format. This allows format strings manipulated by translation functions to be checked against arguments. Without this annotation, attempting to manipulate the format string via this kind of function might generate warnings about non-literal formats, or fail to generate warnings about mismatched arguments.BSLA_FORMAT_IS_ACTIVE
The macro BSLA_FORMAT_IS_ACTIVE
is defined to 0 when BSLA_FORMAT
expands to nothing and 1 otherwise.enum
, Language
, to indicate the choice of languages: enum Language {
e_ENGLISH,
e_SPANISH,
e_DUTCH,
e_FRENCH };
prefixName
, which will take a format string and prefix it with the word name
in the selected language. The BSLA_FORMAT
annotation indicates that the result will be a pointer to a printf
-style format string equivalent to the format string passed to the third argument: const char *prefixName(char *buf, Language lang, const char *format) BSLA_FORMAT(3); const char *prefixName(char *buf, Language lang, const char *format) // Create a buffer beginning with the word 'name' translated to the // specified 'lang', followed by the specified format string 'format', // using the specified 'buf' for memory. { const char *name = ""; switch (lang) { case e_ENGLISH: name = "Name"; break; case e_SPANISH: name = "Nombre"; break; case e_DUTCH: name = "Naam"; break; case e_FRENCH: name = "Nom"; break; } ::strcpy(buf, name); ::strcat(buf, ": "); ::strcat(buf, format); return buf; }
main
, we call printf
and sscanf
using the return value of prefixName
. No warnings occur when correct arguments are passed: char buffer[1000]; ::printf(prefixName(buffer, e_SPANISH, "%s\n"), "Michael Bloomberg"); char name[100]; ::sscanf("Emmanuel Macron", prefixName(buffer, e_FRENCH, "%s"), name);
printf
and sscanf
passing arguments that won't match the resulting format string: ::printf(prefixName(buffer, e_ENGLISH, "%s\n"), 2.7); int x; ::sscanf("Sharon den Adel", prefixName(buffer, e_DUTCH, "%s"), &x);
.../bsla/bsla_format.t.cpp:306:56: warning: format '%s' expects argument of type 'char*', but argument 2 has type 'double' [-Wformat=] ::printf(prefixName(buffer, e_ENGLISH, "%s\n"), 2.7); ^ .../bsla_format.t.cpp:308:70: warning: format '%s' expects argument of type 'char*', but argument 3 has type 'int*' [-Wformat=] ::sscanf("Sharon den Adel", prefixName(buffer, e_DUTCH, "%s"), &x); ~~^