我在 Windows 机器上使用 Eclipse 4.2、CDT 和 MinGW 工具链(尽管我感觉问题与此特定配置无关)。 G++编译器是4.7
我正在使用 c++11 功能,代码如下:
#include <iostream>
#include <iomanip>
#include <memory>
#include <vector>
#include <list>
#include <algorithm>
using namespace std;
int main( int argc, char* argv[] )
{
vector<int> v { 1, 2, 3, 4, 5, 6, 7 };
int x {5};
auto mark = remove_if( v.begin(), v.end(), [x](int n) { return n<x; } );
v.erase( mark, v.end() );
for( int x : v ) { cout << x << ", "; }
cout << endl;
}
一切都非常直接且符合 C++11 习惯。代码在命令行上编译没有问题 (g++ -std=c++11 hello.cpp)。
为了使这段代码在eclipse中编译,我将编译器设置为支持C++11:
- 属性 -> C/C++ 构建 -> 设置 -> 其他 -> 其他标志:
我添加 -std=c++11
- 属性 -> C/C++Build -> 发现选项 -> 编译器调用参数:
添加-std=c++11
这是我对全局首选项或项目属性所做的唯一更改。
第一个问题:为什么我必须在两个地方更改标志?何时使用每个编译器标志?
如果我按 Ctrl-B,项目将按预期成功构建,并从 eclipse 中运行它,显示预期结果(打印:“5,6,7”)。
但是,编辑器视图在“remove_if”行和“v.erase”行上都显示红色错误标记。同样,问题视图显示我遇到了这两个问题。看看问题的细节,我得到:
- 对于remove_if行:'无效的参数。候选者是:#0 remove_if(#0, #0, #1)
- 对于擦除行:“无效参数候选者是:”?擦除(?),?擦除(?,?)'
第二个问题:似乎有两种不同的构建:一种用于继续状态,另一种用于实际构建。是对的吗?如果是这样,它们是否有不同的规则(编译标志、包含路径等)?
第三个问题:在问题详细信息中我还看到:“索引器发现的名称解析问题”。我想这就是错误消息如此神秘的原因。这些消息是来自 MinGW g++ 编译器还是来自 Eclipse?这个名称解析是什么?我该如何修复?
感谢你的帮助。
编辑(回复@Eugene):谢谢尤金。我在 Eclipse 上打开了一个错误。我认为 C++11 只是部分原因。我已经清除了代码中的 C++11 内容,并从两个编译开关中删除了 -std=c++11 标志。然而,CodAn 在remove_if 行上咆哮:
int pred( int n ) { return n < 5; }
int main( int argc, char* argv[] )
{
vector<int> v;
for( int i=0; i<=7; ++i ) {
v.push_back( i );
}
vector<int>::iterator mark = remove_if( v.begin(), v.end(), pred );
v.erase( mark, v.end() );
for( vector<int>::iterator i = v.begin(); i != v.end(); ++i ) {
cout << *i << ", ";
}
cout << endl;
}
代码编译得很好(使用 Ctrl-B),但 CodAn 不喜欢 remove_if 行,说:参数无效,候选者为“#0 remove_if(#0,#0,#1)”。
这是一条非常神秘的消息 - 看起来它错过了替换格式字符串中的参数(#0 代表“迭代器”,#1 代表“谓词”)。我要去更新这个bug了
有趣的是,使用“列表”而不是“向量”可以消除错误。
然而,至于我的问题,我很好奇 CodAn 是如何工作的。它是否使用 g++(带有一组自定义的标志)或其他外部工具(lint?),还是在 Java 内部执行此操作?如果有一个工具,我如何获取它的命令行参数及其输出?