当前位置: 首页 > news >正文

GCC /Clang __attribute__

__attribute__ 系列(GCC / Clang)🛠️

__attribute__((...)) 是 GCC / Clang 提供的扩展,用来把额外的语义 / 优化提示告诉编译器。合理使用可以帮助编译器生成更高效或更安全的代码;滥用则可能导致代码臃肿、不可移植或难以调试。下面把常用属性按用途分类讲清楚:语法、常见属性、示例、注意事项与可移植写法。


1) 语法与现代替代写法

  • 经典写法(C / C++):
int f(int) __attribute__((pure));
  • 多属性:
int f(int) __attribute__((pure, hot));
  • C++11 风格(部分属性支持):
[[gnu::pure]]
[[nodiscard]]

建议:对公共头文件,使用宏封装以便可移植到 MSVC 或兼容不同编译器版本。


2) 常用函数属性(按类别)

语义 / 副作用相关

  • pure
    函数无副作用(除了读取内存)。返回值依赖参数 + 读取的内存。允许消除重复调用。

    int strcmp(const char*, const char*) __attribute__((pure));
    
  • const
    更严格:函数仅依赖其参数(不能读取可变内存或全局)。更强的优化空间。

    int square(int) __attribute__((const));
    

内联 / 调用控制

  • always_inline / inline
    尽量/强制内联(可能被编译器在某些情况下忽略)。

    static inline int add(int a,int b) __attribute__((always_inline));
    
  • noinline
    禁止内联(对调试、大小控制有用)。

    void heavy_log(const char*) __attribute__((noinline));
    

性能 / 布局提示

  • hot / cold
    告诉编译器热/冷函数,用于代码布局与优化策略(把 cold 放到 .cold)。

    void handle_error() __attribute__((cold));
    
  • flatten
    强制将函数中可内联的调用全部展开(可能导致代码暴涨)。

  • optimize("O3")
    针对单函数设置优化级别(注意可读性与一致性问题)。

控制流与错误

  • noreturn
    函数不会返回(例如 exit()abort()),帮助编译器消除后续死代码警告。

    void fatal_error(const char*) __attribute__((noreturn));
    

接口 / 参数校验

  • format(printf, fmt_idx, arg_idx)
    告诉编译器这是 printf/scanf 风格函数,启用参数检查(位置从 1 开始)。

    void my_printf(const char *fmt, ...) __attribute__((format(printf, 1, 2)));
    
  • sentinel
    用于可变参数函数,检查尾部是否有 NULL 终结(常用于 varargs)。

  • nonnull
    指定某些参数不应为 NULL(优化/警告提示)。

    void foo(char *p) __attribute__((nonnull(1)));
    

返回值 / 分配相关

  • returns_nonnull(或 __attribute__((returns_nonnull))
    告诉编译器函数返回非 NULL 指针。
  • malloc
    返回的指针不与现存内存重叠(可用于更好优化)。

诊断 / 可用性

  • deprecated("msg")
    标记废弃的接口(编译时发出警告,支持自定义消息)。
  • error("msg")
    直接把使用视为错误(GCC 有此属性)。
  • unused / used
    标记变量/函数避免被编译器误报未使用或确保不被删除。

连接 / 链接器相关

  • visibility("default"|"hidden"|"internal")
    控制符号导出(对共享库非常重要,能减少动态符号表与重定位)。

    int api_fn() __attribute__((visibility("default")));
    
  • weak / alias("sym")
    创建弱符号或为符号创建别名(高级用法)。

构造 / 析构(初始化)

  • constructor / destructor
    使函数在 main() 之前或之后运行(像静态初始化)。

    void init_fn() __attribute__((constructor));
    

3) 变量 / 类型级属性

  • aligned(n)
    设置类型或变量的对齐(影响 ABI、性能)。

    int x __attribute__((aligned(64)));
    struct S { char c; } __attribute__((aligned(8)));
    
  • packed
    去掉对齐填充(紧凑布局),注意可能导致未对齐访问与性能下降。

    struct __attribute__((packed)) P { char c; int i; };
    
  • transparent_unionmay_alias 等(高级)用于 ABI/兼容性技巧。

  • section("name")
    将变量/函数放到指定段(用于嵌入式或特殊链接需求)。


