The first option in my mind is that the output should be "-1". I think you would agree with me. However, how about the output on the 64-bit system? We expect the same output -1 and let's see if this is the case. Let's test it:

#xlc -q64 a.c -qlanglvl=extended
#./a.out
4294967295

Here the output is "4294967295" rather than "-1". How that comes?

Don't worry, maybe we missed sth? Let's see the following code before we can answer the question:

"char dt = '\1'; -dt;"

For this code block, we need to verify whether the variable "dt" is signed or unsigned. Let's see how 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 define signed or unsigned for type char. Let's see how the XL compiler documentation 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."

From this, we know that in XL compilers, the type char is unsigned by default. We can use the -qchars option to change the default behavior. Let's test it:

#xlc -q64 a.c -qlanglvl=extended -qchar=signed
#./a.out
-1

Great! That explains the above behavior and get the point, I think.

Wait a minute... let's hold on. Do you really understand it? Maybe not. Let's look at another question. Regardless of whether we use -qchars, we can still get "-1" if we do not specify -qlanglvl=extended. Why?

#xlc -q64 a.c
#./a.out
-1

And, the following code prints "-1" as well, even -qlanglvl=extended is used.

"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."

Meanwhile, let's pay attention to the notes below:

-qupconv (C only)

Specifies whether the unsigned specification is preserved when integral promotions are performed.

Defaults
-qnoupconv for all language levels except classic or extended
-qupconv when the classic or extended language levels are in effect

We can see that the -qupconv (-qlanglvl=extended）option impacts the unsigned specification processing during integral promotion. When -qlanglvl=extended or -qupconv is in effect, unsigned specification is preserved.

3. We all know that the unsigned specification is determined by the target type when the type cast is performed. So, back to the preceding code:

the type of dt is unsigned int. According to #2 above, no need to be promoted, so the type of "-dt" is unsigned int as well. As a result, the value of -dt is 0xFFFFFFFF in binary. It is then cast to type long and assigned to dt, so the result of 0x00000000FFFFFFFF is 4294967295.

tdt = -dt. Unsigned char needs to be promoted to unsigned int when -qupconv or -qlanglvl=extended is in effect; otherwise, promoted to int.

When -qupconv or -qlanglvl=extended is effect, "tdt=-dt" is equivalent to "(long)( (unsigned int) (-((unsigned int)td)) )" and the result is 4294967295. Whereas when -qnoupconv (with other langlvl） is in effect, "tdt=-dt" is equivalent to "(long)( ( int) (-(( int)dt)) )" and the result is -1.

At this point, we can finally answer "d=1,-d==?". The result relies on operand type, possible type conversion, and the compiler options.