-5

当我尝试编译此代码时,它显示错误:

main.cpp:19:3: error: invalid operands of types 'void' and 'int' to binary 'operator!='

这是文件:

#include <iostream>
#include <cstdio>
using namespace std;
#define $ DEBUG
#define DEBUG 1
#define _(out) do{  std::cout << __FILE__ << ":" << __LINE__ \
                       << " " << out << '\n';}while(0)
#define _(out) printf(out);
int main(){

#ifdef LOCAL_PROJECT
    #define DEBUG 0
#endif

    $ && ({
        _("eeeeewe");
    });//line 19

    return 0;
}

$是 的简单名称DEBUG,在运行时它是0or 1

编译错误是针对这个源文件的。如何摆脱这个并编译?

4

2 回答 2

3

你在这里做的有些事情是不可取的,有些是非法的。但我给了你一个赞成票,至少提醒我注意我没见过的 gcc 扩展

#include <iostream>

int main() {
    int x = ({std::cout << "I'm surprised this prints "; 10 + 20;});
    std::cout << x << "\n";
}

这确实在 IDEone 上输出I'm surprised this prints 30,即使在 C++14 设置下也是如此。在coliru 上,虽然你得到:

main.cpp:4:17:警告:ISO C++ 禁止表达式中的大括号组 [-Wpedantic]

然而,既然我们已经一起学习了,请避免非标准的扩展。部分原因是 StackOverflow 上的人会对你大喊大叫。但主要是因为当你坚持已经被大量思考问题的人同意和审查的子集时,生活已经足够艰难,试图在语言发展、教育和使用方面找到真正的土地。

(“那个人当时为那个项目添加的语言特性”可能是一个坏主意——对于“那个人”或“那个项目”的任何定义。)

此外,像这样的东西——很少使用——可能在优化器中缺乏关于获取该表达式的各种关注。这意味着充其量它比其他方式慢,最坏的情况是它有随机错误。


继续:

  • $in 标识符名称的使用显然是“实现定义的行为”。这意味着规范中没有任何内容不允许它......但也没有说编译器也必须实现它。它可能不是你想要发明新的创造性用途的东西,只有当你陷入与 VAX 或其他东西上的旧代码桥接的情况时才使用它。

  • 另一方面,您根本不能命名任何以下划线开头的全局变量或宏。它们保留给编译器实现以供自己使用。 (如果您阅读所有内容,您会看到其他不寻常的细微差别,例如在任何范围内不能有以下划线开头并后跟大写字母的标识符,尽管如果字母是小写字母,您可以在本地定义它们。通常人们将其用于成员变量,但必须小心遵守规则。)

  • printf出于兼容性目的可以使用...因为显式设计允许使用旧的 C 程序并将它们慢慢升级到 C++。但是您不应该使用它编写新的结构或代码,如果您想了解一些基本原理,请阅读简短的论文Learning Standard C++ as a New Language。它本身就是一篇旧论文,但它来自 Bjarne Stroustrup,并且很好地解决了这一点。

然而,为什么这种方法通常是错误的“最大”问题是,有比试图将文本代码段抓取到宏中更可靠的方法来做到这一点。许多主题需要研究,例如 C++11 中 lambdas 的使用。但更一般地说,您应该专注于这里似乎是您的愿望,这是日志记录的主题领域。快速搜索标签交叉点可以为您提供很好的建议:

搜索查询[c++] [logging] __FILE__

如何摆脱这个并编译?

在流程中引入中间步骤。

  1. 摆脱这个......(代码!)
  2. 阅读我提供的链接。
  3. 查看用于实现此目标的方法,并评估您喜欢或不喜欢它们的哪些方面。
  4. 编写使用更好实践的新代码,或从其他人那里借鉴。
  5. ...并编译。:-)
于 2015-03-21T09:40:57.790 回答
3

在调用宏之后删除分号,或者只是更改宏以删除 printf(out) 之后的分号。

当宏引起这样的错误时,它们尤其不方便。因为宏像查找+复制+粘贴一样被直接替换,所以有时会导致没有意义的结果。

#include <iostream>
#include <cstdio>
using namespace std;
#define $ DEBUG
#define DEBUG 1
#define _(out) do{  std::cout << __FILE__ << ":" << __LINE__ \
                       << " " << out << '\n';}while(0)
#define _(out) printf(out);
int main(){

#ifdef LOCAL_PROJECT
    #define DEBUG 0
#endif

    $ && ({
        _("eeeeewe")
    });//line 19

    return 0;
}
于 2015-03-21T08:23:39.653 回答