C语言宏定义-主流编译器相关的宏

C语言宏定义-主流编译器相关的宏

1. 目的

嵌入式c语言日常开发中,主要面对的编译器有3种,KEIL、IAR、GCC,为了实现多编译代码的统一,抽象了编译器相关的宏,初始设计来源于cmsis源码抽象。

2. 编译器类型识别

/**
 * @def CMO_COMPILER_TYPE
 * @brief Compiler type.
 */
/* Compiler enum */
// clang-format off
#define CMO_COMPILER_ARMCC 0 /**< armcc compiler */
#define CMO_COMPILER_IAR   1 /**< iar compiler   */
#define CMO_COMPILER_GCC   2 /**< gcc compiler   */
// clang-format on

#if defined(__CC_ARM)
#if defined(__ARMCC_VERSION) && (__ARMCC_VERSION < 400677)
#error "Please use Arm Compiler Toolchain V4.0.677 or later!"
#endif
#define CMO_COMPILER_TYPE CMO_COMPILER_ARMCC
#elif defined(__ICCARM__)
#define CMO_COMPILER_TYPE CMO_COMPILER_IAR
#elif defined(__GNUC__)
#define CMO_COMPILER_TYPE CMO_COMPILER_GCC
#else
#error "Unknown compiler(now support ARMCC, IAR, GCC)!"
#endif

3. 编译器相关的通用宏

命令规则为CMO__$(XXXX), 注意是这里是CMO__双下划线开头表示编译器相关的通用宏。

CMO__ASM嵌入汇编
CMO__INLINE内联函数
CMO__STATIC_INLINE静态内联函数
CMO__STATIC_FORCEINLINE函数使用了强制内联关键字,但实际没有进行内联,将给出警告
CMO__NO_RETURN函数没有返回值
CMO__CHECK_RETURN函数返回值需要检查,否则编译warning
CMO__USED变量或者函数有used属性
CMO__WEAK函数是weak类型,可以外部被实现而覆盖
CMO__ALIGNED(x)对齐方式
CMO__PACKED取消结构在编译过程中的优化对齐,按照实际占用字节数进行对齐
CMO__RESTRICTrestrict是c99标准引入的,它只可以用于限定和约束指针,并表明指针是访问一个数据对象的唯一且初始的方式
/**
 * @brief Compiler Marco.
 * - CMO__ASM
 * - CMO__INLINE
 * - CMO__STATIC_INLINE
 * - CMO__STATIC_FORCEINLINE
 * - CMO__NO_RETURN
 * - CMO__CHECK_RETURN
 * - CMO__USED
 * - CMO__WEAK
 * - CMO__ALIGNED
 * - CMO__PACKED
 * - CMO__RESTRICT
 */

#if (CMO_COMPILER_TYPE == CMO_COMPILER_ARMCC) /* ARM Compiler */
#define CMO__ASM __asm
#define CMO__INLINE __inline
#define CMO__STATIC_INLINE static __inline
#define CMO__STATIC_FORCEINLINE static __forceinline
#define CMO__NO_RETURN __declspec(noreturn)
#define CMO__CHECK_RETURN __attribute__((warn_unused_result))
#define CMO__USED __attribute__((used))
#define CMO__WEAK __attribute__((weak))
#define CMO__ALIGNED(x) __attribute__((aligned(x)))
#define CMO__PACKED __attribute__((packed))
#define CMO__RESTRICT __restrict
#elif (CMO_COMPILER_TYPE == CMO_COMPILER_IAR) /* IAR Compiler */
#if (__VER__ >= 8000000)
#define __ICCARM_V8 1
#else
#define __ICCARM_V8 0
#endif

#define CMO__ASM __asm
#define CMO__INLINE inline
#define CMO__STATIC_INLINE static inline
#define __FORCEINLINE _Pragma("inline=forced")
#define CMO__STATIC_FORCEINLINE __FORCEINLINE CMO__STATIC_INLINE
#if __ICCARM_V8
#define CMO__NO_RETURN __attribute__((__noreturn__))
#else
#define CMO__NO_RETURN _Pragma("object_attribute=__noreturn")
#endif

#define CMO__CHECK_RETURN // TODO:

#if __ICCARM_V8
#define CMO__USED __attribute__((used))
#else
#define CMO__USED _Pragma("__root")
#endif

#if __ICCARM_V8
#define CMO__WEAK __attribute__((weak))
#else
#define CMO__WEAK _Pragma("__weak")
#endif

#if __ICCARM_V8
#define CMO__ALIGNED(x) __attribute__((aligned(x)))
#elif (__VER__ >= 7080000)
/* Needs IAR language extensions */
#define CMO__ALIGNED(x) __attribute__((aligned(x)))
#else
//#warning No compiler specific solution for CMO__ALIGNED.CMO__ALIGNED is ignored.
#define CMO__ALIGNED(x)
#endif

#if __ICCARM_V8
#define CMO__PACKED __attribute__((packed, aligned(1)))
#else
/* Needs IAR language extensions */
#define CMO__PACKED __packed
#endif

#define CMO__RESTRICT __restrict
#elif (CMO_COMPILER_TYPE == CMO_COMPILER_GCC) /* GCC Compiler */
#define CMO__ASM __asm
#define CMO__INLINE inline
#define CMO__STATIC_INLINE static inline
#define CMO__STATIC_FORCEINLINE __attribute__((always_inline)) static inline
#define CMO__NO_RETURN __attribute__((__noreturn__))
#if !defined(__GNUC__) || (__GNUC__ < 3) ||                                  \
    (__GNUC__ == 3 && __GNUC_MINOR__ < 4)
#define CMO__CHECK_RETURN
#else
#define CMO__CHECK_RETURN __attribute__((warn_unused_result))
#endif
#define CMO__USED __attribute__((used))
#define CMO__WEAK __attribute__((weak))
#define CMO__PACKED __attribute__((packed, aligned(1)))
#define CMO__ALIGNED(x) __attribute__((aligned(x)))
#define CMO__RESTRICT __restrict
#else
#error Unknown compiler.
#endif

4. 编译器相关的特性宏

命令规则为CMO__HAVE_$(XXXX), 注意是以CMO__HAVE固定开头表示编译器特性宏开关。

CMO__HAVE_STATIC_ASSERT检查编译器是否支持_Static_assert
CMO__HAVE_TYPEOF检查编译器是否支持typeof
CMO__HAVE_BUILTIN_TYPES_COMPATIBLE_P检查编译器是否支持__builtin_types_compatible_p函数
/**
 * @def CMO__HAVE_STATIC_ASSERT
 * @brief GCC 4.6 and higher have the C11 `_Static_assert` builtin.
 */
#if (__GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 6)) ||              \
    (__STDC_VERSION__ >= 201100)
#define CMO__HAVE_STATIC_ASSERT 1
#else
#define CMO__HAVE_STATIC_ASSERT 0
#endif /* _Static_assert built in */

/**
 * @def CMO__HAVE_TYPEOF
 * @brief GUNC have `typeof` keyword.
 */
#ifdef(__GNUC__)
#define CMO__HAVE_TYPEOF 1
#else
#define CMO__HAVE_TYPEOF 0
#endif /* __GNUC__ */

/**
 * @def CMO__HAVE_BUILTIN_TYPES_COMPATIBLE_P
 * @brief GUNC have `__builtin_types_compatible_p` function.
 */
#ifdef(__GNUC__)
#define CMO__HAVE_BUILTIN_TYPES_COMPATIBLE_P 1
#else
#define CMO__HAVE_BUILTIN_TYPES_COMPATIBLE_P 0
#endif /* __GNUC__ */
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值