【发布时间】:2017-11-05 18:02:48
【问题描述】:
为什么我需要找出字面量的 smalles 类型(背景故事)
我编写了一组宏来创建和使用 fifo。宏允许在所有具有静态内存分配的系统上进行通用但仍然非常快速的实现,例如在小型嵌入式系统中。 codereview 那边的人对my implementation 也没有任何大的顾虑。
数据被放入匿名struts,所有数据都通过该结构的标识符访问。目前用于创建这些结构的类函数宏如下所示
#define _fff_create(_type, _depth, _id) \
struct {uint8_t read; uint8_t write; _type data[_depth];} _id = {0,0,{}}
#define _fff_create_deep(_type, _depth, _id) \
struct {uint16_t read; uint16_t write; _type data[_depth];} _id = {0,0,{}}
我在寻找什么
现在我想将这两个合并到一个宏中。为此,我必须计算read 和write 在编译时索引_depth 元素数量所需的最小大小。以_ 开头的参数名称表示仅可以传递文字或#define 值,两者在编译时都是已知的。
因此,我希望找到一个宏 typeof_literal(arg),如果 arguint16_t 否则返回 uint8_t。
我尝试过的
- GCC 4.9.2。提供了一个名为
typeof()的命令。但是,当与任何文字一起使用时,它会返回一个int类型,在我的系统上是两个字节。 - GCC 4.9.2 的另一个特性是compound statement。
typeof(({uint8_t u8 = 1; u8;}))将正确返回uint8_t。但是我想不出一种方法来为该块中的类型设置条件: -
typeof(({uint8_t u8 = 1; uint16_t u16 = 1; input ? u8 : u16;}))总是返回uint16_t因为 ?: 运算符的类型提升 -
if(...)也不能使用,因为任何命令都会发生在“较低”块中 - 宏不能包含
#if,这使得它们也无法用于此比较。
你就不能这样吗?
我意识到这个问题可能没有解决方案。那也没关系;当前的代码只是一个小小的不便。然而,我想知道是否有一个棘手的方法来解决这个问题。对此的解决方案通常可以为宏开辟新的可能性。如果您确定这不可能,请解释原因。
【问题讨论】:
-
这似乎是 C++ 模板的理想用例,但我知道您的问题与 C++ 无关。
-
@GregHewgill 如果所有常量都是
int类型,那么在 C 中真正有什么帮助... -
以下划线开头的名称保留用于文件范围内的实现。而且空的初始化列表是非法的。
标签: c gcc casting macros c-preprocessor