【问题标题】:multiple lines macro in CC中的多行宏
【发布时间】:2017-04-04 14:39:27
【问题描述】:

有谁知道为什么这在语法上是错误的? 我试图掩盖这一点

    #define OUTS_FROM_FP(_fp, _argCount) ((u4*) ((u1*)SAVEAREA_FROM_FP(_fp) - sizeof(u4) * (_argCount)))

到这里

    #define OUTS_FROM_FP(_fp, _argCount) {\
    ((u4*) ((u1*)SAVEAREA_FROM_FP(_fp) - sizeof(u4) * (_argCount))); \
    cout<<"Hello World"<<endl;  \
    }

    outs = OUTS_FROM_FP(fp, vsrc1); --this is how it is being called

运行此程序时出现很多错误:它们从声明之前传递给宏的变量未使用的语句开始

【问题讨论】:

  • 你为什么还要使用宏而不是函数?
  • 这是来自 Dalvik VM 的 sn-p。我正在尝试修改它
  • 您能举例说明宏的使用位置吗?我认为可能是您的编译器不支持表达式块,或者该块的最后一行是打印语句而不是原始表达式,但无论哪种方式,如果您提供您在哪里使用它以及错误是什么的示例。
  • outs = OUTS_FROM_FP(fp, vsrc1); --这就是它的调用方式
  • 你能用那个编辑问题吗,outs 是什么类型,你看到了什么错误?

标签: c++ macros


【解决方案1】:

展开后,原来的宏会是这样的:

outs = ((u4*) ((u1*)SAVEAREA_FROM_FP(fp) - sizeof(u4) * (vsrc)));

这是(据我所知,因为您没有提供太多上下文)有效代码。

您修改后的宏将相同的语句扩展为:

outs = { /* ... */ };

当您尝试将代码块分配给变量时,您的编译器会感到各种困惑......

除了一般使用宏的所有常见警告之外,您可以使用逗号运算符让修改后的宏“工作”:

#define OUTS_FROM_FP( _fp, _argCount ) \
    cout << "Hello world\n", \
    ((u4*) ((u1*)SAVEAREA_FROM_FP(_fp) - sizeof(u4) * (_argCount)))

(输出放在最前面,因为由逗号分隔的语句评估为 last 语句的结果 - 将输出放在最前面使宏仍然评估为与原始值相同的值宏。)

总而言之,你最好把那个宏变成一个函数。

【讨论】:

  • GCC 实际上支持使用块作为表达式。
  • @DanielH:是的,但不是那样,除非绝对必要,否则我不想展示编译器的细节。
  • 这仍然给出错误;(但更具体:从 'void*' 到 'u4* {aka unsigned int*}' 的无效转换 [-fpermissive]
  • 可能只是你需要在cout 行和整个宏主体周围加上括号,但我不这么认为。
【解决方案2】:

假设_fp_argCount是变量或者简单的表达式,原来的版本是u4*类型的表达式。

第二个更复杂。大括号使它成为一个块,但在语法上你将它用作一个表达式。这在 C++ 标准中是不允许的,但在 is supported by g++some other compilers 中是不允许的。既然你说你使用的是 GCC,那么这个表达式的值就是块的最后一行的值,在这种情况下是 cout&lt;&lt;"Hello World"&lt;&lt;endl。如果你使用的编译器不支持语句表达式,你会得到一个更加混乱的语法错误。

我希望除非您可以将 ostream 转换为 u4 指针(考虑到我们所拥有的上下文,这似乎不太可能),否则这是行不通的。在这种简单的情况下,您可以通过简单地切换块中行的顺序来修复它。在一个更复杂的情况下,我期望这是最终目标,你可能需要做类似的事情

#define OUTS_FROM_FP(_fp, _argCount) {\
    u4* result = ((u4*) ((u1*)SAVEAREA_FROM_FP(_fp) - sizeof(u4) * (_argCount))); \
    cout<<"Hello World"<<endl;  \
    result; \
}

这会将宏的输出保存到一个临时变量中,执行您想要的任何计算(可以更改result),然后在最后一行“返回”宏之外的result。这比DevSolar’s solution 的可移植性差,但如果您需要创建临时变量,它会更好,而且在我看来更具可读性。

但是,正如其他人在 cmets 中指出的那样,几乎没有理由(至少我们可以看到)将其保留为宏而不是将其转换为函数。函数在很多方面都更加健壮。您可能仍希望将其保留为宏的原因包括 SAVEAREA_FROM_FP 的定义发生变化或 u4u1 类型在不同的地方不同。这些都不是好的编程习惯,但你无法控制其他人以前做过的事情,而且我对 Dalvik 的了解还不够,不能说事实并非如此。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-07-23
    • 1970-01-01
    • 2016-09-05
    相关资源
    最近更新 更多