跳轉到內容

GCC 除錯/g++/錯誤

來自 Wikibooks,開放書籍,開放世界

抽象宣告符 'TYPE' 用作宣告

[編輯 | 編輯原始碼]
  • 在 GCC 版本 4.5.1 中找到的訊息
    • 通常與以下內容一起分組
      • 成員 'DATA_MEMBER' 在匿名聚合體中不允許使用建構函式
      • 成員 'DATA_MEMBER' 在匿名聚合體中不允許使用解構函式
      • 成員 'DATA_MEMBER' 在匿名聚合體中不允許使用複製賦值運算子
  • 類或結構體缺少名稱
struct {  // error, no name
   int bar;
};
  • 標頭檔案中包含一個類或結構體,其名稱已在 ifndef、define 語句中使用
#ifndef foo
#define foo
#include <vector>

struct foo {  // error, foo already in use
   std::vector<int> bar;
};

#endif

'VARIABLE' 不能用作函式

[編輯 | 編輯原始碼]
  • 在 GCC 版本 4.5.1 中找到的訊息
  • 確保變數名中不包含下劃線(編譯器怪癖)
  • 在函式定義中,使用相同的名稱作為變數名和函式名
int foo(int baf) { return baf; }
 
int bar(int foo) {
   foo = foo(4);
   return foo; 
}

請求從 'TYPE' 到非標量型別 'TYPE' 的轉換

[編輯 | 編輯原始碼]
  • 在 GCC 版本 4.5.1 中找到的訊息
  • 型別轉換錯誤,查詢缺少 "::" 語法或缺少括號
  • 可能是強制轉換錯誤
  • 類成員函式返回的值與函式宣告的返回型別不匹配
class Foo {
public:
   int x;
};
 
class Bar {
public:
   Foo Maz() { return 0; }  // 0 is of type int, not Foo
};

無法將 'STATEMENT' 轉換為 'bool'

[編輯 | 編輯原始碼]
  • 在 GCC 版本 3.2.3、4.5.1 中找到的訊息
  • 輸入的比較運算子錯誤(例如:使用 "=" 而不是 "==")
  • 呼叫函式的定義使用了不正確的返回型別
// you had: 
foo operator<(const foo & f) const

// instead of:
bool operator<(const foo & f) const
  • 使用無效的引數進行條件語句
string x = "foo";
if (x) cout << "true" << endl;

在類外部宣告 'FUNCTION' 不是定義

[編輯 | 編輯原始碼]
  • 在 GCC 版本 3.2.3、4.5.1 中找到的訊息
  • 嘗試使用 '=' 初始化值,而不是括號
  • 在建構函式和初始化列表之間使用分號或逗號,而不是冒號
  • 在函式定義的主體之前遺漏分號
class Foo 
{
public:
   int bar;
   Foo(int x);
}; 
 
Foo::Foo(int x);  // semicolon ';' needs to be removed
{
   bar = x;
}

'VARIABLE' 的宣告隱藏了引數

[編輯 | 編輯原始碼]
  • 在 GCC 版本 3.2.3、4.5.1 中找到的訊息
  • 重新定義了已經在使用的變數名,可能在函式的引數列表中宣告過
int foo(int bar)
{
   int bar;
   return bar;
}

'TYPE' 不是型別名

[編輯 | 編輯原始碼]
  • 在 GCC 版本 4.5.1 中找到的訊息
    • 在 GCC 版本 3.2.3 中,有時報告為:在 'CHARACTER' 標記之前出現語法錯誤
    • 在 GCC 版本 4.0.1 中,有時報告為:ISO C++ 禁止宣告
      • 例如:ISO C++ 禁止宣告沒有型別的 'vector'
  • 遺漏了物件的名稱限定符或使用指令
ostream & os;  // instead of: std::ostream & os;
  • 確保沒有輸入作用域運算子 "::" 的錯誤,例如:使用 "name:name" 而不是 "name::name"
  • 確保包含了所需的庫
