静态 unsigned int foo 以及以后的 if ( foo >0 )?

发布于 2024-12-05 03:59:34 字数 493 浏览 0 评论 0原文

书上说写:

static unsigned int foo;

andlater

if( foo > 0)
{

是错误的,而且会导致很难发现的bug。 这是为什么?

在 x86 汇编语言编程中,有符号算术指令和 还有无符号算术指令, JG JL <-有符号算术 JB JA <-无符号指令。

因此编译器可以用无符号指令组装 if (foo >0 ) 语句 不是吗?有人可以提前解释一下它是如何工作的吗?

那个指令有错吗?或者,如果“C”中存在差异,而“C++”在以下方面是严格的: 那件事呢?请解释一下。

在这里,我们将无符号变量与立即值进行比较。里面发生了什么 编译器实际上在这种情况下吗?

当我们比较有符号值和无符号值时会发生什么?那么编译器会选择什么指令,有符号指令还是无符号指令?

- 提前致谢 -

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

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

圈圈圆圆圈圈 2024-12-12 03:59:34

这个问题不应该在汇编程序层面上回答,而应该在c/c++语言层面上回答。在大多数体系结构上,无法比较有符号数和无符号数,并且 c/c++ 不方便进行此类比较。相反,存在有关将其中一个操作数转换为另一个操作数的类型以便进行比较的规则 - 例如参见 这个问题

关于与文字进行比较 - 典型的做法(就像你所做的那样)并没有错,但你可以做得更好 - 根据 c++ 标准:

2.13.1.1 整数文字是没有句点的数字序列
或指数部分。整数文字可能有一个前缀,指定
它的基数和指定其类型的后缀。词汇第一
数字序列中的数字是最重要的。一位小数
整数文字(以 10 为基数)以 0 以外的数字开头并且 con-
由十进制数字序列组成。八进制整数字面量(基数
八)以数字 0 开头,由八进制序列组成
digits.22) 以 0x 开头的十六进制整数字面量(基数为 16)
或 0X,由一系列十六进制数字组成,其中包括
十进制数字和字母 a 到 f 和 A​​ 到 F
十进制值十到十五。 [示例:数字十二可以是
写为 12、014 或 0XC。 ]

2.13.1.2 整数文字的类型取决于其形式、值、
和后缀。如果它是十进制且没有后缀,则它具有第一个
可以表示其值的这些类型:int、long int;如果
该值不能表示为 long int,其行为是
不明确的。如果它是八进制或十六进制并且没有后缀,则它具有可以表示其值的第一种类型:int,
无符号整型、长整型、无符号长整型。如果后缀为 u 或
U,它的类型是这些类型中的第一个,其中它的值可以是
表示:unsigned int、unsigned long int。如果后缀是l
或 L,它的类型是这些类型中的第一个,其中它的值可以是
表示:long int、unsigned long int。如果以ul、lu为后缀,
uL、Lu、Ul、lU、UL 或 LU,其类型为 unsigned long int。

如果您想确定您的文字类型(以及比较类型),请添加描述的后缀以确保文字类型正确。

还值得注意的是,文字 0 实际上不是十进制而是八进制 - 它似乎没有改变任何东西,但很出乎意料 - 或者我错了?

总而言之 - 编写这样的代码并没有错,但您应该记住,在某些情况下,可能会表现出反直觉的行为(或者至少是反数学的;)

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 ;)

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文