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

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