Both format strings provide relatively simple functionality compared to other template engines, lexers and parsers.
Early programming languages like Fortran used special statements with different syntax from other calculations to build formatting descriptions.
[3] An example application looks like this: Hereby: In 1968, ALGOL 68 had a more function-like API, but still used special syntax (the $ delimiters surround special formatting syntax): In contrast to Fortran, using normal function calls and data types simplifies the language and compiler, and allows the implementation of the input/output to be written in the same language.
These advantages were thought to outweigh the disadvantages (such as a complete lack of type safety in many instances) up until the 2000s, and in most newer languages of that era I/O is not part of the syntax.
People have since learned[4] that this potentially results in consequences, ranging from security exploits to hardware failures (e.g., phone's networking capabilities being permanently disabled after trying to connect to an access point named "%p%s%s%s%s%n"[5]).
In 1973, printf was included as a C standard library routine as part of Version 4 Unix.
The need to do something about the range of problems resulting from lack of type safety has prompted attempts to make the C++ compiler printf-aware.
The -Wformat option of GCC allows compile-time checks to printf calls, enabling the compiler to detect a subset of invalid calls (and issue either a warning or an error, stopping the compilation altogether, depending on other flags).
The approach (and syntax) of C++20 std::format resulted from effectively incorporating Victor Zverovich's libfmt[13] API into the language specification [14] (Zverovich wrote[15] the first draft of the new format proposal); consequently, libfmt is an implementation of the C++20 format specification.
The formatting function has been combined with output in C++23, which provides[16] the std::print command as a replacement for printf().
Incorporation of a separate, domain specific mini-language specifically for formatting into the C++ language syntax for std::print, therefore, completes the historical cycle, bringing the state-of-the-art (as of 2024) back to what it was in the case of FORTRAN's first PRINT implementation in the 1950s discussed in the beginning of this section.
The precision field usually specifies a maximum limit of the output, depending on the particular formatting type.
For floating-point numeric types, it specifies the number of digits to the right of the decimal point to which the output should be rounded; for %g and %G it specifies the total number of significant digits (before and after the decimal, not including leading or trailing zeroes) to round to.
However, it is rarely used due to the fact that it conflicts with static format string checking.
Some applications (like the Apache HTTP Server) include their own printf-like function, and embed extensions into it.
This allows static format string checking (of the %p portion) at the expense of full compatibility with normal printf.
Variants of printf provide the formatting features but with additional or slightly different behavior.
For most printf-family functions, there is a variant that accepts va_list rather than a variable length parameter list.
Although an output function on the surface, printf allows writing to a memory location specified by an argument via %n.
[24] The %n functionality also makes printf accidentally Turing-complete even with a well-formed set of arguments.