我有一个编译得很好的旧代码(对于NXP micro也是gcc,不记得是哪个版本)
#define TIME_CONSTANT 250,mSec
if (SysTimerOnTime(tmr, TIME_CONSTANT))
{
}
现在我尝试为ESP8266做同样的事情,使用gcc for Xtensa
xtensa-lx106-elf-gcc.exe (GCC) 5.2.0
Copyright (C) 2015 Free Software Foundation, Inc.
This is free software; see the source for copying conditions. There is NO
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
我正在使用-std = c99(因为某些内联asm)
投诉是关于在SysTimerOnTime宏中传递2个参数,需要3.所以,如果我使用:
if (SysTimerOnTime(tmr, 250, mSec))
会正常工作。
会出现什么问题?
我很肯定LpcXpresso工作得很完美(也就是gcc),但由于工具链不再安装,我现在无法测试。
宏就像这样
#define SysTimerOnTime(t,v,unit) (t.Enable && (Now()-t.Value) > unit(v))
看起来双重间接成功了。也许LPCXpresso使用较旧的编译器。没关系,这很有效,谢谢Jonathan Leffler
#define TIME_CONSTANT 250,mSec
#define SysTimerOnTime_(t,v,unit) (t.Enable && (Now()-t.Value) > unit(v))
#define SysTimerOnTimeX(x) x
#define SysTimerOnTime(tmr, con) SysTimerOnTimeX(SysTimerOnTime_(tmr, con))
答案 0 :(得分:4)
在评估SysTimerOnTime()
的调用时,在任何参数扩展之前收集参数。只有两个参数 - 因此宏调用不正确。您必须引入一个间接级别才能使用TIME_CONSTANT
宏。例如:
#define SysTimerOnTimeC(tmr, con) SysTimerOnTimeX(SysTimerOnTime(tmr, con))
#define SysTimerOnTimeX(x) x
然后你可以调用:
if (SysTimerOnTimeC(tmr, TIME_CONSTANT))
{
…
}
C代表'恒定'; X代表“扩张”。您不直接从代码调用SysTimerOnTimeX()
宏;它只是一个帮手宏。
我不禁觉得你会更好:
#define QUARTER_SECOND mSec(250)
#define SysTimerOnTime(t, v) ((t).Enable && (Now()-(t).Value) > (v))
然后调用:
if (SysTimerOnTime(tmr, QUARTER_SECOND))
{
…
}
我还在扩展中将两个参数括起来。这是传统的,通常是明智的建议(虽然绝对不是答案的主要部分所需要的)。没有括号,如果你曾经调用过,你会得到编译器的抱怨:
if (SysTimerOnTime(*ptr, QUARTER_SECOND))
因为*
的优先级低于.
。额外的括号应该应用于基础SysTimerOnTime
宏。