【发布时间】:2014-10-16 17:42:00
【问题描述】:
我目前正在做一个项目,一个特定的部分需要一个多行宏函数(据我所知,常规函数在这里不起作用)。
目标是制作一个堆栈操作宏,将任意类型的数据拉出堆栈(作为函数调用的内部堆栈,不是高级“堆栈”数据类型)。如果它是一个函数,它看起来像这样:
type MY_MACRO_FUNC(void *ptr, type);
其中type 是从堆栈中提取的数据类型。
我目前有一个适用于我的平台 (AVR) 的有效实现:
#define MY_MACRO_FUNC(ptr, type) (*(type*)ptr); \
(ptr = /* Pointer arithmetic and other stuff here */)
这让我可以写如下内容:
int i = MY_MACRO_FUNC(ptr, int);
正如您在实现中看到的那样,这是有效的,因为分配i 的语句是宏中的第一行:(*(type*)ptr)。
然而,我真正想要的是能够有一个声明之前,在任何东西被破坏之前验证ptr 是一个有效的指针。但是,这会导致宏被扩展为 int i = 指向该指针检查。有没有办法在标准 C 中解决这个问题?感谢您的帮助!
【问题讨论】:
-
如何验证
ptr是否有效?使用表达式(并且可能是逗号的操作数)?什么是“算术和其他东西”?ptr(赋值前)的原值能否恢复?如果可以,那就有可能,否则,您需要一些临时对象,这至少会使它变得困难。 -
三元运算符可能会做你想做的事,但无论如何我很容易想象出重大问题。不涉及违反严格别名的公然潜力,您所拥有的只是一个类型和一个前景指针。假设它实际上不是有效的,那么确切地说你是初始化
i的替代值源? (或者您只是计划彻底终止流程)? -
@mafso
ptr将被验证为非NULL并具有预期的对齐方式(对齐为 AVR 上的有效整数指针)。你能解释一下“逗号操作数”部分吗?在弹出这个值之后,算法只是将ptr分配给堆栈上的下一个点。我相信可以恢复原来的价值,是的。 -
@WhozCraig 另一种选择是拨打
abort,是的。