"char" memory layout problem!


 
Thread Tools Search this Thread
Top Forums Programming "char" memory layout problem!
# 1  
Old 08-17-2012
"char" memory layout problem!

In the following code, why the final result of "usC=cA+(char)ucB;" is 0xFF00?
In my opioion the memory layout of cA is "10000000" and
(char)cB is "10000000",usC type is unsigned short ,so the result should be "100000000" ,the 0x100.
Please help tell me what is wrong? Thanks!!Smilie

Code:
#include<stdio.h>

int main(int argc,char *argv[])
{

    char cA;
    unsigned char ucB;
    unsigned short usC;
    cA = 128;    
    ucB = 128;

    usC = cA+ucB;
    printf("0x%x\n",usC);

    usC=cA+(short)ucB;
    printf("0x%x\n",usC);

    usC = (unsigned char)cA+ucB;
    printf("0x%x\n",usC);

    usC=cA+(char)ucB;
    printf("0x%x\n",usC);


    return 0;

}

# 2  
Old 08-17-2012
Quote:
Originally Posted by micky.zhou
why the final result of "usC=cA+(char)ucB;" is 0xFF00?
In my opioion the memory layout of cA is "10000000" and
(char)cB is "10000000",usC type is unsigned short ,so the result should be "100000000" ,the 0x100.
Short version:

Integral promotion with sign extension followed by left truncation.


Long version:

Whether char is signed or unsigned depends on the implementation. Working backwards, 0xFF00 suggests that on your platform char is signed. I will also assume that on your platform char is 1 byte, short is 2 bytes, and int is 4 bytes.

Initial values:
signed char cA = 1000 0000 (0x80) (-128)
unsigned char ucB = 1000 0000 (0x80) (128)

Expression as written:
cA + (char)ucB

Arithmetic in C doesn't use anything smaller than an int. In an expression whose operands are all char or short, on a platform where char is signed, every operand is always promoted to int.

Expression as evaluated:
(int)cA + (int)(char)ucB

Before moving on to each operand's promotion to int, let's take a close look at (char) ucB.

The result of casting ucB to char is unpredictable for a couple of reasons. First, is char signed or unsigned? As mentioned earlier, that depends on the implementation. If char is unsigned, then your cast of ucB has no effect, because the original type and the new type are identical. If, however, char is signed (as appears to be the case here), you will be casting from an unsigned type to a signed type of identical width. Even though both types use the same number of bits, since a bit is lost to the sign, the new, signed type cannot represent the full range of values of the original type. Obviously, this is also true when the new type is narrower. In both cases, ANSI says that the result of converting from an unsigned type to a signed type of equal or lesser width is implementation-defined.

Your implementation seems to have left the original bit-field as is. So before and after the cast, unsigned char to signed char, ucB still holds 1000 0000 (0x80).

Before adding, each value is promoted to int. Promoting a signed type to a wider signed type is done through sign-extension. cA and ucB, now both of identical type and value, are promoted from signed char to signed int:
1000 0000 (0x80) (-128) --> 1111 1111 1111 1111 1111 1111 1000 0000 (0xffffff80) (-128)

Finally, we can perform some arithmetic:
Code:
  1111 1111 1111 1111 1111 1111 1000 0000    (0xffffff80) (-128)
+ 1111 1111 1111 1111 1111 1111 1000 0000    (0xffffff80) (-128)
=========================================
1 1111 1111 1111 1111 1111 1111 0000 0000    (0xffffff00) (-256)

The carry bit (in red) is ignored.

The assignment to usC requires converting a signed type to a narrower unsigned type, int to unsigned short. This is done through left truncation:
1111 1111 1111 1111 1111 1111 0000 0000 (0xffffff00) (-256) --> 1111 1111 0000 0000 (0xff00) (65280)

Keep in mind that due to the implementation-defined situations mentioned above, a different platform can yield different results.

Regards,
Alister

Last edited by alister; 08-17-2012 at 06:45 PM..
This User Gave Thanks to alister For This Post:
# 3  
Old 08-17-2012
Quote:
“Arithmetic in C doesn't use anything smaller than an int.”
Wow,thanks very much. It's very useful for me.
Login or Register to Ask a Question

