You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何让GCC知晓只读访问函数不修改内存,无需重新加载值

需求与问题

测试代码

#include <stdio.h>

typedef char*(*g)(const char*)
__attribute__((__access__(__read_only__, 1)))
;

char *h(const char*)
__attribute__((__access__(__read_only__, 1)))
;

// 非string.h中的声明,此处自定义!
char *strdup(const char*);

int main() {
    
    g f = h; // 将h改为strdup可查看效果
    char c[2] = "0";
    f(c);
    
    printf("%c\n", c[0]);

    return 0;
}

需求

希望GCC编译上述代码时,调用printf无需从内存重新加载c[0]的值,同时要求方案支持函数指针调用场景。

尝试与现象

  • 由于const修饰符易被强制转换,编译器不会基于它做优化,这在预料之中;因此尝试使用__access__(__read_only__, 1)属性,但未产生效果。
  • 当将代码中的g f = h改为g f = strdup时,得到了期望的优化效果:
    • 调用h时生成的汇编(未优化):
      call    h
      movsbl  14(%rsp), %esi    // 从内存加载c[0]
      movl    $.LC0, %edi
      xorl    %eax, %eax
      call    printf
      
    • 调用strdup时生成的汇编(符合期望):
      call    strdup
      movl    $48, %esi    // 直接使用常量"0"的ASCII值
      movl    $.LC0, %edi  // GCC识别到c的内容未被修改
      xorl    %eax, %eax
      call    printf
      
  • 值得注意的是,即使使用自定义的strdup声明(而非string.h中的标准声明),编译器依然能识别该函数不会修改c的内容,从而执行上述优化,这看起来是GCC内置了针对strdup的特殊优化规则。

核心问题

如何让GCC对自定义函数h(最好支持通过函数指针调用的场景)执行同样的优化?


更新说明

  • 更新:因部分评论者对示例用单个char而非合法字符串感到困惑,已修改示例,并突出核心问题。
  • 更新2:已将汇编结果复制到问题中,无需跳转外部链接查看。

内容的提问来源于stack exchange,提问作者UniversE

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.16 14:52:23