头文件初始化Non-Static Extern变量引发编译警告的技术咨询
解决"no previous extern declaration for non-static variable"警告问题
这个警告的根源是你对extern关键字的用法理解有点偏差,咱们一步步来捋清楚:
问题出在哪?
你在led.h里写的extern int iStep = +1;其实不是声明,而是定义。C语言里,当extern变量带有初始化值时,编译器会把它当作一个变量定义,而非单纯的声明。这就导致两个问题:
- 如果这个头文件被多个源文件包含,会触发重复定义的错误;
- 你在
led.c里又写了int iStep;,这是一个不带初始化的定义,编译器会认为这个定义之前没有对应的extern声明,所以抛出那个警告。
正确的写法应该是这样:
- 修改头文件
led.h:只做extern声明,不要初始化
/* led.h */ #ifndef LED_H #define LED_H // 加上头文件保护,避免重复包含 extern int iStep; // 这里是单纯的声明,告诉编译器这个变量在其他地方定义 static void SetLEDPort2Output(void); void LEDPortIni(void); void LEDSet(unsigned char Value); void PB10IntIni(void); void TIM3IntIni(void); void EXTI15_10_IRQHandler(void); void TIM3_IRQHandler(void); #endif
- 修改源文件
led.c:在这里定义并初始化变量
/* led.c */ #include <stm32f10x.h> #include "led.h" int iStep = +1; // 这里是变量的定义,同时赋予初始值 #define CHECKBIT(Var, Nr) (Var & (1<<Nr)) #define CLR_PORTBIT(PORT, BIT) {PORT->BRR |= (1<<BIT);} #define SET_PORTBIT(PORT, BIT) {PORT->BSRR |= (1<<BIT);} #define COPY_PORTBIT(Var, Nr, PORT, BIT) {if(CHECKBIT(Var, Nr)) SET_PORTBIT(PORT, BIT); else CLR_PORTBIT(PORT, BIT);} typedef struct { GPIO_TypeDef* aGPIO[7]; unsigned int aPIN[7]; } PORT; static PORT LEDPort = {{GPIOA, GPIOA, GPIOA, GPIOA, GPIOA, GPIOA, GPIOA}, { 0, 1, 2, 3, 4, 5, 6}}; void EXTI15_10_IRQHandler(void) { if(GPIOB->IDR & (0x1<<10)) iStep = +1; else iStep = -1; EXTI->PR |= (0x1<<10); } void TIM3_IRQHandler(void) { const unsigned char out[] = {0x1, 0x3, 0x6, 0xC, 0x18, 0x30, 0x60, 0x40}; static int i = 0; i = (i + iStep) & 7; LEDSet(out[i]); }
补充说明:
extern的作用是告诉编译器:“这个变量已经在其他地方定义了,你别在这里再定义一遍,直接用就行”。所以声明的时候不能带初始化,带初始化就变成定义了。- 头文件保护(
#ifndef/#define/#endif)是个好习惯,能防止头文件被多次包含导致的重复声明/定义问题,建议加上。
内容的提问来源于stack exchange,提问作者Mohamad
相关产品推荐
相关产品推荐

