Inline Function là gì?
Inline function: Gợi ý compiler thay thế lời gọi hàm bằng thân hàm (code substitution), tránh overhead gọi hàm (push/pop stack, jump).
Cú pháp
inline int binhPhuong(int x) {
return x * x;
}
// Hoặc với static (file-scope)
static inline int binhPhuong(int x) {
return x * x;
}
Chương trình ví dụ
#include <stdio.h>
inline int nhan(int a, int b) {
return a * b;
}
int main() {
int x = 5, y = 6;
int kq = nhan(x, y); // Có thể được thay bằng: x * y
printf("%d * %d = %d\n", x, y, kq);
return 0;
}
Kết quả
5 * 6 = 30
Khi nào compiler THỰC HIỆN inline?
Từ khóa inline chỉ là gợi ý (hint), compiler quyết định:
- Inline: Hàm nhỏ, đơn giản, không đệ quy, không vòng lặp phức tạp
- Không inline: Hàm lớn, đệ quy, có vòng lặp nhiều, lấy địa chỉ hàm (
&func), virtual function (C++)
Inline vs Macro
| Đặc điểm | Inline Function | Macro (#define) |
|---|---|---|
| Kiểm tra kiểu | Có (type safety) | Không (text substitution) |
| Đánh giá đối số | 1 lần | Nhiều lần (bug tiềm ẩn) |
| Debug | Dễ (có symbol) | Khó (không có symbol) |
| Scope | Tuân theo quy tắc scope | Global từ điểm define |
| Overhead | 0 nếu inline thành công | 0 (luôn thay thế) |
Ví dụ bug Macro vs Inline
// Macro nguy hiểm
#define BINH_PUONG(x) ((x) * (x))
// Inline an toàn
inline int binhPhuong(int x) {
return x * x;
}
int main() {
int i = 5;
printf("Macro: %d\n", BINH_PUONG(i++)); // 5*6=30 (i++ đánh giá 2 lần!) -> i=7
printf("Inline: %d\n", binhPhuong(i++)); // 7*7=49 (i++ đánh giá 1 lần) -> i=8
return 0;
}
Static Inline (Header-only)
Để dùng inline trong header cho nhiều file .c:
// math_utils.h
#ifndef MATH_UTILS_H
#define MATH_UTILS_H
static inline int max(int a, int b) {
return a > b ? a : b;
}
static inline int min(int a, int b) {
return a < b ? a : b;
}
#endif
static inline: Mỗi file .c có bản copy riêng, không gây multiple definition- Phù hợp cho hàm nhỏ, dùng chung nhiều file
- C99:
inlinekhông static → cần một file .c định nghĩaextern inline
Compiler Optimization
Compiler hiện đại (GCC, Clang, MSVC) tự động inline hàm nhỏ khi bật tối ưu hóa (-O2, -O3, -Os) ngay cả khi không có từ khóa inline.
// GCC
gcc -O2 -finline-functions main.c // Tự động inline
gcc -O3 main.c // Tích cực hơn
Khi nào NÊN dùng inline?
- Hàm nhỏ, gọi thường xuyên (getter/setter, toán tử đơn giản)
- Hàm trong header (static inline)
- Thay thế macro phức tạp
- Performance-critical code (sau khi profile)
Khi nào KHÔNG nên dùng?
- Hàm lớn (làm phình binary - code bloat)
- Hàm đệ quy
- Cần lấy địa chỉ hàm:
func_ptr = &my_func; - Hàm có static variable bên trong (mỗi bản inline có bản copy riêng)
Tóm tắt
inline= gợi ý, không bắt buộc- Ưu tiên
static inlinetrong header - An toàn hơn macro (type checking, evaluate once)
- Compiler hiện đại tự inline tốt hơn tay
- Dùng
__attribute__((always_inline))(GCC/Clang) nếu BUỘC phải inline