Я использую Eclipse 4.2 с CDT и инструментальной цепочкой MinGW на компьютере с Windows (хотя у меня есть ощущение, что проблема не имеет ничего общего с этой конкретной конфигурацией). Компилятор G++ версии 4.7.
Я играю с функциями С++ 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++ -> Настройки -> Разное -> Флаги Ohter:
я добавляю -std=c++11 - Свойства -> Сборка C/C++ -> Параметры обнаружения -> Аргументы вызова компилятора:
Добавление -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 для «предиката»). Я собираюсь обновить ошибку.
Интересно, что использование «списка» вместо «вектора» устраняет ошибку.
Однако, что касается моего вопроса, мне любопытно, как работает CodAn. Использует ли он g++ (с настроенным набором флагов) или другой внешний инструмент (lint?), или он делает это внутри Java? Если есть инструмент, как я могу получить его аргумент командной строки и его вывод?