0

According to ISO C standard (ISO/IEC 9899), printf function contains "%n" format to count the number of output characters.

n: The argument shall be a pointer to signed integer into which is written the number of characters written to the output stream so far by this call to fprintf. No argument is converted, but one is consumed. If the conversion specification includes any flags, a field width, or a precision, the behavior is undefined.

Example code:

#include <stdio.h>
int main (void) {
    int c1, c2;
    printf ("hello%n, world%n\n", &c1, &c2);
    printf ("% d\t% d\n", c1, c2);
    return 0;
}

Output of the example

The C runtime library on both Windows (MSVCRT/UCRT) and Linux (GLIBC) supports "%n" format in printf function. (However, "%n" format is disabled by default when using cl.exe to compile C program in Windows. A nonstandard function _set_printf_count_output by Microsoft is required to enable "%n" format. That is because cl.exe is a C++ compiler, function printf is not in common use in C++ [In C++ std::cout is used instead]. If cl.exe followed C standard, "%n" format should be enabled by default and disabled by using _set_printf_count_output function. In addition, Microsoft creates a nonstandard function printf_s, in which "%n" format is completely disabled)

Unlike MSVCRT/UCRT in Windows and GLIBC in Linux, The Bionic C runtime library in Android does not support "%n" format at all, which parses "%n" format only into two ordinary characters "%" and "n". Why "%n" format is not parsed in ISO standard by Bionic C runtime library?

  • 1
    Likely because `%n` has been the source of a great many exploits in programs, and is rarely used. – mevets Aug 07 '22 at 11:45
  • In MSVC [Microsoft says](https://learn.microsoft.com/en-us/cpp/c-runtime-library/format-specification-syntax-printf-and-wprintf-functions?view=msvc-160#type) *The `n` specifier is disabled by default; for information see the important security note.*. – Weather Vane Aug 07 '22 at 12:00
  • 1
    Please don't post pictures of text. Just post the text itself in your question, formatted as a code sample. – larsks Aug 07 '22 at 12:43
  • @WeatherVane cl.exe is a C++ compiler. `printf` is not commonly used in C++ because C++ has `std::cout`. So Microsoft does not need to fully support C standard in cl.exe. – stanchcorder6 Aug 07 '22 at 16:33
  • @stanchcorder6 CL is a C compiler. I use it all the time, but don't code in C++ although CL might work for C++ too. I was pointing out that `%n` isn't freely usable. – Weather Vane Aug 07 '22 at 16:40
  • @WeatherVane `int n; scanf ("%d", &n); int a[n];` does not have any error in C. But cl.exe generates an error "Expression must have a constant value" even with /tc switch and file extension is .c. (GCC and Clang does not give any errors or warnings) – stanchcorder6 Aug 07 '22 at 16:46
  • @stanchcorder6 that is `scanf` not `printf` and didn't use `%n` anyway. The compiler error is referring to `int a[n];` because MS VC does not support variable length arrays. – Weather Vane Aug 07 '22 at 16:54

0 Answers0