Trong bài này mình sẽ giới thiệu một số lỗi biên dịch thường gặp khi biên dịch chương trình C/C++ bằng trình biên dịch GCC trên Linux/Unix và cách khắc phục.
1. undefined reference to ***
Đây là lỗi linker, xuất hiện khi linker không thể tìm thấy symbol đã được sử dụng. Thông thường nó hay xảy ra khi các hàm của một thư viện nào đó được sử dụng trong source code nhưng thư viện đó không được link.
Để thực hiện link một thư viện nào đó thì config như sau →
Với qmake
C++ LIBS += nameOfLib
Với cmake
C++ TARGET_LINK_LIBRARIES(target nameOfLib)
1 | TARGET_LINK_LIBRARIES(target nameOfLib) |
Lệnh g++
C++ g++ -o main main.cpp -LdirOfLibrary -lnameOfLib
1 | g++-omain main.cpp-LdirOfLibrary-lnameOfLib |
hoặc link trực tiếp bằng cách chỉ định file obiect như sau
C++ g++ -o main main.o functionsModule.o
1 | g++-omain main.ofunctionsModule.o |
functionsModule.o là file object chứa code của function được sử dụng bởi main.o
2. error: *** was not declared in this scope
Lỗi này xảy ra khi một biến hoặc hàm không xác định nào đó được sử dụng.
— Trường hợp lỗi xảy ra với ‘biến’
Compiling error →
C++ #include <iostream> int main(int argc, char *argv[]) { { int i = 2; } std::cout << i << std::endl; // i is not in the scope of the main function return 0; }
12345678910 | #include <iostream> intmain(intargc,char*argv[]){{inti=2;}std::cout<<i<<std::endl;// i is not in the scope of the main functionreturn0;} |
Fix →
C++ #include <iostream> int main(int argc, char *argv[]) { { int i = 2; std::cout << i << std::endl; } return 0; }
12345678910 | #include <iostream> intmain(intargc,char*argv[]){{inti=2;std::cout<<i<<std::endl;}return0;} |
— Trường hợp lỗi xảy ra với ‘hàm’
Thường xảy ra khi thiếu include header files (ví dụ sử dụng
std::cout mà không có
#include <iostream>) hoặc gọi hàm mà chưa có khai báo (hoặc định nghĩa) của hàm đó trước khi sử dụng, ví dụ :
Compiling error →
C++ #include <iostream> int main(int argc, char *argv[]) { doCompile(); return 0; } void doCompile() { std::cout << "No!" << std::endl; }
123456789101112 | #include <iostream> intmain(intargc,char*argv[]){doCompile();return0;} voiddoCompile(){std::cout<<"No!"<<std::endl;} |
Fix →
C++ #include <iostream> void doCompile(); // forward declare the function int main(int argc, char *argv[]) { doCompile(); return 0; } void doCompile() { std::cout << "No!" << std::endl; }
1234567891011121314 | #include <iostream> voiddoCompile();// forward declare the function intmain(intargc,char*argv[]){doCompile();return0;} voiddoCompile(){std::cout<<"No!"<<std::endl;} |
hoặc C++ #include <iostream> void doCompile() // define the function before using it { std::cout << "No!" << std::endl; } int main(int argc, char *argv[]) { doCompile(); return 0; }
123456789101112 | #include <iostream> voiddoCompile()// define the function before using it{std::cout<<"No!"<<std::endl;} intmain(intargc,char*argv[]){doCompile();return0;} |
Note: Về cơ bản compiler biên dịch code từ trên xuống dưới. Tất cả mọi thứ đều phải được khai báo (hoặc định nghĩa) trước khi sử dụng.
3. fatal error: ***: No such file or directory
Compiler không tìm thấy file. Ví dụ trong 1 file source có #include “someFile.h” nhưng compiler không tìm thấy file “someFile.h” đâu cả. Trường hợp này chúng ta cần bổ sung thông tin config để compiler có thể tìm thấy file cần thiết.
Với qmake
C++ INCLUDEPATH += dir/Of/File
1 | INCLUDEPATH+=dir/Of/File |
Với cmake
C++ include_directories(dir/Of/File)
1 | include_directories(dir/Of/File) |
Lệnh g++
C++ g++ -o main main.cpp -Idir/Of/File
1 | g++-omain main.cpp-Idir/Of/File |
— Phạm Minh Tuấn (Shun) —
Xem thêm: