为什么即使使用-O0标志,clang也会优化我的数组?

3

我正在尝试使用GDB调试以下C程序:

// Program to generate a user specified number of 
// fibonacci numbers using variable length arrays
// Chapter 7  Program 8   2013-07-14

#include <stdio.h>

int main(void)
{
    int i, numFibs;
    printf("How many fibonacci numbers do you want (between 1 and 75)?\n");
    scanf("%i", &numFibs);

    if (numFibs < 1 || numFibs > 75)
    {
        printf("Between 1 and 75 remember?\n");
        return 1;
    }

    unsigned long long int fibonacci[numFibs];

    fibonacci[0] = 0;  // by definition
    fibonacci[1] = 1;  // by definition

    for(i = 2; i < numFibs; i++)
        fibonacci[i] = fibonacci[i-2] + fibonacci[i-1];

    for(i = 0; i < numFibs; i++)
        printf("%llu ", fibonacci[i]);

    printf("\n");

    return 0;
}

我遇到的问题是在尝试使用以下命令编译代码时: clang -ggdb3 -O0 -Wall -Werror 7_8_FibonacciVarLengthArrays.c 当我试图对创建的a.out文件运行gdb并逐步执行程序时,无论何时在fibonacci[]数组声明后键入"info locals",结果会显示>(直到我的for循环的第一次迭代之后),这导致fibonacci在程序的其余部分保持地址0xbffff128(但解引用该地址并不包含任何有意义的数据)。
我只是困惑为什么clang似乎在使用-O0标志时优化了这个数组?
我可以使用gcc编译此代码,并在使用GDB时正常显示值。您有什么想法吗?
谢谢。

(不)幸的是,-O0 并不意味着“关闭所有优化”。嗯,它确实是这样,但 clang 似乎并不在意。有些优化是无法关闭的,例如 1 + 2 将始终被常量折叠,无论如何。显然,这就是其中之一。 - user529758
3个回答

3
你没有提到你使用的clang版本。我尝试过3.2版本和最近的SVN安装(3.4)。
两个版本生成的代码看起来非常相似,但调试信息不同。Clang 3.2(来自默认的Ubuntu 13.04安装)在我尝试在gdb中检查斐波那契数列时会产生错误:
fibonacci = <error reading variable fibonacci (DWARF-2 expression error: DW_OP_reg operations must be used either alone or in conjunction with DW_OP_piece or DW_OP_bit_piece.)>

在使用clang 3.4编译的代码中,一切都运行良好。在两种情况下,数组并没有被“优化掉”,它显然是在堆栈上分配的。因此,我怀疑你看到的奇怪现象更多地与调试信息的发出有关,而不是实际代码。

2

1

clang并没有对数组进行任何"优化"!该数组被声明为堆栈上的可变长度数组,因此在其声明到达时必须显式分配(使用类似于alloca()的技术)。直到该过程完成后,数组的起始地址才是未知的。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接