【问题标题】:C, macro arguments, substitution of parametersC、宏参数、参数替换
【发布时间】:2018-03-28 14:52:33
【问题描述】:

我有一个编译得很好的旧代码(也是 NXP micro 的 gcc,不记得是哪个版本)

#define TIME_CONSTANT     250,mSec

if (SysTimerOnTime(tmr, TIME_CONSTANT)) 
{

}

现在我尝试对 ESP8266 做同样的事情,将 gcc 用于 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 在 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))

【问题讨论】:

  • ...SysTimerOnTime 的定义可能与此处相关...
  • 这无关紧要,我只是说效果很好。但在这里:) 一定是编译器问题或标准......我想不通。
  • SysTimerOnTime 是一个宏这一事实与您的问题 100% 相关。不清楚的是为什么以前的代码可以正常工作。
  • 您似乎已经得到了很好的答案,但以后在提出此类问题时,请始终包含错误消息的完整且未经编辑的文本。跨度>

标签: c gcc macros


【解决方案1】:

在评估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 宏。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2012-04-08
    • 2014-12-15
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-06-05
    相关资源
    最近更新 更多