简单的c ++程序会出现编译错误

时间:2015-03-21 08:12:08

标签: c++ logging macros gcc-extensions

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

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

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

2 个答案:

答案 0 :(得分:3)

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

当它们导致这样的错误时,宏特别不方便。因为宏直接被替换为find + copy + paste,所以它有时会导致结果不合理。

#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;
}

答案 1 :(得分:3)

你在这里做的一些事情是不可取的,有些是违法的。但是我给了你一个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:警告:ISO C ++禁止在表达式中使用支撑组[-Wpedantic]

然而,现在我们已经将我们的学习时刻放在一起,避免非标准的扩展。部分原因是因为StackOverflow上的人会对你大喊大叫。但主要是因为生活很难在语言发展,教育和使用方面寻找土地,因为你坚持已经商定并经过大量思考这些问题的人审查的子集。

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

此外,类似的东西 - 很少使用 - 可能在优化器中有各种各样的缺乏关注表达式。这意味着它最好比其他方式慢,最糟糕的是它有随机错误。


继续前进:

  • 在标识符名称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并且非常适合这一点。

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

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

  

如何摆脱这个并编译?

在流程中引入中间步骤。

  1. 摆脱这个......(代码!)
  2. 仔细阅读我提供的链接。
  3. 了解用于实现此目标的方法,并评估您喜欢或不喜欢的目标。
  4. 编写使用更好实践的新代码,或借用其他代码。
  5. ...并编译。 : - )