4) 实例与常见用法(代码片段)

// printf-like checker
void my_log(const char *fmt, ...) __attribute__((format(printf, 1, 2)));// error handling (cold)
void handle_error(const char *msg) __attribute__((cold, noreturn));// performance hints
int compute(int x) __attribute__((hot, always_inline, const));// avoid inlining (keep stack trace)
void debug_breakpoint() __attribute__((noinline));// mark API exported, smaller dynamic symbol table
int public_api() __attribute__((visibility("default")));

5) 常见坑 / 注意事项

  • 可移植性:这些是 GCC/Clang 扩展;MSVC 有不同语法(__declspec)。请用宏封装并在不支持时回退为空定义。
  • 改变 ABIpackedaligned 会影响结构布局和 ABI,可能导致未定义行为或性能问题。
  • 调试影响always_inline / flatten 会把函数展开,导致堆栈帧信息丢失,影响调试与栈回溯。
  • 代码膨胀flattenalways_inline 可能导致二进制变大(instruction cache 受影响)。
  • 误用导致性能变差pure/const 仅在语义满足时使用;错误标注会让编译器做不安全的优化。
  • 编译器支持差异:某些属性 Clang 支持但 GCC 不支持(反之亦然),可用 __has_attribute 做条件编译(见下)。

6) 可移植的宏封装建议(示例)

把属性包装成宏,便于不同编译器兼容:

#pragma once/* ===========================================================*  Cross-Compiler Attribute Macros*  Compatible with GCC, Clang, and MSVC (fallback to empty)* =========================================================== */#if defined(__has_attribute)
#  define HAS_ATTR(x) __has_attribute(x)
#else
#  define HAS_ATTR(x) 0
#endif#if defined(_MSC_VER)
#  define FORCE_INLINE __forceinline
#  define NOINLINE     __declspec(noinline)
#  define DEPRECATED(msg) __declspec(deprecated(msg))
#else
#  define FORCE_INLINE inline __attribute__((always_inline))
#  define NOINLINE     __attribute__((noinline))
#  if HAS_ATTR(deprecated) || defined(__GNUC__)
#    define DEPRECATED(msg) __attribute__((deprecated(msg)))
#  else
#    define DEPRECATED(msg)
#  endif
#endif/* --- Function purity hints --- */
// Pure: no side effects, result depends only on args + memory reads
#if HAS_ATTR(pure) || defined(__GNUC__)
#  define PURE __attribute__((pure))
#else
#  define PURE
#endif// Const: stronger than pure, depends only on args (no memory access)
#if HAS_ATTR(const) || defined(__GNUC__)
#  define CONST __attribute__((const))
#else
#  define CONST
#endif/* --- Hot/Cold function hints --- */
#if HAS_ATTR(hot) || defined(__GNUC__)
#  define HOT __attribute__((hot))
#else
#  define HOT
#endif#if HAS_ATTR(cold) || defined(__GNUC__)
#  define COLD __attribute__((cold))
#else
#  define COLD
#endif/* --- Inline flattening --- */
#if HAS_ATTR(flatten) || defined(__GNUC__)
#  define FLATTEN __attribute__((flatten))
#else
#  define FLATTEN
#endif/* --- Function flow attributes --- */
// Function never returns
#if HAS_ATTR(noreturn) || defined(__GNUC__)
#  define NORETURN __attribute__((noreturn))
#else
#  define NORETURN
#endif// printf-style format checking
#if HAS_ATTR(format) || defined(__GNUC__)
#  define FORMAT(archetype, fmt_idx, var_idx) \__attribute__((format(archetype, fmt_idx, var_idx)))
#else
#  define FORMAT(archetype, fmt_idx, var_idx)
#endif/* --- Branch prediction hints --- */
#if defined(__GNUC__) || defined(__clang__)
#  define LIKELY(x)   __builtin_expect(!!(x), 1)
#  define UNLIKELY(x) __builtin_expect(!!(x), 0)
#else
#  define LIKELY(x)   (x)
#  define UNLIKELY(x) (x)
#endif/* --- Prefetch hint --- */
#if defined(__GNUC__) || defined(__clang__)
#  define PREFETCH(addr, rw, locality) __builtin_prefetch((addr), (rw), (locality))
#else
#  define PREFETCH(addr, rw, locality) ((void)0)
#endif/* --- Variable/struct attributes --- */
// Force alignment
#if HAS_ATTR(aligned) || defined(__GNUC__)
#  define ALIGNED(n) __attribute__((aligned(n)))
#else
#  define ALIGNED(n)
#endif// Pack struct (no padding, ABI sensitive!)
#if HAS_ATTR(packed) || defined(__GNUC__)
#  define PACKED __attribute__((packed))
#else
#  define PACKED
#endif// Control symbol visibility (shared libs)
#if HAS_ATTR(visibility) || defined(__GNUC__)
#  define EXPORT __attribute__((visibility("default")))
#  define HIDDEN __attribute__((visibility("hidden")))
#else
#  define EXPORT
#  define HIDDEN
#endif