Previous Thread | Next Thread

10 More Discussions You Might Find Interesting

1. Shell Programming and Scripting

Bash script - Print an ascii file using specific font "Latin Modern Mono 12" "regular" "9"

Hello. System : opensuse leap 42.3 I have a bash script that build a text file. I would like the last command doing : print_cmd -o page-left=43 -o page-right=22 -o page-top=28 -o page-bottom=43 -o font=LatinModernMono12:regular:9 some_file.txt where : print_cmd ::= some printing... (1 Reply)
Discussion started by: jcdole
1 Replies

2. Shell Programming and Scripting

Move a line containg "char" above line containing "xchar"

Okay, so I have a rather large text file and will have to process many more and this will save me hours of work. I'm not very good at scripting, so bear with me please. Working on Linux RHEL I've been able to filter and edit and clean up using sed, but I have a problem with moving lines. ... (9 Replies)
Discussion started by: rex007can
9 Replies

3. Programming

Small query regarding function "char * strerror(int errnum)"

As this function returns the address of the string corressponding to the errno value provided to it. Can someone please let me know where, in the memory, it could be (on freeBSD). The MAN page tells under the BUG section that "For unknown error numbers, the strerror() function will return its... (5 Replies)
Discussion started by: Praveen_218
5 Replies

4. Shell Programming and Scripting

problem with char "%"

hi all i have a problem...when i do the command my output is "n%" where n is a number but i want to delete the charater "%" . how i can delete it Thanks a lot REgards (2 Replies)
Discussion started by: FrancescoIt
2 Replies

5. Shell Programming and Scripting

awk command to replace ";" with "|" and ""|" at diferent places in line of file

Hi, I have line in input file as below: 3G_CENTRAL;INDONESIA_(M)_TELKOMSEL;SPECIAL_WORLD_GRP_7_FA_2_TELKOMSEL My expected output for line in the file must be : "1-Radon1-cMOC_deg"|"LDIndex"|"3G_CENTRAL|INDONESIA_(M)_TELKOMSEL"|LAST|"SPECIAL_WORLD_GRP_7_FA_2_TELKOMSEL" Can someone... (7 Replies)
Discussion started by: shis100
7 Replies

6. AIX

"too big" and "not enough memory" errors in shell script

Hi, This is odd, however here goes. There are several shell scripts that run in our production environment AIX 595 LPAR m/c, which has sufficient memory 14GB (physical memory) and horsepower 5CPUs. However from time to time we get the following errors in these shell scripts. The time when these... (11 Replies)
Discussion started by: jerardfjay
11 Replies

7. Solaris

significance of "+" char in SunOS "ls -l" output

Hi, I've noticed that the permissions output from "ls -l" under SunOS differs from Linux in that after the "rwxrwxrwx" field, there is an additional "+" character that may or may not be there. What is the significance of this character? Thanks, Suan (6 Replies)
Discussion started by: sayeo
6 Replies

8. UNIX for Advanced & Expert Users

A question/problem about oracle "tns listener" and "enterprise manager"

hi, I have a problem about the Oracle related components. I'm not able to find any answer yet, and waiting for your responses... Here is the configuration of my system: * an IBM P550 machine, * an AIX 5.3 running on it and * an oracle database, already installed on it. The problem (or... (1 Reply)
Discussion started by: talipk
1 Replies

9. UNIX and Linux Applications

A question/problem about oracle "tns listener" and "enterprise manager"

hi, I have * an IBM P550 machine, * an AIX 5.3 running on it and * an oracle database, already installed on it. The problem (or question of my own) is: Oracle tns listener, "CT_LISTENER", and the enterprise manager (EM) of the instance, which is uniq instance and called... (0 Replies)
Discussion started by: talipk
0 Replies

10. UNIX for Dummies Questions & Answers

Explain the line "mn_code=`env|grep "..mn"|awk -F"=" '{print $2}'`"

Hi Friends, Can any of you explain me about the below line of code? mn_code=`env|grep "..mn"|awk -F"=" '{print $2}'` Im not able to understand, what exactly it is doing :confused: Any help would be useful for me. Lokesha (4 Replies)
Discussion started by: Lokesha
4 Replies
Login or Register to Ask a Question