3

I know multi-character character constant stated as int. and I know that the value of it is compiler dependent. but my question is when I store a multi-character character constant in a char variable it will behave in a different way.

#include <iostream>

int main() {
    std::cout << 'asb';
    return 0;
}

output: 6386530


#include <iostream>

int main() {
    char a = 'asb';
    std::cout << a;
    return 0;   
}

output: b

StoryTeller - Unslander Monica
  • 165,132
  • 21
  • 377
  • 458
  • Wouldn't it be clearer to write portable code that shows your intent and doesn't cause warnings? – Tom Blodget Jul 02 '18 at 15:44
  • Does this answer your question? [Multi-character constant warnings](https://stackoverflow.com/questions/7755202/multi-character-constant-warnings) – phuclv Apr 10 '22 at 09:13

3 Answers3

3

Case 1 : You are getting 'a'*256²+'s'*256+'b' = 6386530 because 'a' = 97, 's' = 115, 'b' = 98

cf. Ascii table

'asb' is interpreted as an integer.

typeid('asb').name()[0] == 'i' && sizeof('asd') == 4;

An integer is 32 bits, and you can store 'asb' (24bits) in an integer. That's why std::cout interprets it as an integer and display 6386530

Note that also:

  typeid('xxxxabcd').name()[0] == 'i' && sizeof('xxxxabcd') == 4;

but 'xxxxabcd' is represented by 64-bits, so 32-bits are lost.

std::cout << 'xxxxabcd';
std::cout << 'abcd';

would print the same thing.


Case 2 : 'asb' is interpreted as an integer and you cast it into a char (8-bits). As @BenjaminJones pointed out, only the last 8-bits (98=='b') are saved. And std::cout interprets it as a char so it displays 'b'.


Anyway, both case provokes compilation warning such as :

warning: multi-character character constant [-Wmultichar] 
warning: multi-character character constant [-Wmultichar] In function 'int main()'
warning: overflow in implicit constant conversion [-Woverflow]

I guess the behavior depends on the compiler.

user30701
  • 308
  • 1
  • 6
  • actually I didn't know the method of calculating. is that 256 the number of ASCII characters? is the calculation in base of 256? I'll appreciate for more information or some resource – oldMCdonald Jul 02 '18 at 12:33
  • @oldMCdonald, I completed my answer. Sry, no documentation, I just wrote a piece of code to understand this behaviour. ASCII table is extended to 256 chars, but it used to be 128. Also, there is no base 256 "calculation", it's a base 256 interpretation. – user30701 Jul 02 '18 at 14:35
  • 1
    Doesn't your answer assume a little-endian architecture? (As well as CHAR_BITS=8, but that doesn't matter until you overflow the `int`.) – Tom Blodget Jul 02 '18 at 15:37
  • yes [the behavior is implementation-defined](https://stackoverflow.com/q/7755202/995714) so using it is discouraged – phuclv Apr 10 '22 at 09:13
1

You don't store the value of the multi-char constant as is. You convert the value into another value that fits in the range of a char. Since you are also printing the value via entirely different overloads of operator<< (the one for char instead of the one for int), it stands to reason the output would be different on account of that too.

StoryTeller - Unslander Monica
  • 165,132
  • 21
  • 377
  • 458
1

In your second example, the literal is an int that gets converted to a char. Therefore, there are a few implementation specific issues here:

  • Interpretation of a multi-character literal
  • Whether char is signed or unsigned
  • Conversion from an int to an signed char (if char is signed)

It appears that what is happening is that 'asb' is getting interpreted as 6386530, and then truncated according to the rules for conversion from int to an unsigned char. In other words, 6386530 % 256 == 97 == 'b'.

Ben Jones
  • 652
  • 6
  • 21