简单的c++程序得到编译错误

Simple c++ program gets compilation errors

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

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 的简单名称,在运行时它是 01.

此源文件的编译错误。 如何摆脱它并进行编译?

去掉宏调用后的分号,或者直接修改宏去掉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;
}

有些你在这里做的事情是不可取的,有些是非法的。但是我给了你一个 upvote 至少提醒我 gcc extension I hadn't seen:

#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: warning: ISO C++ forbids braced-groups within expressions [-Wpedantic]

现在我们已经一起学习了,请避免使用非标准扩展。部分原因是 Whosebug 上的人会对你大吼大叫。但主要是因为当你坚持已经达成一致并经过大量思考问题的人审查的子集时,生活已经足够艰难,试图在语言发展、教育和使用中找到土地。

(对于 "that one guy" 或 "that project" 的任何定义,"language feature that one guy added that time for that project" 可能是个坏主意。)

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


继续:

  • 在标识符名称 is apparently "implementation-defined behavior" 中使用 $。这意味着规范中没有任何内容不允许它……但也没有说编译器必须实现它。它可能不是你想要发明新的创造性用途的东西,并且只有当你陷入与 VAX 或其他东西上的旧代码桥接的情况时才使用它。

  • 另一方面,你只是you can't name any global variables or macros starting with an underscore。它们保留供编译器实现自己使用。 (如果你阅读了所有内容,你会发现其他不寻常的细微差别,例如你不能在任何范围内使用以下划线开头且后跟大写字母的标识符,尽管如果字母是小写字母你可以在本地定义它们。通常人们将其用于成员变量,但必须小心遵守规则。)

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

然而,"biggest" 为什么这种方法通常是错误的问题在于,有比尝试将文本代码段抓取到宏中更可靠的方法来做到这一点。许多主题需要研究,例如在 C++11 中使用 lambda。但更一般地说,您应该关注您似乎想要的东西,这是 logging 的主题领域。快速搜索标签交集可以为您提供很好的建议:

Search Query for [c++] [logging] __FILE__

how to get rid of this and compile?

在过程中引入中间步骤。

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