首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >C-逻辑表达式2> -3在gcc中的计算

C-逻辑表达式2> -3在gcc中的计算
EN

Stack Overflow用户
提问于 2015-10-27 11:41:56
回答 2查看 202关注 0票数 1

假设我有这份文件:

代码语言:javascript
复制
[xiaobai@xiaobai done_read]$ cat my_bool.c 
#include <stdio.h>
int
main() {
        if (2 > -3) {
                printf("true\n" );
        }
        else  {
                printf("false\n" );
        }
}

[xiaobai@xiaobai done_read]$

用gdb编译和调试:

代码语言:javascript
复制
[xiaobai@xiaobai done_read]$ gcc -g3 my_bool.c     
[xiaobai@xiaobai done_read]$ gdb ./a.out
GNU gdb (GDB) Fedora 7.8.2-39.fc21
...
Reading symbols from ./a.out...done.
(gdb) b *main+1
+b *main+1
Breakpoint 1 at 0x400537: file my_bool.c, line 3.
(gdb) r
+r
Starting program: .../a.out 

Breakpoint 1, 0x0000000000400537 in main () at my_bool.c:3
3       main() {
(gdb) s
+s
5                       printf("true\n" );
(gdb) s
+s
_IO_puts (str=0x4005e0 "true") at ioputs.c:34
34      {
(gdb)

它总是跳过if (2 > -3)的构造并进入printf("true\n" );

我想了解如果2> -3在二进制级别上c是如何表现的,它如何知道0x2大于0xfffffffffd,而0xfffffffd显然大于0x2。它可能是存储符号位还是其他什么的,但它需要检查系统中长的最大大小(0x7fffffffffffff)才能知道0xfffffffffd有签名位吗?

似乎gdb不可能这样做,那么如何在程序集/二进制级别调试这种逻辑表达式(if 2 > -3)呢?

下面的更新是我gcc的配置选项,安装在Fedora 21中。

代码语言:javascript
复制
[xiaobai@xiaobai note]$ gcc -v
Using built-in specs.
COLLECT_GCC=gcc
COLLECT_LTO_WRAPPER=/usr/libexec/gcc/x86_64-redhat-linux/4.9.2/lto-wrapper
Target: x86_64-redhat-linux
Configured with: ../configure --prefix=/usr --mandir=/usr/share/man --infodir=/usr/share/info --with-bugurl=http://bugzilla.redhat.com/bugzilla --enable-bootstrap --enable-shared --enable-threads=posix --enable-checking=release --enable-multilib --with-system-zlib --enable-__cxa_atexit --disable-libunwind-exceptions --enable-gnu-unique-object --enable-linker-build-id --with-linker-hash-style=gnu --enable-languages=c,c++,objc,obj-c++,fortran,ada,go,lto --enable-plugin --enable-initfini-array --disable-libgcj --with-isl=/builddir/build/BUILD/gcc-4.9.2-20150212/obj-x86_64-redhat-linux/isl-install --with-cloog=/builddir/build/BUILD/gcc-4.9.2-20150212/obj-x86_64-redhat-linux/cloog-install --enable-gnu-indirect-function --with-tune=generic --with-arch_32=i686 --build=x86_64-redhat-linux
Thread model: posix
gcc version 4.9.2 20150212 (Red Hat 4.9.2-6) (GCC) 
[xiaobai@xiaobai note]$

UPDATE2我更改了标题,因为gdb gcc是调试它的唯一方法。但是,了解2 > -3在gcc的折叠常数c或其他源文件中的表现并没有多大帮助。在这种特殊情况下,逻辑操作是如何执行/涉及的?gcc在执行逻辑操作前如何检测符号位?

EN

回答 2

Stack Overflow用户

发布于 2015-10-28 14:11:02

我认为实际的问题是“如果2> -3在二进制级别上,我想了解c是如何运行的”。要找到这一点,您可以观察编译器创建的机器代码。

根据20.html,下面的命令应该以人类可读的形式创建程序集代码

代码语言:javascript
复制
gcc -S foo.c

要了解CPU如何在二进制级别处理每个程序集命令,请阅读CPU手册。

票数 1
EN

Stack Overflow用户

发布于 2015-10-28 16:08:16

由于(2 > -3)是一个常量表达式,gdb对其进行优化。如果使用变量,则不会发生这样的情况:

代码语言:javascript
复制
#include <stdio.h>
int main() {
    int i=2, j=-3;
    if (i > j) {
            printf("true\n" );
    }
    else  {
            printf("false\n" );
    }
    return 0;
}

gdb产出:

代码语言:javascript
复制
[dbush] gdb /tmp/x1
GNU gdb (GDB) Red Hat Enterprise Linux (7.0.1-45.el5)
Copyright (C) 2009 Free Software Foundation, Inc.
License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html>
This is free software: you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law.  Type "show copying"
and "show warranty" for details.
This GDB was configured as "x86_64-redhat-linux-gnu".
For bug reporting instructions, please see:
<http://www.gnu.org/software/gdb/bugs/>...
Reading symbols from /tmp/x1...done.
(gdb) start
Temporary breakpoint 1 at 0x4004a0: file /tmp/x1.c, line 4.
Starting program: /tmp/x1
warning: no loadable sections found in added symbol-file system-supplied DSO at 0x2aaaaaaab000

Temporary breakpoint 1, main () at /tmp/x1.c:4
4           int i=2, j=-3;
(gdb) step
5               if (i > j) {
(gdb)
6                       printf("true\n" );
(gdb)
true
11      }
(gdb)

编辑:

关于如何计算(i > j),有符号整数比较与无符号整数比较是不同的。来自维基百科

比较通常用虚拟减法实现,其中检查计算机状态寄存器中的标志,但主要结果被忽略。零标志指示两个比较值是否相等。如果排他-或符号和溢出标志的值为1,则减法结果小于零,否则结果为零或更大。这些检查通常在有条件分支指令中的计算机中实现。 无符号二进制数可以通过一个简单的字典排序排序,其中位值0被定义为小于位值1。对于两个补值,最重要位的意义被颠倒(即1小于0)。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/33367070

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档