C语言宏定义-主流编译器相关的宏
1. 目的
嵌入式c语言日常开发中,主要面对的编译器有3种,KEIL、IAR、GCC,为了实现多编译代码的统一,抽象了编译器相关的宏,初始设计来源于cmsis源码抽象。
2. 编译器类型识别
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 | /** * @brief Compiler type. * - CMO_COMPILER_TYPE */ #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__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__RESTRICT | restrict是c99标准引入的,它只可以用于限定和约束指针,并表明指针是访问一个数据对象的唯一且初始的方式 |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 | /** * @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 #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 |