C99/GNU99对inline关键字的处理不同于C89

C99中的inline关键字常被误解,它有两个作用:一是作为编译提示,在函数声明中;二是提供内联定义,作为外部定义的替代,外部定义必须在不同的翻译单元中给出。如果不提供外部定义,将导致未定义行为,通常表现为链接失败。

C99 inline semantics are often misunderstood. The inline specifier serves two purposes:

First, as a compiler hint in case of static inline and extern inline declarations. Semantics remain unchanged if you remove the specifier.

Second, in case of raw inline (ie without static or extern) to provide an inline definition as an alternative to an external one, which has to be present in a different translation unit. Not providing the external one is undefined behaviour, which will normally manifest as linking failure.

带有staticextern的情况下,

static inline === static
extern inline === extern

否则,和

inline === extern

Ref: http://stackoverflow.com/a/16254679

Build started: Project: 11 *** Using Compiler 'V6.18', folder: 'D:\kell\core\ARM\ARMCLANG\Bin' Build target 'Target 1' start/core_cm3.c(445): error: non-ASM statement in naked function is not supported uint32_t result=0; ^ start/core_cm3.c(442): note: attribute is here uint32_t __get_PSP(void) __attribute__( ( naked ) ); ^ start/core_cm3.c(465): error: parameter references not allowed in naked functions "BX lr \n\t" : : "r" (topOfProcStack) ); ^ start/core_cm3.c(461): note: attribute is here void __set_PSP(uint32_t topOfProcStack) __attribute__( ( naked ) ); ^ start/core_cm3.c(479): error: non-ASM statement in naked function is not supported uint32_t result=0; ^ start/core_cm3.c(476): note: attribute is here uint32_t __get_MSP(void) __attribute__( ( naked ) ); ^ start/core_cm3.c(499): error: parameter references not allowed in naked functions "BX lr \n\t" : : "r" (topOfMainStack) ); ^ start/core_cm3.c(495): note: attribute is here void __set_MSP(uint32_t topOfMainStack) __attribute__( ( naked ) ); ^ start/core_cm3.c(509): warning: no previous prototype for function '__get_BASEPRI' [-Wmissing-prototypes] uint32_t __get_BASEPRI(void) ^ start/core_cm3.c(509): note: declare 'static' if the function is not intended to be used outside of this translation unit uint32_t __get_BASEPRI(void) ^ static start/core_cm3.c(524): warning: no previous prototype for function '__set_BASEPRI' [-Wmissing-prototypes] void __set_BASEPRI(uint32_t value) ^ start/core_cm3.c(524): note: declare 'static' if the function is not intended to be used outside of this translation unit void __set_BASEPRI(uint32_t value) ^ static start/core_cm3.c(536): warning: no previous prototype for function '__get_PRIMASK' [-Wmissing-prototypes] uint32_t __get_PRIMASK(void) ^ start/core_cm3.c(536): note: declare 'static' if the function is not intended to be used outside of this translation unit uint32_t __get_PRIMASK(void) ^ static start/core_cm3.c(551): warning: no previous prototype for function '__set_PRIMASK' [-Wmissing-prototypes] void __set_PRIMASK(uint32_t priMask) ^ start/core_cm3.c(551): note: declare 'static' if the function is not intended to be used outside of this translation unit void __set_PRIMASK(uint32_t priMask) ^ static start/core_cm3.c(563): warning: no previous prototype for function '__get_FAULTMASK' [-Wmissing-prototypes] uint32_t __get_FAULTMASK(void) ^ start/core_cm3.c(563): note: declare 'static' if the function is not intended to be used outside of this translation unit uint32_t __get_FAULTMASK(void) ^ static start/core_cm3.c(578): warning: no previous prototype for function '__set_FAULTMASK' [-Wmissing-prototypes] void __set_FAULTMASK(uint32_t faultMask) ^ start/core_cm3.c(578): note: declare 'static' if the function is not intended to be used outside of this translation unit void __set_FAULTMASK(uint32_t faultMask) ^ static start/core_cm3.c(590): warning: no previous prototype for function '__get_CONTROL' [-Wmissing-prototypes] uint32_t __get_CONTROL(void) ^ start/core_cm3.c(590): note: declare 'static' if the function is not intended to be used outside of this translation unit uint32_t __get_CONTROL(void) ^ static start/core_cm3.c(605): warning: no previous prototype for function '__set_CONTROL' [-Wmissing-prototypes] void __set_CONTROL(uint32_t control) ^ start/core_cm3.c(605): note: declare 'static' if the function is not intended to be used outside of this translation unit void __set_CONTROL(uint32_t control) ^ static start/core_cm3.c(619): warning: no previous prototype for function '__REV' [-Wmissing-prototypes] uint32_t __REV(uint32_t value) ^ start/core_cm3.c(619): note: declare 'static' if the function is not intended to be used outside of this translation unit uint32_t __REV(uint32_t value) ^ static start/core_cm3.c(635): warning: no previous prototype for function '__REV16' [-Wmissing-prototypes] uint32_t __REV16(uint16_t value) ^ start/core_cm3.c(635): note: declare 'static' if the function is not intended to be used outside of this translation unit uint32_t __REV16(uint16_t value) ^ static start/core_cm3.c(656): warning: implicit conversion changes signedness: 'uint32_t' (aka 'unsigned int') to 'int32_t' (aka 'int') [-Wsign-conversion] return(result); ~~~~~~ ^~~~~~ start/core_cm3.c(651): warning: no previous prototype for function '__REVSH' [-Wmissing-prototypes] int32_t __REVSH(int16_t value) ^ start/core_cm3.c(651): note: declare 'static' if the function is not intended to be used outside of this translation unit int32_t __REVSH(int16_t value) ^ static start/core_cm3.c(667): warning: no previous prototype for function '__RBIT' [-Wmissing-prototypes] uint32_t __RBIT(uint32_t value) ^ start/core_cm3.c(667): note: declare 'static' if the function is not intended to be used outside of this translation unit uint32_t __RBIT(uint32_t value) ^ static start/core_cm3.c(683): warning: no previous prototype for function '__LDREXB' [-Wmissing-prototypes] uint8_t __LDREXB(uint8_t *addr) ^ start/core_cm3.c(683): note: declare 'static' if the function is not intended to be used outside of this translation unit uint8_t __LDREXB(uint8_t *addr) ^ static start/core_cm3.c(699): warning: no previous prototype for function '__LDREXH' [-Wmissing-prototypes] uint16_t __LDREXH(uint16_t *addr) ^ start/core_cm3.c(699): note: declare 'static' if the function is not intended to be used outside of this translation unit uint16_t __LDREXH(uint16_t *addr) ^ static start/core_cm3.c(715): warning: no previous prototype for function '__LDREXW' [-Wmissing-prototypes] uint32_t __LDREXW(uint32_t *addr) ^ start/core_cm3.c(715): note: declare 'static' if the function is not intended to be used outside of this translation unit uint32_t __LDREXW(uint32_t *addr) ^ static start/core_cm3.c(732): warning: no previous prototype for function '__STREXB' [-Wmissing-prototypes] uint32_t __STREXB(uint8_t value, uint8_t *addr) ^ start/core_cm3.c(732): note: declare 'static' if the function is not intended to be used outside of this translation unit uint32_t __STREXB(uint8_t value, uint8_t *addr) ^ static start/core_cm3.c(749): warning: no previous prototype for function '__STREXH' [-Wmissing-prototypes] uint32_t __STREXH(uint16_t value, uint16_t *addr) ^ start/core_cm3.c(749): note: declare 'static' if the function is not intended to be used outside of this translation unit uint32_t __STREXH(uint16_t value, uint16_t *addr) ^ static start/core_cm3.c(766): warning: no previous prototype for function '__STREXW' [-Wmissing-prototypes] uint32_t __STREXW(uint32_t value, uint32_t *addr) ^ start/core_cm3.c(766): note: declare 'static' if the function is not intended to be used outside of this translation unit uint32_t __STREXW(uint32_t value, uint32_t *addr) ^ static 19 warnings and 4 errors generated. compiling core_cm3.c... start/system_stm32f10x.c(65): warning: In file included from... ./start/stm32f10x.h(478): warning: In file included from... ./start/core_cm3.h(1204): error: unknown type name 'inline' static __INLINE void __enable_irq() { __ASM volatile ("cpsie i"); } ^ ./start/core_cm3.h(751): note: expanded from macro '__INLINE' #define __INLINE inline /*!< inline keyword for GNU Compiler */ ^ ./start/core_cm3.h(1205): error: unknown type name 'inline' static __INLINE void __disable_irq() { __ASM volatile ("cpsid i"); } ^ ./start/core_cm3.h(751): note: expanded from macro '__INLINE' #define __INLINE inline /*!< inline keyword for GNU Compiler */ ^ ./start/core_cm3.h(1207): error: unknown type name 'inline' static __INLINE void __enable_fault_irq() { __ASM volatile ("cpsie f"); } ^ ./start/core_cm3.h(751): note: expanded from macro '__INLINE' #define __INLINE inline /*!< inline keyword for GNU Compiler */ ^ ./start/core_cm3.h(1208): error: unknown type name 'inline' static __INLINE void __disable_fault_irq() { __ASM volatile ("cpsid f"); } ^ ./start/core_cm3.h(751): note: expanded from macro '__INLINE' #define __INLINE inline /*!< inline keyword for GNU Compiler */ ^ ./start/core_cm3.h(1210): error: unknown type name 'inline' static __INLINE void __NOP() { __ASM volatile ("nop"); } ^ ./start/core_cm3.h(751): note: expanded from macro '__INLINE' #define __INLINE inline /*!< inline keyword for GNU Compiler */ ^ ./start/core_cm3.h(1211): error: unknown type name 'inline' static __INLINE void __WFI() { __ASM volatile ("wfi"); } ^ ./start/core_cm3.h(751): note: expanded from macro '__INLINE' #define __INLINE inline /*!< inline keyword for GNU Compiler */ ^ ./start/core_cm3.h(1212): error: unknown type name 'inline' static __INLINE void __WFE() { __ASM volatile ("wfe"); } ^ ./start/core_cm3.h(751): note: expanded from macro '__INLINE' #define __INLINE inline /*!< inline keyword for GNU Compiler */ ^ ./start/core_cm3.h(1213): error: unknown type name 'inline' static __INLINE void __SEV() { __ASM volatile ("sev"); } ^ ./start/core_cm3.h(751): note: expanded from macro '__INLINE' #define __INLINE inline /*!< inline keyword for GNU Compiler */ ^ ./start/core_cm3.h(1214): error: unknown type name 'inline' static __INLINE void __ISB() { __ASM volatile ("isb"); } ^ ./start/core_cm3.h(751): note: expanded from macro '__INLINE' #define __INLINE inline /*!< inline keyword for GNU Compiler */ ^ ./start/core_cm3.h(1215): error: unknown type name 'inline' static __INLINE void __DSB() { __ASM volatile ("dsb"); } ^ ./start/core_cm3.h(751): note: expanded from macro '__INLINE' #define __INLINE inline /*!< inline keyword for GNU Compiler */ ^ ./start/core_cm3.h(1216): error: unknown type name 'inline' static __INLINE void __DMB() { __ASM volatile ("dmb"); } ^ ./start/core_cm3.h(751): note: expanded from macro '__INLINE' #define __INLINE inline /*!< inline keyword for GNU Compiler */ ^ ./start/core_cm3.h(1217): error: unknown type name 'inline' static __INLINE void __CLREX() { __ASM volatile ("clrex"); } ^ ./start/core_cm3.h(751): note: expanded from macro '__INLINE' #define __INLINE inline /*!< inline keyword for GNU Compiler */ ^ ./start/core_cm3.h(1468): error: unknown type name 'inline' static __INLINE void NVIC_SetPriorityGrouping(uint32_t PriorityGroup) ^ ./start/core_cm3.h(751): note: expanded from macro '__INLINE' #define __INLINE inline /*!< inline keyword for GNU Compiler */ ^ ./start/core_cm3.h(1489): error: unknown type name 'inline' static __INLINE uint32_t NVIC_GetPriorityGrouping(void) ^ ./start/core_cm3.h(751): note: expanded from macro '__INLINE' #define __INLINE inline /*!< inline keyword for GNU Compiler */ ^ ./start/core_cm3.h(1489): error: expected ';' after top level declarator static __INLINE uint32_t NVIC_GetPriorityGrouping(void) ^ ; ./start/core_cm3.h(1756): error: unknown type name 'inline' static __INLINE uint32_t ITM_SendChar (uint32_t ch) ^ ./start/core_cm3.h(751): note: expanded from macro '__INLINE' #define __INLINE inline /*!< inline keyword for GNU Compiler */ ^ ./start/core_cm3.h(1756): error: expected ';' after top level declarator static __INLINE uint32_t ITM_SendChar (uint32_t ch) ^ ; start/system_stm32f10x.c(162): warning: no previous extern declaration for non-static variable 'SystemCoreClock' [-Wmissing-variable-declarations] uint32_t SystemCoreClock = SYSCLK_FREQ_72MHz; /*!< System Clock Frequency (Core Clock) */ ^ start/system_stm32f10x.c(162): note: declare 'static' if the variable is not intended to be used outside of this translation unit uint32_t SystemCoreClock = SYSCLK_FREQ_72MHz; /*!< System Clock Frequency (Core Clock) */ ^ start/system_stm32f10x.c(167): warning: no previous extern declaration for non-static variable 'AHBPrescTable' [-Wmissing-variable-declarations] __I uint8_t AHBPrescTable[16] = {0, 0, 0, 0, 0, 0, 0, 0, 1, 2, 3, 4, 6, 7, 8, 9}; ^ start/system_stm32f10x.c(167): note: declare 'static' if the variable is not intended to be used outside of this translation unit __I uint8_t AHBPrescTable[16] = {0, 0, 0, 0, 0, 0, 0, 0, 1, 2, 3, 4, 6, 7, 8, 9}; ^ 2 warnings and 17 errors generated. compiling system_stm32f10x.c... user/main.c(1): warning: In file included from... ./start\stm32f10x.h(478): warning: In file included from... ./start/core_cm3.h(1204): error: unknown type name 'inline' static __INLINE void __enable_irq() { __ASM volatile ("cpsie i"); } ^ ./start/core_cm3.h(751): note: expanded from macro '__INLINE' #define __INLINE inline /*!< inline keyword for GNU Compiler */ ^ ./start/core_cm3.h(1205): error: unknown type name 'inline' static __INLINE void __disable_irq() { __ASM volatile ("cpsid i"); } ^ ./start/core_cm3.h(751): note: expanded from macro '__INLINE' #define __INLINE inline /*!< inline keyword for GNU Compiler */ ^ ./start/core_cm3.h(1207): error: unknown type name 'inline' static __INLINE void __enable_fault_irq() { __ASM volatile ("cpsie f"); } ^ ./start/core_cm3.h(751): note: expanded from macro '__INLINE' #define __INLINE inline /*!< inline keyword for GNU Compiler */ ^ ./start/core_cm3.h(1208): error: unknown type name 'inline' static __INLINE void __disable_fault_irq() { __ASM volatile ("cpsid f"); } ^ ./start/core_cm3.h(751): note: expanded from macro '__INLINE' #define __INLINE inline /*!< inline keyword for GNU Compiler */ ^ ./start/core_cm3.h(1210): error: unknown type name 'inline' static __INLINE void __NOP() { __ASM volatile ("nop"); } ^ ./start/core_cm3.h(751): note: expanded from macro '__INLINE' #define __INLINE inline /*!< inline keyword for GNU Compiler */ ^ ./start/core_cm3.h(1211): error: unknown type name 'inline' static __INLINE void __WFI() { __ASM volatile ("wfi"); } ^ ./start/core_cm3.h(751): note: expanded from macro '__INLINE' #define __INLINE inline /*!< inline keyword for GNU Compiler */ ^ ./start/core_cm3.h(1212): error: unknown type name 'inline' static __INLINE void __WFE() { __ASM volatile ("wfe"); } ^ ./start/core_cm3.h(751): note: expanded from macro '__INLINE' #define __INLINE inline /*!< inline keyword for GNU Compiler */ ^ ./start/core_cm3.h(1213): error: unknown type name 'inline' static __INLINE void __SEV() { __ASM volatile ("sev"); } ^ ./start/core_cm3.h(751): note: expanded from macro '__INLINE' #define __INLINE inline /*!< inline keyword for GNU Compiler */ ^ ./start/core_cm3.h(1214): error: unknown type name 'inline' static __INLINE void __ISB() { __ASM volatile ("isb"); } ^ ./start/core_cm3.h(751): note: expanded from macro '__INLINE' #define __INLINE inline /*!< inline keyword for GNU Compiler */ ^ ./start/core_cm3.h(1215): error: unknown type name 'inline' static __INLINE void __DSB() { __ASM volatile ("dsb"); } ^ ./start/core_cm3.h(751): note: expanded from macro '__INLINE' #define __INLINE inline /*!< inline keyword for GNU Compiler */ ^ ./start/core_cm3.h(1216): error: unknown type name 'inline' static __INLINE void __DMB() { __ASM volatile ("dmb"); } ^ ./start/core_cm3.h(751): note: expanded from macro '__INLINE' #define __INLINE inline /*!< inline keyword for GNU Compiler */ ^ ./start/core_cm3.h(1217): error: unknown type name 'inline' static __INLINE void __CLREX() { __ASM volatile ("clrex"); } ^ ./start/core_cm3.h(751): note: expanded from macro '__INLINE' #define __INLINE inline /*!< inline keyword for GNU Compiler */ ^ ./start/core_cm3.h(1468): error: unknown type name 'inline' static __INLINE void NVIC_SetPriorityGrouping(uint32_t PriorityGroup) ^ ./start/core_cm3.h(751): note: expanded from macro '__INLINE' #define __INLINE inline /*!< inline keyword for GNU Compiler */ ^ ./start/core_cm3.h(1489): error: unknown type name 'inline' static __INLINE uint32_t NVIC_GetPriorityGrouping(void) ^ ./start/core_cm3.h(751): note: expanded from macro '__INLINE' #define __INLINE inline /*!< inline keyword for GNU Compiler */ ^ ./start/core_cm3.h(1489): error: expected ';' after top level declarator static __INLINE uint32_t NVIC_GetPriorityGrouping(void) ^ ; ./start/core_cm3.h(1756): error: unknown type name 'inline' static __INLINE uint32_t ITM_SendChar (uint32_t ch) ^ ./start/core_cm3.h(751): note: expanded from macro '__INLINE' #define __INLINE inline /*!< inline keyword for GNU Compiler */ ^ ./start/core_cm3.h(1756): error: expected ';' after top level declarator static __INLINE uint32_t ITM_SendChar (uint32_t ch) ^ ; 17 errors generated. compiling main.c... 阅读该错误报告并给出修改建议
最新发布
09-25
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值