Question: d = 1,-d =?
Let's look at the answer:
-----------------------------
What is the output of the following code?
Int main (){
Char dt = '\ 1 ';
Long tdt;
Tdt =-dt;
Printf ("% ld \ n", tdt );
}
My first response is that the output should be "-1". I think so too. However, what is output on a 64-bit system? I also expect "-1". Let's see if this is the case.
Let's test it.
# Xlc-q64 a. c-qlanglvl = extended
#./A. out
4294967295
!! The output here is "4294967295" instead of "-1". How can this happen?
Don't worry. Maybe we missed something?
Before answering the above questions, let's look at the following code segment:
"Char dt = '\ 1';-dt ;"
For this code segment, do we know whether the dt variable is signed or unsigned? C
Let's take a look at what the C language standard says:
The implementation shall define char to have the same range, representation, and behavior as either signed char or unsigned char.
That is to say, the standard does not require the symbol of the char type variable. Let's look at XL compiler documentation http://publib.boulder.ibm.com/infocenter/comphelp/v111v131/topic/com.ibm.xlc111.aix.doc/language_ref/ch.html
It says:
By default, char behaves like an unsigned char. To change this default, you can use the-qchars option or the # pragma chars directive. See-qchars for more information.
In XL compiler, char is unsigned by default. We can use-qchars to change this default behavior. Let's test:
# Xlc-q64 a. c-qlanglvl = extended-qchar = signed
#./A. out
-1
That's great. We seem to understand.
Don't worry. Now you have to Hold it. Do you really understand? Maybe not. Let's look at another question:
You can get "-1" even if you don't use-qlanglvl = extended.-qchars is not used. Why? As follows:
-------------
# Xlc-q64 a. c
#./A. out
-1
--------------
The following code also prints "-1", even if-qlanglvl = extended:
--------------
Int main (){
Unsigned char dt = '\ 1 ';
Long tdt = dt;
Tdt =-tdt;
Printf ("% ld \ n", tdt );
}
# Xlc-q64 a. c-qlanglvl = extended;./a. out
-1
--------------
Why is the output of the following code 4294967295 again "?
Int main (){
Unsigned dt = '\ 1 ';
Long tdt;
Tdt =-dt;
Printf ("% ld \ n", tdt );
}
There seems to be something deep here. Let's take a closer look at the following points:
* Subtraction Operator
* Integer escalation rules (integral promotion)
* Type cast)
########################################
Let's look at it one by one:
1. subtraction operator behavior: iso c ++ standard description
The result of the unary-operator is the negative of its (promoted) operand. The integer promotions are saved med on the operand, and the result has the promoted type.
Therefore, the operation result type of the minus sign operator depends on the type after the operand is upgraded.
In the XL compiler documentation, there are similar statements:
Http://publib.boulder.ibm.com/infocenter/comphelp/v111v131/topic/com.ibm.xlc111.aix.doc/language_ref/artnege.html
Unary minus operator-: The result has the same type as the operand after integral promotion.
2. Integer escalation rules
The following information is displayed in the XL document.
Http://publib.boulder.ibm.com/infocenter/comphelp/v111v131/topic/com.ibm.xlcpp111.aix.doc/language_ref/integer_float_promotion.html? Resultof = % 22% 70% 72% 6f % 6d % 6f % 74% 65% 64% 22% 20% 22% 70% 6f % 6d % 6f % 72% 74% 20
If an integer type other than wchar_t, bit field, and Boolean can be represented by the int type and its rank is lower than the rank of int, the integer type can be converted to the int type. otherwise, the integer type can be converted to the unsigned int type.
At the same time, we noticed the following descriptions of XL:
**************************************** *************************
-Qupconv (C only)
Specifies whether the unsigned specification is preserved when integral promotions are saved med.
Ults
-Qnoupconv for all language levels extends t classic or extended
-Qupconv when the classic or extended language levels are in effect
**************************************** *******************
It can be seen that option-qupconv (-qlanglvl = extended) affects the processing behavior of the symbol bit when the integer is upgraded. If-qlanglvl = extended or-qupconv is specified, the symbol bit is reserved for integer increase.
3. We know that the mandatory class-to-class conversion is a symbol depending on the target type.
As a result, let's look back at the above Code:
----------------------
Int main (){
Unsigned char dt = '\ 1 ';
Long tdt = dt; // The type that is forcibly converted to tdt is still "1"
Tdt =-tdt; // The result type is still long, so the result is-1
Printf ("% ld \ n", tdt );
}
--------------------------
For
Int main (){
Unsigned dt = '\ 1 ';
Long tdt;
Tdt =-dt; // = equivalent to => (long) (unsigned int) (-(unsigned int) u )))
Printf ("% ld \ n", tdt );
}
The dt type is unsigned int and does not need to be upgraded (according to the above 2nd). Therefore, the "-dt" type is still "unsigned int ". therefore, the value of-dt is "0 xFFFFFFFF" (in binary format), which is then forcibly converted to the long type and paid to dt. Therefore, 0x000000000000ffffffff is 4294967295.
For
Int main (){
Unsigned char dt = '\ 1 ';
Long tdt;
Tdt =-dt;
Printf ("% ld \ n", tdt );
}
Tdt =-dt; unsigned char must be upgraded first to "unsigned int" If-qupconv or-qlanglvl = extended; otherwise, it must be upgraded to "int"
Therefore, when-qupconv/-qlanglvl = extended: tdt =-dt is equivalent to "(long) (unsigned int) (-(unsigned int) td )))". The result is 4294967295.
In-qnoupconv (Other langlvl), it is equivalent to "(long) (int) (-(int) dt)" and the result is-1.
So far, we can finally answer "d = 1,-d = ?" . The result depends on the type of the operand, possible type conversion, and compiler options.
Author: Zhang peili