#include <iostream>
// missing vector library include
class Foo {
public:      
   std::vector<int> Bar(std::vector<int> FooBar) { return FooBar; }
};
  • 在包含指令中,標頭檔案列在使用它的檔案之後
// test.h file
#ifndef TEST_H_
#define TEST_H_
std::string bar;
#endif

// test.cpp file
#include "test.h"
#include <iostream>  // error, needed before test.h
using namespace std;

int main()
{
   cout << bar << endl;
   return 0;
}

在 'TOKEN' 標記之前預期 'TOKEN'

[編輯 | 編輯原始碼]
  • 在 GCC 版本 3.2.3、4.5.1 中找到的訊息
    • 在 GCC 版本 3.2.3 中,有時報告為:在 'CHARACTER' 標記之前出現語法錯誤
  • 檢查函式引數中是否缺少逗號或括號
  • 檢查是否缺少分號
    • 例如:在 'TOKEN' 之前預期 ',' 或 ';'
const int MAX = 10  // error

int main() {
   string foo;
   cout << foo.size();
   return 0;
}
  • 可能來自雙重新命名空間定義,或者已經存在於 'using' 指令下的完全限定(例如:std::cout)名稱
  • 可能在 cin/cout 語句中缺少 '<<' 或 '>>' 運算子
int foo = 0, bar = 0;
cin foo >> bar;  // should be: cin >> foo >> bar;

在 'TOKEN' 之前預期主表示式

[edit | edit source]
在 'int' 之前預期為初等表示式
  • 在 GCC 版本 4.5.1 中找到的訊息
    • 在 GCC 3.2.3 版本中報告為:解析錯誤,在 ')' 標記之前
  • 一個可能的原因是在函式呼叫中使用(或保留)型別名稱
int sum(int x, int y) { return (x + y); }

int main() {
   int a = 4, b = 5;
   sum(a, int b); // int is the problem causer
   return 0;
}

在 'TOKEN' 之前預期為非限定識別符號

[edit | edit source]
  • 在 GCC 版本 4.5.1 中找到的訊息
  • 檢查語法是否有遺漏、錯位或錯誤的字元
  • 在 '(' 標記之前預期為非限定識別符號
    • 例如:類名中的括號
class Foo() {
public:
   int x;
};
  • 在 'return' 之前預期為非限定識別符號
    • 例如:條件語句中缺少左花括號
int foo = 3, bar = 2;
if (foo > bar)  // error, no "{"
   cout << foo << endl;
}

將 'TYPE' 賦值給 'TYPE' 時型別不相容

[edit | edit source]
  • 在 GCC 4.5.1 版本中找到的錯誤資訊
  • 您試圖使用字元指標來為字元陣列賦值或初始化
    • 例如:將 'const char*' 賦值給 'char [10]' 時型別不相容
char bar[10];
const char *foo = "ppp";
bar = *foo;  // error

// possible fix, use strcpy from the cstring header:
char bar[10];
const char *foo = "ppp";
strcpy(bar, foo);
  • 不正確地訪問二維陣列的元素
char foo[2][3];
foo[1] = ' '; // error, need both dimensions, eg: foo[1][0] = ' ';

從 'TYPE' 到 'TYPE' 的無效轉換

[edit | edit source]
  • 在 GCC 版本 3.2.3、4.5.1 中找到的訊息
  • 確保沒有遺漏函式名稱的括號
  • 確保為函式傳遞了正確的引數
char foo = 'f';
char bar[] = "bar";
if (strcmp(foo, bar) != 0)
   cout << "Correct answer!";
// strcmp was expecting 2 character pointers, foo doesn't qualify

'TYPE' 和 'TYPE' 型別對二元運算子 'FUNCTION' 的無效運算元

[edit | edit source]
  • 在 GCC 版本 4.5.1 中找到的訊息
  • 您試圖使用加號運算子連線 C 字串引數
