Ba định danh này cung cấp tên hàm tại compile-time, nhưng mức độ chi tiết khác nhau.
Bảng so sánh
| Định danh | Chuẩn | Nội dung | Ví dụ output |
|---|---|---|---|
__func__ | C99, C++11 | Tên hàm đơn giản | "main" |
__FUNCTION__ | GCC/MSVC extension | Tên hàm đơn giản | "main" |
__PRETTY_FUNCTION__ | GCC/Clang extension | Chữ ký đầy đủ (class, template, const, params) | "void MyClass::func(int) const" |
Ví dụ minh họa
#include <iostream>
class MyClass {
public:
void ClassMethod() const {
std::cout << "__func__: " << __func__ << '\n';
std::cout << "__FUNCTION__: " << __FUNCTION__ << '\n';
std::cout << "__PRETTY_FUNCTION__: " << __PRETTY_FUNCTION__ << '\n';
}
};
template <typename T>
void TemplateFunc(T) {
std::cout << "__PRETTY_FUNCTION__: " << __PRETTY_FUNCTION__ << '\n';
}
void RegularFunc() {
std::cout << "__func__: " << __func__ << '\n';
}
int main() {
std::cout << "=== main ===\n";
std::cout << "__func__: " << __func__ << '\n';
RegularFunc();
MyClass obj;
obj.ClassMethod();
TemplateFunc(42);
}
Kết quả (GCC/Clang)
=== main === __func__: main __func__: RegularFunc __func__: ClassMethod __FUNCTION__: ClassMethod __PRETTY_FUNCTION__: void MyClass::ClassMethod() const __PRETTY_FUNCTION__: void TemplateFunc(T) [with T = int]
Ứng dụng: Logging chi tiết
// Macro log portable
#if defined(__GNUC__) || defined(__clang__)
#define FUNC_SIG __PRETTY_FUNCTION__
#else
#define FUNC_SIG __FUNCTION__
#endif
#define LOG(msg) std::cerr << "[" << FUNC_SIG << "] " << msg << '\n'
void process(int id) {
LOG("Processing id: " + std::to_string(id));
}
Lưu ý
__func__là duy nhất chuẩn (C99, C++11) — portable nhất__PRETTY_FUNCTION__cực hữu ích cho debug template, overload, const member- MSVC: Dùng
__FUNCSIG__thay cho__PRETTY_FUNCTION__ - Không tốn chi phí runtime (là string literal compile-time)
Tóm tắt
- Portable:
__func__ - Chi tiết (GCC/Clang):
__PRETTY_FUNCTION__ - MSVC chi tiết:
__FUNCSIG__ - Dùng cho: Logging, debug, profiling, error reporting