7) 测试与落地建议

  • 先测量后优化:用 perf / VTune / sampling profiler 找到热点,再用属性微调。
  • 小步改动:一次只改一个热点,比较二进制大小、分支未命中和 cycles。
  • 结合 PGO:Profile-Guided Optimization 可在很多情况下胜过手动注解。
  • 记录兼容约束:在项目 README 记录哪些属性被使用、为何使用、对哪个编译器/平台有效。

8) (cheat-sheet)

  • pure / const — 无副作用 / 仅依赖参数
  • format(printf, m, n) — printf/scanf 参数检查
  • noreturn — 不返回
  • always_inline / noinline — 控制内联
  • hot / cold — 热/冷函数提示
  • flatten — 全部展开(慎用)
  • visibility("hidden") — 减少导出符号
  • deprecated("msg") — 标记废弃
  • packed / aligned(n) — 控制内存布局(影响 ABI)
http://www.dtcms.com/a/520058.html

相关文章:

  • 阮一峰《TypeScript 教程》学习笔记——Enum 类型
  • 人工只能综合项目开发8---手势识别data_processing
  • C primer plus (第六版)第十一章 编程练习第13题
  • 网站被k申述泉州专业网站建设公司
  • FLUMINER福禄T3 115T挖矿机深度评测:智能管理与高效性能如何平衡?
  • 怎么调网站兼容性公益网站怎么做
  • 压缩与缓存调优实战指南:从0到1根治性能瓶颈(四)
  • 嵌入式软件架构--显示界面架构(工厂流水线模型,HOME界面,命令界面)
  • Ubuntu20.04 + QT5.14.2 + Android23的开发平台搭建总结
  • 【思维链条CoT与React模式深度解析】AI智能体的核心推理框架
  • svchost第一个是rpcss第二个是termsvcs第三个是NetworkService第四个是LocalService第五个是netsvcs----备忘
  • 餐饮网站模板免费下载jetpack wordpress
  • Hadoop High Availability 简介
  • Tier 1 供应商EDI对接:Forvia EDI需求分析
  • 2025最新策略答案引擎优化(AEO):在AI搜索引擎中获得更多曝光
  • SpringAI Redis RAG 搜索
  • 服务器和域名都有了 怎么做网站网站seo诊断分析报告
  • SpringBoot的Web开发
  • 基于springboot的大创管理系统开发与设计
  • GitHub 热榜项目 - 日榜(2025-10-23)
  • RAG:让大模型“既懂又查”的智能系统
  • cms网站建设的优缺点wordpress两个站合并
  • 数据结构——B树及其基本操作
  • java.text.MessageFormat的用法
  • 公司网站怎么做分录平面设计怎么网上接单
  • Java爬虫性能优化:以喜马拉雅音频元数据抓取为例
  • 使用 Java 对 PDF 添加水印:提升文档安全与版权保护
  • CRMEB-PHP订单改价模块详解
  • 丽水 网站建设注册163免费邮箱
  • 网站建设微信开发怎么做订阅号