ฉันใช้ Eclipse 4.2 กับ CDT และ Toolchain MinGW บนเครื่อง Windows (แม้ว่าฉันจะรู้สึกว่าปัญหาไม่เกี่ยวข้องกับการกำหนดค่าเฉพาะนี้) คอมไพเลอร์ 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++ -> การตั้งค่า -> เบ็ดเตล็ด -> ธง Ohter:
ฉันกำลังเพิ่ม -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)
- สำหรับบรรทัดลบ: 'ข้อโต้แย้งที่ไม่ถูกต้องผู้สมัครคือ: '? ลบ(?), ? ลบ(?,?)'
คำถามที่สอง: ดูเหมือนว่ามีบิลด์ที่แตกต่างกัน 2 บิลด์: บิลด์หนึ่งสำหรับสถานะดำเนินการต่อ และอีกบิลด์สำหรับบิลด์จริง นั่นถูกต้องใช่ไหม? หากเป็นเช่นนั้น พวกเขามีกฎที่แตกต่างกันหรือไม่ (แฟล็กการคอมไพล์ รวมพาธ ฯลฯ)
คำถามที่สาม: ในรายละเอียดของปัญหา ฉันยังเห็น: 'ปัญหาการแก้ไขชื่อที่พบโดยตัวสร้างดัชนี' ฉันเดาว่านี่คือเหตุผลว่าทำไมข้อความแสดงข้อผิดพลาดจึงเป็นความลับ ข้อความเหล่านั้นมาจากคอมไพเลอร์ MinGW g++ หรือจาก Eclipse ความละเอียดของชื่อนี้คืออะไร? ฉันจะแก้ไขได้อย่างไร?
ขอบคุณที่คุณช่วย.
แก้ไข (ตอบกลับ @Eugene): ขอบคุณ 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 สำหรับ 'เพรดิเคต') ฉันจะอัปเดตข้อผิดพลาด
สิ่งที่น่าสนใจคือการใช้ 'list' แทน 'vector' จะช่วยล้างข้อผิดพลาด
อย่างไรก็ตาม สำหรับคำถามของฉัน ฉันอยากรู้ว่า CodAn ทำงานอย่างไร มันใช้ g++ (พร้อมชุดแฟล็กที่กำหนดเอง) หรือเครื่องมือภายนอกอื่น (lint?) หรือทำภายในใน Java หรือไม่ หากมีเครื่องมือ ฉันจะรับอาร์กิวเมนต์บรรทัดคำสั่งและเอาต์พุตของมันได้อย่างไร