Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Please explain this result please. printf("%c", 'abcd')

#include <stdio.h>

int main()
{
    printf("%c\n", 'abcd');
    printf("%p\n", 'abcd');
    printf("%c\n", 0x61626364);
    printf("%c\n", 0x61626363);
    printf("%c\n", 0x61626365);
    return 0;
}

I want to ask this line : printf("%c\n", 'abcd');
In this line, the result is 'd' but, I can't understand why 'd' is come out.
I tried to look other memories. In this situation, I found other memories have all alphabets.
Please explain me why result is 'd' and why other memories have all alphabets.
Thank you.

like image 543
Tenny Avatar asked May 28 '26 14:05

Tenny


2 Answers

'abcd' is a multi-character constant, its value is implementation-defined.

C11 §6.4.4.4 Character constants section 10

An integer character constant has type int. The value of an integer character constant containing a single character that maps to a single-byte execution character is the numerical value of the representation of the mapped character interpreted as an integer. The value of an integer character constant containing more than one character (e.g., 'ab'), or containing a character or escape sequence that does not map to a single-byte execution character, is implementation-defined. If an integer character constant contains a single character or escape sequence, its value is the one that results when an object with type char whose value is that of the single character or escape sequence is converted to type int.

A common implementation gives 'abcd' a value of 'a' * 256 * 256 * 256 + 'b' * 256 * 256 + 'c' * 256 + 'd' (1633837924), you can check its value in your implementation by printing it using "%d". Although legal C, it's rarely used in practice.

like image 183
Yu Hao Avatar answered May 31 '26 06:05

Yu Hao


Your code is wrong. When you compile it with a recent GCC compiler enabling warnings with

gcc -Wall -Wextra u.c

you get

 u.c: In function 'main':
 u.c:5:20: warning: multi-character character constant [-Wmultichar]
      printf("%c\n", 'abcd');
                     ^
 u.c:6:20: warning: multi-character character constant [-Wmultichar]
      printf("%p\n", 'abcd');
                     ^
 u.c:6:5: warning: format '%p' expects argument of type 'void *', but argument 2 has type 'int' [-Wformat=]
      printf("%p\n", 'abcd');
      ^

Technically, you are in the awful undefined behavior case (and unspecified behavior for the multi-character constants), and anything could happen with a standard compliant implementation.

I never saw any useful case for multi-character constants like 'abcd'. I believe they are useless and mostly are an historical artefact.

To explain what really happens, it is implementation specific (depends upon the compiler, the processor, the optimization flags, the ABI, the runtime environment, ....) and you need to dive into gory details (first look at the generated assembler code with gcc -fverbose-asm -S) and into your libc particular printf implementation.

As a rule of thumb, you should improve your code to get rid of every warnings your compiler is able to give you (your compiler is helpful in warning you). They are few subtle exceptions (but then you should comment your code about them).

like image 45
Basile Starynkevitch Avatar answered May 31 '26 06:05

Basile Starynkevitch