【发布时间】:2015-10-27 11:41:56
【问题描述】:
假设我有这个文件:
[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 编译和调试:
[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 大于 0xfffffffffffffffd 而 0xfffffffffffffffd 显然大于 0x2。可能是存储有符号位或其他东西,但它需要在我的系统中检查 long long 最大大小(0x7fffffffffffffff)才能知道 0xffffffffffffffd 有符号位?
似乎 gdb 无法做到这一点,那么我该如何在汇编/二进制级别调试这种逻辑表达式(if 2 > -3)?
[UPDATE] 下面是我在 Fedora 21 中安装的 gcc 配置选项。
[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 的 fold-constants.c 或其他源文件中的表现并没有太大帮助。在这种特殊情况下,逻辑操作如何执行/涉及? gcc 在执行逻辑操作之前如何检测符号位?
【问题讨论】:
-
编译器知道
2将始终大于-3,因此它可以完全优化整个条件(和另一个分支)。尝试使用-O0标志编译,它告诉GCC 根本不优化,我不知道它是否会停止那个简单表达式的constant folding。 -
我做了-O0,但这是gcc手册中描述的默认选项,仍然相同。
-
至于
0x00000002如何大于0xfffffffd,阅读了解two's complement。 -
经过一番搜索,似乎GCC中无法禁用常量折叠,所以只要你使用文字值,你就很不走运。尝试声明和使用变量,可能标记为
volatile。 -
启用编译器警告并注意它们! gcc 应该已经抱怨
else路径不可访问。
标签: c debugging gcc gdb logical-operators