Trong thực tế, một macro đối tượng có thể được định nghĩa bằng chính tên của một macro đối tượng khác: #define B A rồi #define A 5. Khi khai triển một token, ta phải thay thế lặp lại cho đến khi token thu được không còn là tên của một macro nào nữa (đạt điểm cố định). Nếu quá trình lặp không bao giờ dừng vì xuất hiện chu trình (ví dụ X được định nghĩa là Y và Y được định nghĩa là X), token đó không có giá trị hữu hạn và cần báo lỗi.
Cho n định nghĩa macro đối tượng (TÊN GIÁ_TRỊ, mỗi TÊN định nghĩa đúng một lần trong toàn bộ dữ liệu vào, GIÁ_TRỊ là một token đơn — có thể là hằng số hoặc tên một macro khác), và m dòng mã nguồn (token cách nhau bởi khoảng trắng). Với mỗi token trong mã nguồn: nếu token là tên một macro, khai triển liên tiếp cho tới khi không còn thay được nữa (kết quả không trùng tên bất kỳ macro nào), rồi thay token gốc bằng kết quả cuối cùng; nếu trong quá trình khai triển token quay lại một tên macro đã gặp trước đó trong chính chuỗi khai triển này (chu trình), thay token gốc bằng chuỗi #ERROR. Token không phải tên macro nào thì giữ nguyên.
Ví dụ: Với #define B A, #define A 5: token B khai triển thành A rồi thành 5. Với #define X Y, #define Y X: token X khai triển ra #ERROR.
TÊN GIÁ_TRỊ (mỗi TÊN xuất hiện đúng một lần trong toàn bộ danh sách định nghĩa).In ra m dòng, mỗi dòng là mã nguồn sau khi khai triển đầy đủ mọi token là tên macro (hoặc #ERROR nếu token đó dẫn tới chu trình vô hạn), các token khác giữ nguyên, cách nhau bởi đúng một khoảng trắng.
Ví dụ:
Đầu vào:
2 1
B A
A 5
code B end
Đầu ra:
code 5 end
Đầu vào:
2 1
X Y
Y X
val = X
Đầu ra:
val = #ERROR
Đang tải editor...