// attempting to combine two C-strings
cout << "abc" + "def";

// possible fix: convert 1 argument to a string type
cout << "abc" + string("def");

無效的模板名稱使用

[edit | edit source]
無效的模板名稱 'TEMPLATE' 使用,沒有引數列表
  • 在 GCC 版本 4.5.1 中找到的訊息
    • 通常與以下錯誤資訊配對:在 'TOKEN' 之前預期為非限定識別符號
    • 在 GCC 3.2.3 版本中報告為:在 'CHARACTER' 標記之前出現語法錯誤
  • 函式定義中缺少類名後的型別
template <class T> class Foo {
private:
   int x;
public:
   Foo();
};

template<class T> Foo::Foo() { x = 0; }  // error, should be: Foo<T>::Foo()

不是成員

[edit | edit source]
  • 在 GCC 4.5.1 版本中找到的錯誤資訊
  • 檢查是否缺少標頭檔案包含
例如:'cout' 不是 'std' 的成員
// test.cpp
// file is missing iostream include directive
int main() {
   std::cout << "hello, world!\n";
   return 0;
}

'TYPE' 不是型別

[edit | edit source]
  • 在 GCC 版本 4.5.1 中找到的訊息
    • 在 GCC 3.2.3 版本中報告為:引數 'PARAMETER' 缺少型別說明符
  • 您在函式宣告中誤輸入了模板引數
void foo(int x, vector y);
  • 包含的標頭檔案中沒有包含原始檔中實現它所需的正確庫
    • 例如:您使用 #include "bar.h",但沒有包含 "bar.h" 正常工作所需的 "foo.h"
  • 檢查是否有與 'TYPE' 同名的函式

'CLASS_MEMBER' 在此上下文中是私有的

[edit | edit source]
  • 在 GCC 版本 3.2.3、4.5.1 中找到的訊息
  • 通常以以下格式報告
    • (LOCATION_OF_PRIVATE_DATA_MEMBER) 錯誤:'DATA_MEMBER' 是私有的
    • (LOCATION_OF_CODE_ACCESSING_PRIVATE_DATA) 錯誤:在此上下文中
  • 錯誤資訊通常是由於試圖在類或結構的定義之外訪問類或結構的私有資料成員而導致的
  • 確保友元成員函式名稱沒有拼寫錯誤
class FooBar {
private: int bar;
public: friend void foo(FooBar & f);
};
void fooo(FooBar & f) {  // error
   f.bar = 0;
}
  • 確保只讀函式為類使用 'const' 引數型別
  • 確保修改資料成員的函式不是常量
  • 檢查派生類建構函式是否隱式訪問基類的私有成員
class Foo {
private: Foo() {}
public: Foo(int Num) {}
};
class Bar : public Foo {
public: Bar() {}
// Bar() implicitly accesses Foo's private constructor
};
解決方案 1:使用初始化列表繞過隱式初始化
解決方案 2:將訪問的基類成員設為受保護而不是私有
  • 您試圖透過訪問私有資料來初始化包含的類成員
class Foo {
private: char mrStr[5];
public: Foo(const char *s = "blah") { strcpy(mrStr, s); }
};

class Bar {
private:
   int mrNum;
   Foo aFoo;
public:
   Bar(int n, const Foo &f);
};

// error, attempting to use the Foo class constructor by accessing private data:
Bar::Bar(int n, const Foo &f) : aFoo(f.mrStr) {  // mrStr is private
   mrNum = n;
}

可能的解決方法是,為整個物件賦值,而不是部分賦值

Bar::Bar(int n, const Foo &f) : aFoo(f) {
   mrNum = n;
}

ISO C++ 禁止宣告沒有型別的 'FUNCTION'

[edit | edit source]
  • 在 GCC 3.2.3 和 4.5.1 版本中找到的錯誤資訊
  • 您建立了一個沒有列出返回值型別的函式
Foo() { return 0: }
// should be: int Foo() { return 0: }

多個定義

