Sadek
Sadek

Reputation: 175

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 ?

Upvotes: 2

Views: 1520

Answers (2)

P.P
P.P

Reputation: 121397

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");

Upvotes: 4

John Bode
John Bode

Reputation: 123508

The only length modifier that's valid to use with %s is l, and it signifies that the argument has type wchar_t, not char.

None of hh, h, ll, j, z, or t are defined for use with s.

Please see the C 2011 online standard, §7.21.6.1, para 7.

Upvotes: 2

Related Questions