如何在不修改头文件时返回不同类型SFR的指针?
问题描述
我需要编写一个函数,返回两个特殊功能寄存器(SFR)中任意一个的指针。这两个SFR类型不同,但除类型名称外结构完全一致,相关定义位于无法修改的头文件中:
#define SFRxType SFR0Type typedef struct SFR0Type { union { struct { uint16_t var0; uint16_t var1; }; struct { uint32_t var; }; }; } SFR0Type; extern volatile SFR0Type SFR0 __attribute__((__sfr__)); typedef struct SFR1Type { union { struct { uint16_t var0; uint16_t var1; }; struct { uint32_t var; }; }; } SFR1Type; extern volatile SFR1Type SFR1 __attribute__((__sfr__));
(__sfr__属性用于告知编译器变量地址由链接器脚本指定。)
我最初编写的函数如下:
static volatile SFRxType* get_sfr_ptr(uint16_t select) { return select ? &SFR1 : &SFR0; }
但触发了编译器警告:warning: pointer type mismatch in conditional expression。请问在无法修改头文件的限制下,如何修改函数以消除该警告?
解决方案
由于两个SFR的内存布局完全一致,我们可以通过显式类型转换来统一指针类型,消除编译器的类型不匹配警告,以下是几种可行的实现方式:
方法1:直接对分支指针做类型转换
将类型不匹配的指针强制转换为函数返回的目标类型,让三元表达式两边类型一致:
static volatile SFRxType* get_sfr_ptr(uint16_t select) { return select ? (volatile SFRxType*)&SFR1 : &SFR0; }
也可以对两个分支的指针都做转换,让代码风格更对称:
static volatile SFRxType* get_sfr_ptr(uint16_t select) { return select ? (volatile SFRxType*)&SFR1 : (volatile SFRxType*)&SFR0; }
方法2:用void*中转统一类型
先将两个指针转换为void*(C语言中所有指针类型都可隐式转换为void*),再转换回目标类型:
static volatile SFRxType* get_sfr_ptr(uint16_t select) { volatile void* temp_ptr = select ? (volatile void*)&SFR1 : (volatile void*)&SFR0; return (volatile SFRxType*)temp_ptr; }
方法3:改用if-else分支替代三元表达式
放弃三元运算符,通过分支语句分别返回转换后的指针,避免条件表达式的类型检查:
static volatile SFRxType* get_sfr_ptr(uint16_t select) { if (select) { return (volatile SFRxType*)&SFR1; } else { return &SFR0; } }
以上方法均安全有效,因为两个SFR的结构完全一致,类型转换不会导致内存访问错误或未定义行为。
内容的提问来源于stack exchange,提问作者abessman
相关产品推荐
相关产品推荐

