The book told that writing:
static unsigned int foo;
and later
if( foo > 0)
{
is wrong, and it will leads to a hard to find bug. Why is that?
In the x86 assembly language programming there are signed arithmetic instructions and also unsigned arithmetic instructions, JG JL <-signed arithmetic JB JA <- unsigned instructions.
So the compiler can just assemble that if (foo >0 ) statement with unsigned instructions isn't it? Can somebody explain how it works in advance?
Is that instruction wrong? Or if there is a difference in "C" where "C++" is strict 开发者_高级运维in that case? Please explain.
Here we are comparing a unsigned variable with a immediate value. What is happening inside the compiler actually in this case?
And when we compare a signed value with unsigned value what happens? Then what instructions will compiler choose, signed instructions or unsigned instructions?
--thanks in advance--
This question should not be answered on the level of assembler but stil on c/c++ language level. On most architectures it is impossible to compare signed and unsigned numbers, and c/c++ does not facilitate such comparisons. Instead there are rules about converting one of the operands to type of the other in order to compare them - see for example aswers to this question
About comparing to literals - typical way of doing it (as you did) is not wrong, but you can do it better - according to c++ standard:
2.13.1.1 An integer literal is a sequence of digits that has no period or exponent part. An integer literal may have a prefix that specifies its base and a suffix that specifies its type. The lexically first digit of the sequence of digits is the most significant. A decimal integer literal (base ten) begins with a digit other than 0 and con- sists of a sequence of decimal digits. An octal integer literal (base eight) begins with the digit 0 and con- sists of a sequence of octal digits.22) A hexadecimal integer literal (base sixteen) begins with 0x or 0X and consists of a sequence of hexadecimal digits, which include the decimal digits and the letters a through f and A through F with decimal values ten through fifteen. [Example: the number twelve can be written 12, 014, or 0XC. ]
2.13.1.2 The type of an integer literal depends on its form, value, and suffix. If it is decimal and has no suffix, it has the first of these types in which its value can be represented: int, long int; if the value cannot be repre- sented as a long int, the behavior is undefined. If it is octal or hexadecimal and has no suffix, it has the first of these types in which its value can be represented: int, unsigned int, long int, unsigned long int. If it is suffixed by u or U, its type is the first of these types in which its value can be repre- sented: unsigned int, unsigned long int. If it is suffixed by l or L, its type is the first of these types in which its value can be represented: long int, unsigned long int. If it is suffixed by ul, lu, uL, Lu, Ul, lU, UL, or LU, its type is unsigned long int.
If you want to be sure about your literal type (and therefore comaprison type) add described suffixes to ensure right type of literal.
It is also worth noticing that literal 0
is actually not decimal but octal - it doesn't seem to change anything, but is quite unexpected - or am I wrong?
To summarize - it is not wrong to write code like that, but you should remeber that in certain conditions in might behave counter-intuitive (or at least counter-mathematical ;)
精彩评论