3 điểm bởi GN⁺ 2025-05-31 | Chưa có bình luận nào. | Chia sẻ qua WhatsApp
  • C3 được xây dựng dựa trên ngôn ngữ C, đồng thời cung cấp các tính năng nâng cao như module, nạp chồng toán tử, generic, thực thi tại thời điểm biên dịch
  • Vẫn giữ cú pháp C quen thuộc, nhưng bổ sung các cú pháp tăng năng suất và độ an toàn như xử lý lỗi, defer, foreach
  • Việc đưa vào hợp đồng khai báo (contracts) cùng kiểu tùy chọn và cơ chế xử lý lỗi giúp tăng độ an toàn và tính rõ ràng
  • Hỗ trợ môi trường phát triển thực dụng như thư viện chuẩn và tích hợp hệ thống build, cấp phát bộ nhớ tạm thời
  • Có nhiều điểm tương đồng với ngôn ngữ Zig ở build, tạo project, cấu trúc mã nguồn, cho thấy những thử nghiệm mới trong thiết kế ngôn ngữ

Tổng quan và đặc điểm của C3

C3 là gì?

  • C3 là một ngôn ngữ được xây dựng trên nền C, vừa giữ lại cú pháp quen thuộc vừa cung cấp các tính năng mà C khó hỗ trợ như hệ thống module, nạp chồng toán tử, generic, thực thi tại thời điểm biên dịch, xử lý lỗi, defer, value methods, contracts tăng dần, slice, foreach, hỗ trợ kiểu động
  • Cấu trúc module dùng namespace để ngăn xung đột tên (dùng namespace dạng mệnh lệnh như abc::Context)
  • Mục tiêu chính là tăng năng suất và cung cấp các tính năng hiện đại cho lập trình hệ thống một cách an toàn

Đặc điểm ngôn ngữ

Ví dụ Hello World

  • Về cú pháp, khá giống C
  • Khai báo hàm phải dùng tường minh từ khóa fn
  • Các hàm thư viện chuẩn như nhập/xuất rất mạnh, có thể in trực tiếp nhiều kiểu dữ liệu khác nhau

Vòng lặp foreach

  • Khác với C, hỗ trợ sẵn cú pháp foreach
  • Khi lặp qua tham chiếu, thêm & trước tên biến (tính năng nâng cao)
  • Hỗ trợ break, continue, tương tự foreach ở các ngôn ngữ khác

Vòng lặp while

  • Trước C99, không thể khai báo biến bên trong điều kiện while, nhưng trong C3 thì có thể

enum và câu lệnh switch

  • switch hỗ trợ break ngầm định (việc trộn break ngầm định/tường minh có thể gây tranh cãi)
  • Từ khóa nextcase hỗ trợ chuyển case rõ ràng (giúp hiện thực bảng nhảy dễ hơn)
  • Có thể điều khiển luồng switch-case ngắn gọn hơn so với Zig, C và các ngôn ngữ cũ
Quảng cáo

Từ khóa defer

  • Khi scope kết thúc, các câu lệnh đã đăng ký bằng defer sẽ được thực thi theo thứ tự ngược lại, giúp dọn dẹp tài nguyên an toàn
  • Có thể dùng defer kết hợp với catch, try để điều khiển luồng xử lý lỗi

struct và union

  • Cho phép sub-struct/union có tên hoặc ẩn danh bên trong struct, giúp thiết kế mẫu tagged union dễ hơn
  • Phân biệt chặt chẽ giữa dạng ẩn danh (trùng tên field) và xung đột tên

Cơ chế xử lý lỗi

  • Hỗ trợ kiểu tùy chọn bằng dấu ?, kết hợp lỗi và giá trị tùy chọn để tăng tính tiện dụng
  • Từ khóa catch cho phép rẽ nhánh khi gặp trạng thái rỗng (không có Optional) hoặc lỗi
  • So với Rust, Zig thì ranh giới giữa lỗi và giá trị tùy chọn kém rõ hơn (ưu điểm: đơn giản, nhược điểm: giảm độ minh bạch về mục đích)
  • Có thể lan truyền ngoại lệ bằng toán tử ! (rethrow)

Contracts

  • Điều kiện trước/sau của hàm (Require/Ensure) được viết giữa <* .. *> (điều kiện được kiểm tra khi biên dịch)
  • Hỗ trợ cả phân tích fold tại thời điểm biên dịch (phân tích tĩnh vẫn chưa được hiện thực)

Phương thức của struct

  • Dùng kiểu được chỉ rõ + ký pháp dấu chấm (Foo.next) để tạo phương thức liên kết, có namespace riêng (kể cả với kiểu nguyên thủy)
  • Cho phép gắn phương thức lên mọi kiểu như struct/union/enum

