Search code examples
cprintfundefined-behaviorlibcformat-specifiers

Behaviour of printf using length subspecifier with a string


I'm curious how work printf and I have try many tricks like :

printf("Test 1: %hs\n", "hi");
printf("Test 2: %hhs\n", "hi");
printf("Test 3: %ls\n", "hi");
printf("Test 4: %lls\n", "hi");
printf("Test 5: %js\n", "hi");
printf("Test 6: %zs\n", "hi");
printf("Test 7: %ts", "hi");

I'm using printf with s specifier and all length modifier (usually used with numerical speficier (like d / i / u / o ...) and i'm getting strange output :

Test 1: hi
Test 2: hi
Test 3: Test 4: Test 5: Test 6: hi
Test 7: hi

It seem's that the l / ll / j length modifiers make printf bug and stop to work (it doesn't print the \n but with all other length modifiers it seems to ignore the length modifier and work like normal usage).

Why it follow this behavior ?


Solution

  • The answer is undefined behaviour. The format specifier %s doesn't support any of the length modifiers you have used for the arguments you pass. Format specifier mismatch is undefined in C. When I compile your code with gcc compiler (gcc -Wall -Wextra -std=c11 test.c), it says as much:

    test.c: In function ‘main’:
    test.c:5:19: warning: use of ‘h’ length modifier with ‘s’ type character has either no effect or undefined behavior [-Wformat=]
     printf("Test 1: %hs\n", "hi");
                       ^
    test.c:6:20: warning: use of ‘hh’ length modifier with ‘s’ type character has either no effect or undefined behavior [-Wformat=]
     printf("Test 2: %hhs\n", "hi");
                        ^
    test.c:7:19: warning: format ‘%ls’ expects argument of type ‘wchar_t *’, but argument 2 has type ‘char *’ [-Wformat=]
     printf("Test 3: %ls\n", "hi");
                       ^
    test.c:8:20: warning: use of ‘ll’ length modifier with ‘s’ type character has either no effect or undefined behavior [-Wformat=]
     printf("Test 4: %lls\n", "hi");
                        ^
    test.c:9:19: warning: use of ‘j’ length modifier with ‘s’ type character has either no effect or undefined behavior [-Wformat=]
     printf("Test 5: %js\n", "hi");
                       ^
    test.c:10:19: warning: use of ‘z’ length modifier with ‘s’ type character has either no effect or undefined behavior [-Wformat=]
     printf("Test 6: %zs\n", "hi");
                       ^
    test.c:11:19: warning: use of ‘t’ length modifier with ‘s’ type character has either no effect or undefined behavior [-Wformat=]
     printf("Test 7: %ts", "hi");