从size_t转换为int

Dav*_*eri 0 c assembly type-conversion

遵循这个主题 ......

对于这段代码:

#include <stdio.h>

int main(void)
{
    int i;
    size_t u;

    for (i = 0; i < 10; i++) {
        u = (size_t)i;
        printf("i = %d, u = %zu\n", i, u);
    }
    return 0;
}
Run Code Online (Sandbox Code Playgroud)

程序集中的输出是:

编辑:用-O2编译

    .file   "demo.c"
    .section    .rodata.str1.1,"aMS",@progbits,1
.LC0:
    .string "i = %d, u = %zu\n"
    .section    .text.startup,"ax",@progbits
    .p2align 4,,15
    .globl  main
    .type   main, @function
main:
.LFB3:
    .cfi_startproc
    pushq   %rbx
    .cfi_def_cfa_offset 16
    .cfi_offset 3, -16
    xorl    %ebx, %ebx
    .p2align 4,,10
    .p2align 3
.L2:
    movq    %rbx, %rdx
    movl    %ebx, %esi
    xorl    %eax, %eax
    movl    $.LC0, %edi
    addq    $1, %rbx
    call    printf
    cmpq    $10, %rbx
    jne .L2
    xorl    %eax, %eax
    popq    %rbx
    .cfi_def_cfa_offset 8
    ret
    .cfi_endproc
.LFE3:
    .size   main, .-main
    .ident  "GCC: (Debian 4.7.2-5) 4.7.2"
    .section    .note.GNU-stack,"",@progbits
Run Code Online (Sandbox Code Playgroud)

转换是否u = (size_t)i;消耗额外的周期?

Mat*_*son 5

是的,因为代码已发布,当然.您的转换位于:

movl    -4(%rbp), %eax
cltq
movq    %rax, -16(%rbp)
Run Code Online (Sandbox Code Playgroud)

当然,这段代码没有经过优化,所以这不是一个非常公平的比较.如果你用优化编译,编译器可能会意识到值始终为正,只是做无论从任何寄存器保存一个举动i,以%rdx保持第三个参数.

编辑:

如所怀疑的,优化代码中基本上没有开销.在这种情况下,编译器转换的循环来计数u,并从中获得i从u而不是周围的其他方法,所以%rbx被用于循环,和的值i是在运用%ebx,这是低32位%rbx-所以有在这个例子中没有开销.我强调这一点,因为很可能会有其他情况下转换int为size_t将会受到惩罚.这完全取决于具体情况.