Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why is sizeof a char literal not the same as sizeof(char)? [duplicate]

The program

#include <stdio.h>
int main(void) {
    printf("sizeof( char ) = %zu, sizeof 'a' = %zu.\n", sizeof( char ), sizeof 'a' );
    return 0;
}

outputs the following:

sizeof( char ) = 1, sizeof 'a' = 4.

I'm compiling with gcc (clang gives the same result) and these flags:

gcc -Wall -Wextra -Wswitch -pedantic -ansi -std=c11 -DDEBUG -ggdb3 -o

Section 6.5.3.4 paragraph 4 of the specification at http://www.open-std.org/jtc1/sc22/wg14/www/docs/n1570.pdf says

4 When sizeof is applied to an operand that has type char, unsigned char, or signed char, (or a qualified version thereof) the result is 1.

So I would expect sizeof the operand 'a' to be 1 because the type of 'a' is char, or is it being automatically "promoted" to an int, or something similar? (I notice that if I cast 'a' to char then sizeof( (char)'a' ) is 1).

Or am I looking at the wrong standard?

like image 929
Lianne Connolly Avatar asked Nov 02 '21 13:11

Lianne Connolly


2 Answers

In C opposite to C++ integer character constants (literals) have the type int.

So the value of the expression sizeof( 'a' ) is equal to the value of the expression sizeof( int ). While sizeof( char ) is always equal to 1.

From the C Standard (6.5.3.4 The sizeof and alignof operators)

4 When sizeof is applied to an operand that has type char, unsigned char, or signed char, (or a qualified version thereof) the result is 1...

and (6.4.4.4 Character constants)

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.

Pay attention to that usually objects of the type char used in operations as operands or in expressions are converted to the type int due to the integer promotions.

like image 86
Vlad from Moscow Avatar answered Nov 16 '22 22:11

Vlad from Moscow


Character constants (or more accurately, an integer character constant) have type int.

Section 6.4.4.4p2 of the C standard describes Character Constants:

An integer character constant is a sequence of one or more multibyte characters enclosed in single-quotes, as in 'x'. A wide character constant is the same, except prefixed by the letter L, u, or U. With a few exceptions detailed later, the elements of the sequence are any members of the source character set; they are mapped in an implementation-defined manner to members of the execution character set

And the semantics, which include a description of the type are first described in paragraph 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

like image 24
dbush Avatar answered Nov 16 '22 23:11

dbush