在内存/编译中会发生什么?

时间:2014-04-14 03:27:50

标签: c memory stack printf

代码:

#include <stdio.h>

int main(int argc, char *argv[])
{
    //what happens?
    10*10;

    //what happens?
    printf("%d", 10*10);   

    return 0;
}

这两行的内存/编译会发生什么。它存储了吗? (10 * 10)

6 个答案:

答案 0 :(得分:5)

声明

10*10;

无效。编译器可以选择不为此语句生成任何代码。另一方面,

printf("%d", 10*10);

10*10的结果传递给printf函数,该函数将结果(100)打印到标准输出。

答案 1 :(得分:2)

问你的编译器!他们可能都会有一个有趣的答案。

以下是gcc -c noop.c -o noop.o -g3必须说的内容(我通过objdump --disassemble --source运行目标代码以生成下面的输出):

#include <stdio.h>

void test_code()
{
   0:   55                      push   %rbp
   1:   48 89 e5                mov    %rsp,%rbp
    10*10;

    //what happens?
    printf("%d", 10*10);
   4:   b8 00 00 00 00          mov    $0x0,%eax
   9:   be 64 00 00 00          mov    $0x64,%esi
   e:   48 89 c7                mov    %rax,%rdi
  11:   b8 00 00 00 00          mov    $0x0,%eax
  16:   e8 00 00 00 00          callq  1b <test_code+0x1b>
}
  1b:   5d                      pop    %rbp
  1c:   c3                      retq   

我的编译器将10*10传递给printf并在编译时将其相乘,然后将结果用作immediate$064,也就是十进制的100)并将其放入用于printf的注册表中:

mov    $0x64,%esi

未分配给任何标识符的10*10表达式被删除。请注意,可能可能在某处找到一些决定执行此计算并将其存储在寄存器中的编译器。

答案 2 :(得分:0)

在第一个问题中没有,像这样的表达式由编译器转换为值,并且由于您没有分配给变量它什么都不做,编译器会将其删除。

在第二个中,值100传递给printf。

你必须注意,这取决于编译器要做什么,在其他人将被预先制定,在其他人将执行操作。

答案 3 :(得分:0)

在第一种情况下,由于操作不在任何地方使用,编译器可能会优化代码而根本不执行指令。

在第二种情况下,使用寄存器(堆栈)计算该值并将其打印到控制台,而不是存储在其他任何位置。

答案 4 :(得分:0)

10*10;

未存储。我的猜测是它应该给编译器警告或错误。

printf("%d", 10*10);

应该打印:100。计算(10 * 10)的值(最有可能是编译器,而不是在运行时),然后通过将值(100)推送到堆栈上来发送到printf()。因此,该值存储在堆栈中,直到printf()返回时恢复原始(pre-call-to-printf())堆栈帧。

答案 5 :(得分:0)

C标准描述了程序在抽象机器上的作用。

但要真正决定实际发生了什么,你需要始终牢记一条规则:如果没有违反约束,编译器必须只输出具有可观察行为的代码&#34;好像&#34; 它做了你说的话。
明确允许使用任何其他方式来实现它所支持的结果。

这条规则通俗地称为&#34; as-if&#34; -rule。

因此,您的程序等于例如:

#include <stdio.h>
int main(void) {
    fputs("100", stdout);
}

或者

#include <stdio.h>
int main(void) {
    putchar('1');
    putchar('0');
    putchar('0');
}