[edit | edit source]
例如:`main` 的多個定義
  • 在 GCC 版本 4.5.1 中找到的訊息
  • 檢查標頭檔案中是否缺少包含守衛
  • 檢查編譯命令 / makefile 中是否有重複的檔案列表
    • 例如:g++ -o foo foo.cpp foo.cpp
  • 檢查標頭檔案中是否僅有宣告,而不是定義

'CLASS FUNCTION(ARGUMENTS)' 必須有一個類或列舉型別的引數

[edit | edit source]
  • 在 GCC 版本 3.2.3、4.5.1 中找到的訊息
  • 您試圖使用非成員函式訪問類的成員
    • 非成員函式必須顯式地訪問類成員
例如:CLASS_NAME FUNCTION_NAME(CLASS_NAME OBJECT_NAME, ARGUMENTS)
  • 您正在為標準(內建)型別重新定義運算子
class Foo {
public:
   friend int operator+(int x, int y);
};

返回值型別中不能定義新型別

[edit | edit source]
  • 在 GCC 版本 4.5.1 中找到的訊息
    • 在 GCC 3.2.3 版本中報告為
定義 'CLASS' 之後缺少分號
ISO C++ 禁止在返回值型別中定義型別
  • 檢查類定義末尾是否缺少分號
class Foo {
public:
   int x;
}  // Error

沒有匹配的 'FUNCTION' 呼叫

[edit | edit source]
  • 在 GCC 版本 3.2.3、4.5.1 中找到的訊息
  • 確保使用了函式的名稱空間 (using namespace std / std::function())
  • 確保函式名稱沒有拼寫錯誤,括號沒有遺漏
  • 確保函式呼叫使用了正確的引數 / 型別 / 類
  • 如果您使用括號初始化變數,如果變數名稱中包含下劃線,請嘗試刪除它們。有時等號是唯一可行的方式...
  • 您在同一個名稱空間中為變數和函式使用了相同的名稱
string bar() {
   string foo = "blah";
   return foo;
}

int main() {
   string bar;
   bar = bar();  // error, "bar()" was hidden by string initialization
   return 0;
}

沒有匹配的 'FUNCTION' 呼叫

[編輯 | 編輯原始碼]
  • 在 GCC 版本 4.5.1 中找到的訊息
  • 確保沒有在不應該出現的地方使用括號(例如:classname::value() 而不是 classname::value)。
  • 您正在使用字串引數,而函式需要的是 C 字串。
// broken code
ifstream in;
string MrString = "file.txt";
in.open(MrString);

// solution: convert the string to a C-string
ifstream in;
string MrString = "file.txt";
in.open(MrString.c_str());

非常量“VARIABLE”不能用作模板引數。

[編輯 | 編輯原始碼]
  • 在 GCC 版本 3.2.3 中發現的訊息。
    • 在 GCC 版本 4.5.1 中報告為:'VARIABLE' 不能出現在常量表達式中。
  • 變數用於模板引數,模板引數需要在編譯時是常量。
template <class T, int num>
class Bar {
private:
   T Foo[num];
};

int main() {
   int woz = 8;
   Bar<double, woz> Zed;  // error, woz is not a constant
   return 0;
}

非成員函式 'FUNCTION' 不能有 cv 限定符。

[編輯 | 編輯原始碼]
錯誤:非成員函式“int Foo()”不能有 cv 限定符。
cv = 常量 / 易變。
  • 在 GCC 版本 4.5.1 中找到的訊息
  • 您正在對非成員函式使用“後置”常量(常量值)。
  • 您沒有在函式定義中使用作用域限定符(“TYPENAME::”)。
  • 您為模板類的成員函式的定義拼錯了。
template<class Type>
class Foo {
private:
   int stuff;
public:
   int bar() const;
};

template<class Type>
int Foo::bar() const {  // error
   return stuff;
}

可能的解決辦法。

template<class Type>
int Foo<Type>::bar() const {
   return stuff;
}

