Reputation: 175
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
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
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