Macro

  • Macro dựa trên việc đánh giá tại thời điểm biên dịch (từ khóa macro)
  • Dùng $ cho tham số tại thời điểm biên dịch, # để truyền trước khi đánh giá
  • Phong cách C (giảm vấn đề macro rối rắm, nhấn mạnh tính ổn định của AST, kiểm tra tiền tố @, v.v.)
  • Reflection kiểu và thực thi lúc biên dịch được xử lý qua macro
Quảng cáo

Thuộc tính kiểu

  • alignof, kindof, extnameof, sizeof, typeid, methodsof, has_tagof, tagof, is_eq, is_ordered, is_substruct v.v.
  • Phù hợp cho metaprogramming và reflection

Literal Base64/Hex

  • Có thể khai báo trực tiếp chuỗi byte dưới dạng b64"..." hoặc x"..."
  • Có thể thay thế bằng macro tích hợp $embed (trong thực tế ít dùng)

Kiểu nguyên thủy

  • Có nhiều kiểu cơ bản như int, uint, char (luôn unsigned), bool, float, int128/uint128
  • Có các kiểu riêng cho con trỏ/kích thước như iptr, uptr, isz, usz (hơi kém trực quan)
  • Khác với C, kích thước bit được đảm bảo

Khác

  • Tích hợp bộ tính năng rộng như nạp chồng toán tử, subtyping cho struct, generic, runtime dispatch, kiểu any, bitstructs

Thực hành: trải nghiệm với C3

Cài đặt C3

  • Hỗ trợ hai cách: dùng binary dựng sẵn từ trang chính thức hoặc tự build từ mã nguồn
  • Cần cài LLVM, LLD (nếu gặp lỗi liên kết có thể dùng cờ CMake -DLLVM_DIR, -DLLD_DIR)
  • Do một số bản phân phối không kèm thư viện LLD, nên khuyến nghị tải binary trực tiếp
  • Trình biên dịch C3 cần phụ thuộc libtinfo
Quảng cáo

Tạo project

  • Lệnh c3c init tạo cấu trúc thư mục chuẩn (LICENSE/README.md/project.json/src v.v.)
  • Thiết lập project cơ bản gồm Bluild, mục tiêu build, cấu hình mã nguồn... (tương tự Zig, Cargo)
  • File main.c3 mặc định rất ngắn gọn (đánh giá: phù hợp cho người mới)

Làm máy tính bỏ túi

Thiết kế và mục tiêu

  • Hiện thực recursive descent parser và logic cốt lõi của máy tính bỏ túi để thực hành nhiều cú pháp của C3 như hàm, nhập xuất, quản lý bộ nhớ, vòng lặp
  • Mục tiêu là tự đánh giá các điểm trực quan, năng suất thực tế cũng như những điểm bất tiện của ngôn ngữ

Xử lý đầu vào

  • Dùng @pool để sử dụng allocator tạm thời (tmem), tự động giải phóng bộ nhớ khi scope kết thúc (arena allocator)
  • Hỗ trợ hai cơ chế quản lý bộ nhớ chuẩn: tmem (tạm thời), mem (thông thường), cùng mẫu truyền allocator theo hàm (kết hợp ưu điểm của Zig và C)
  • Hàm main bắt buộc phải khai báo giá trị trả về (được compiler ép buộc)
  • Những hàm có thể bỏ qua giá trị trả về được đánh dấu bằng thuộc tính @maydiscard (ngăn việc bỏ qua một cách tùy tiện)

Hiện thực tokenizer

  • Phân tách đầu vào của người dùng thành danh sách token
  • Tận dụng List trong thư viện chuẩn C3, cú pháp foreach, switch-case (nextcase, kết hợp break ngầm định/tường minh) và nhiều cấu trúc điều khiển khác
  • Cú pháp slice (bao gồm cả chỉ số đầu và cuối) và vấn đề slice độ dài 0 có thể gây nhầm lẫn (có cú pháp riêng để chỉ định độ dài)
  • Việc trộn allocator tạm thời/thông thường cho thấy quản lý bộ nhớ minh bạch và linh hoạt, vượt trội hơn một số ngôn ngữ khác như Rust

Hiện thực parser

  • Trải nghiệm tự viết parser (lược bỏ)

Kết luận và đánh giá tổng hợp

  • C3 theo đuổi điểm giao giữa ngôn ngữ hệ thống truyền thống và thiết kế hiện đại
  • Được thiết kế như một ngôn ngữ dung hòa hiệu năng và độ ổn định của mã, có tham khảo Zig, Rust, C
  • Nổi bật ở tính mô-đun, xử lý bộ nhớ/lỗi/contracts an toàn, metaprogramming mạnh, hệ thống build trực quan
  • Độ dốc học tập với người đã biết C là tương đối dễ tiếp cận theo từng bước
  • Hệ sinh thái như language server, IDE còn chưa trưởng thành, và một số cú pháp vẫn có thể gây chia rẽ, cần tiếp tục cải thiện
  • Đây là một ngôn ngữ thay thế thế hệ mới đáng chú ý cho công việc low-level/lập trình hệ thống trong thực tế

Chưa có bình luận nào.

Chưa có bình luận nào.