將 'const OBJECT' 作為 'FUNCTION' 的 'this' 引數傳遞會丟棄限定符。

[編輯 | 編輯原始碼]
  • 在 GCC 版本 4.5.1 中找到的訊息
  • 您正在返回一個地址。
  • 您正在嘗試使用 const_iterator 訪問容器元素,但使用的是沒有非 const 版本的成員函式。非 const 函式不保證它不會更改資料。

請求在“NAME”中使用成員“NAME”,而“NAME”是非類型別“CLASS”。

[編輯 | 編輯原始碼]
  • 在 GCC 4.5.1 版本中找到的錯誤資訊
    • 在 GCC 版本 3.2.3 中報告為
請求在“NAME”中使用成員“NAME”,而“NAME”是非聚合型別“TYPE”。
  • 檢查程式碼中的函式呼叫,它可能正在呼叫帶有錯誤引數的函式,或者可能放置或缺少括號。
  • 您正在使用“*this”指標,而您應該只使用函式名。
  • 例如,使用:return mem_func(); 而不是:return *this.mem_func();
  • 使用帶有錯誤語法的“*this”指標。
class Foo {
public:
   int x;
   Foo(int num = 0) { x = num; }
   void newX(int num);
};

void Foo::newX(int num) {
   *this.newX(num);  // error, need (*this).newX or this->newX
}

語句無法解析過載函式的地址。

[編輯 | 編輯原始碼]
  • 在 GCC 版本 3.2.3、4.5.1 中找到的訊息
  • 確保您沒有忘記成員函式名後面的括號。
class Foo {
public:
   int Bar() { return 0; }
};

int main() {
   Foo x;
   x.Bar;  // error
   return 0;
}

在 'NAME' 的宣告中存在兩個或多個數據型別。

[編輯 | 編輯原始碼]
  • 在 GCC 版本 4.5.1 中找到的訊息
    • 在 GCC 版本 3.2.3 中報告為:多餘的 'TYPE' 被忽略。
  • 您為函式宣告的返回值列出了多個數據型別。
int char sum(int x, int y);  // int char
  • 可能是兩個型別宣告之間缺少分號。
    • 通常在函式、結構體或類宣告之後的花括號 {} 之後缺少。

<GOBBLEDEGOOK> 未定義對 <GOBBLEDEGOOK> 的引用。

[編輯 | 編輯原始碼]
  • 在 GCC 版本 4.5.1 中找到的訊息
    • 在 GCC 版本 4.0.1、4.2.1 中報告為:未定義的符號。
  • 檢查是否有丟失或拼錯的標題檔案包含。
  • 檢查專案/make 檔案中是否有丟失或拼錯的檔案/庫。
  • 檢查是否有丟失、拼錯或未定義的函式或類建構函式。
// header file
void foo();
void bar();
void baz();

// implementation file, bar definition is missing
void foo() { cout << "foo\n"; }
void baz() { cout << "baz\n"; }
  • 檢查函式宣告是否與其定義不匹配。
  • 確保函式名不與現有標題檔案中的函式名重疊。
  • 確保編譯命令語法/makefile 結構正確(例如:g++ -o file.cc ... 等)。
  • 專案/makefile 中的任何檔案中都沒有定義 main() 函式。
    • 例如:未定義對 `WinMain@16` 的引用。

'NAME' 在此作用域中未宣告。

[編輯 | 編輯原始碼]
  • 在 GCC 版本 4.5.1 中找到的訊息
    • 在 GCC 版本 3.2.3 中報告為:'FUNCTION' 未宣告(此函式的首次使用)。
  • 查詢拼錯或更改的變數/函式/標題呼叫名稱。
lonh wait;

// instead of:
long wait;
  • 確保包含了正確的標題檔案和庫檔案。
    • 定義的變數可能需要包含它們使用的標題檔案,這些標題檔案需要包含在所有使用定義的變數的檔案中。
華夏公益教科書