编译时函数 ptr 取消引用

标签 c gcc clang

您好,我有以下设计,我想知道通常 C 编译器(gcc 或 clang)是否会尝试在编译时解析函数指针,还是会一直保留到运行时。

在测试.h中:

typedef struct array_ {
  size_t size;
  void *array;
  size_t (*get_size)(struct array_ *);
} array_t;

static inline size_t
get_size (array_t *A) {
  return A->get_size(A);
}

在测试.c中:

#include <stdio.h>
#include <stdlib.h>
#include "test.h"

static size_t _get_size (array_t *A) {
  return A->size;
}

int main(void)
{
  array_t *A = malloc(sizeof(array_t));

  A->size = 3;
  A->array = (int[]){1,2,3};
  A->get_size = _get_size;

  printf("%llu\n", A->get_size(A));
  printf("%llu\n", get_size(A));
  return 0;
}

我的问题是——A->get_size(A) 会在编译时解析为 _get_size(A) 还是 A->size? A->get_size() 总是比 get_size(A) 更有效还是它们编译成几乎相同的东西?

我意识到我问的是编译器会做什么或不会做什么,这取决于编译器和其他因素(例如优化级别),但总的来说是否有答案,或者它是否仅取决于太多因素?

编辑:为清楚起见,我省略了错误检查。

编辑:“gcc -S”代码。我认为正在取消引用指针。

main:
.LFB4:
        .cfi_startproc
        pushq   %rbp
        .cfi_def_cfa_offset 16
        .cfi_offset 6, -16
        movq    %rsp, %rbp
        .cfi_def_cfa_register 6
        subq    $32, %rsp
        movl    $24, %edi
        call    malloc
        movq    %rax, -24(%rbp)
        movq    -24(%rbp), %rax
        movq    $3, (%rax)
        movl    $1, -16(%rbp)
        movl    $2, -12(%rbp)
        movl    $3, -8(%rbp)
        movq    -24(%rbp), %rax
        leaq    -16(%rbp), %rdx
        movq    %rdx, 8(%rax)
        movq    -24(%rbp), %rax
        movq    $_get_size, 16(%rax)
        movq    -24(%rbp), %rax
        movq    16(%rax), %rax
        movq    -24(%rbp), %rdx
        movq    %rdx, %rdi
        call    *%rax
        movq    %rax, %rsi
        movl    $.LC0, %edi
        movl    $0, %eax
        call    printf
        movq    -24(%rbp), %rax
        movq    %rax, %rdi
        call    get_size
        movq    %rax, %rsi
        movl    $.LC0, %edi
        movl    $0, %eax
        call    printf
        movl    $0, %eax
        leave
        .cfi_def_cfa 7, 8
        ret
        .cfi_endproc

最佳答案

由于您只是在使用函数指针的上方一行分配了函数指针,因此像 gcc 和 clang 这样的优秀编译器应该足够聪明,可以在编译时解析它。但是,一旦您开始在不同文件中的不同函数之间传递指向该结构的指针,它们几乎肯定不会在编译时解析它。

如果您想如此详细地了解您的编译器,您应该开始查看反汇编 list 。

如果您想在示例代码中使用类似的语法并高效地编译它,C++ 是一种很好的语言。

关于编译时函数 ptr 取消引用,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/27335308/

相关文章:

c - 将文件中的数字以 6 为一组读取到 2x3 矩阵中?

c - ffmpeg:加载图像的函数

css - 有没有用 C 语言编写的 CSS 选择器引擎?

gcc - Cuda Clang 和 OS X Mavericks

gcc - 该程序无法找到正确版本的 glibc/libstdc++,尽管它是静态链接的

c - OSX/Clang 版本的 __progname 获取可执行文件的绝对路径?

c - 使用 dlsym 并将 -ldl 添加到标志

c - OSX 10.11 上的 OpenMP 支持,gcc 错误 "file omp.h not found"

installation - 在 ubuntu 12.04 lts 上安装 llvm-3.4

c++ - 在 NetBeans 中集成 Clang?