让我们看看内部 llvm 程序集。这并不难。
C++代码:
void preincrement() __attribute__((noinline));
void preincrement() {
volatile int x = 10;
volatile int y = ++x;
}
void postincrement() __attribute__((noinline));
void postincrement() {
volatile int x = 10;
volatile int y = x++;
}
int main()
{
preincrement();
postincrement();
}
生成的 LLVM 程序集(减去一些不感兴趣的前导和尾随文本):
; Function Attrs: noinline nounwind uwtable
define void @_Z12preincrementv() #0 {
%x = alloca i32, align 4
%y = alloca i32, align 4
store volatile i32 10, i32* %x, align 4
%1 = load volatile i32* %x, align 4
%2 = add nsw i32 %1, 1
store volatile i32 %2, i32* %x, align 4
store volatile i32 %2, i32* %y, align 4
ret void
}
; Function Attrs: noinline nounwind uwtable
define void @_Z13postincrementv() #0 {
%x = alloca i32, align 4
%y = alloca i32, align 4
store volatile i32 10, i32* %x, align 4
%1 = load volatile i32* %x, align 4
%2 = add nsw i32 %1, 1
store volatile i32 %2, i32* %x, align 4
store volatile i32 %1, i32* %y, align 4
ret void
}
; Function Attrs: nounwind uwtable
define i32 @main() #1 {
tail call void @_Z12preincrementv()
tail call void @_Z13postincrementv()
ret i32 0
}
在这里我们可以很清楚地看到唯一的区别:在后增量版本中,我们使用原始值,而不是升级后的值。
在这两种情况下,我们只使用传统的添加操作码来完成实际工作。