Static, this và const: xác định thứ gì dùng chung và thứ gì bị giữ cố định

Khoảng 50 phútMức 1/3Bản nháp: một số khẳng định chưa đối chiếu spec

Sau bài này bạn sẽ

  • Phân biệt static property với dữ liệu riêng mỗi object
  • Dùng this để chọn field của object hiện tại
  • Giới hạn const theo biến được bảo vệ và ghi rõ giới hạn công cụ

Ba câu hỏi khác nhau về trạng thái

Created đếm tổng số Counter đã tạo; serial gắn với từng object; value có thể thay đổi theo object. Gộp chúng thành một loại biến khiến ID bị lặp, dữ liệu bị chia sẻ hoặc caller hiểu nhầm tính bất biến. Hãy hỏi phạm vi chia sẻ và quyền sửa cho từng field.

Static property có một bản trong class này

Counter.created khởi tạo 0 và tăng một lần trong mỗi constructor. Tạo ba object cho tổng 3; gán alias_handle=first không gọi constructor nên không tăng count. Count này là số lần construction trong ví dụ, không phải số object đang sống, số handle hay một phép đo garbage collection.

[1]

Static method có thể gọi trước khi tạo object

Counter::total() được gọi trước new và trả 0, rồi trả 3 sau ba lần new. Nó đọc static created, không ngầm có một object hiện tại để đọc value. Phân biệt static class method với lifetime của local variable; bài không dùng cú pháp function static hoặc hứa mọi tool hỗ trợ biến thể đó.

This chọn field của object đang nhận call

Constructor nhận formal value rồi gán this.value = value. Method add cũng nhận value và cộng vào this.value. Với first 3 rồi add 4, field thành 7; second được sửa riêng thành 50; third giữ 8. Nếu bỏ this trong phép gán có shadowing, field có thể không nhận input.

Instance const serial được gán trong constructor

Mỗi object có const int serial, được gán lần lượt 1/2/3 từ created trong constructor. Main chỉ ghi serial tại construction rồi đọc để kiểm. Không biến const runtime property thành parameter hoặc compile-time constant; negative parser probe ghi serial sau new phải bị từ chối đúng diagnostic trước khi được báo là đã kiểm.

Const handle không đồng nghĩa mọi dữ liệu phía sau bất biến

Counter.contents là const handle tới Payload. Trong main, một handle thường mutable_view nhận contents rồi sửa object qua mutable_view.data=55; đọc qua first.contents thấy 55. Case đã chạy chỉ chứng minh const handle không tự tạo snapshot hoặc đóng băng object thông qua mọi alias.

Giữ riêng capability probe mà tool chưa chạy được

Probe viết trực tiếp first.contents.data = 55 được pyslang chấp nhận nhưng Verilator 5.050 từ chối với CONSTWRITTEN trước runtime. Giữ nguyên probe và diagnostic ở toolcheck/probes, không tắt diagnostic hoặc gọi direct-member write là pass. Main dùng đường alias nêu rõ ở section trước; điều đó không chứng minh direct syntax được hỗ trợ trên simulator này.

Ba instance, một alias và một view tới payload

Expected tính trước chạy: static total0→3, serial 1/2/3; value 7/50/8; payload thấy 55 qua alias; alias_handle vẫn cùng identity với first. Chỉ claim parse và simulation 2-state của source chính; không claim synthesis, GC timing hoặc full const semantics.

Static, this và const: xác định thứ gì dùng chung và thứ gì bị giữ cố định

Expected tính trước chạy: static total0→3, serial 1/2/3; value 7/50/8; payload thấy 55 qua alias; alias_handle vẫn cùng identity với first. Chỉ claim parse và simulation 2-state của source chính; không claim synthesis, GC timing hoặc full const semantics.

tb.sv testbench
`timescale 1ns/1psclass Payload;  int data;endclassclass Counter;  static int created=0;  const int serial;  int value;  const Payload contents;  function new(int value);    created++;    serial=created;    this.value=value;    contents=new();  endfunction  function void add(int value);    this.value+=value;  endfunction  static function int total();    return created;  endfunctionendclassmodule tb_static;  Counter first,second,third,alias_handle;  Payload mutable_view;  initial begin    if(Counter::total()!=0)$fatal(1,"static call before construction");    first=new(3);second=new(5);third=new(8);alias_handle=first;    second.value=50;first.add(4);    mutable_view=first.contents;mutable_view.data=55;    if(Counter::total()!=3||first.serial!=1||second.serial!=2||third.serial!=3)      $fatal(1,"static count or per-object const serial");    if(first.value!=7||second.value!=50||third.value!=8||alias_handle!=first||alias_handle.value!=7||first.contents.data!=55)      $fatal(1,"this binding, instance storage or const-handle target");    $display("STATIC CHECK before=0 created=3 serials=1/2/3 values=7/50/8 const_handle_data=55 alias_same=1");    $finish;  endendmodule

Đã kiểm chứng thế nào

  • Phân tích và elaborate theo LRM (pyslang 12.1.0)
  • Mô phỏng, exit 0 và output khớp kỳ vọng tính tay (Verilator 5.050, 2-state)

Output phải khớp: STATIC CHECK before=0 created=3 serials=1/2/3 values=7/50/8 const_handle_data=55 alias_same=1

Chỉ source và self-check đã nêu, Verilator 2-state; không claim X/Z, synthesis, garbage-collection timing hoặc đầy đủ mọi class feature.

Main sửa payload qua mutable alias của const handle. Probe direct-member write được pyslang chấp nhận nhưng Verilator CONSTWRITTEN/buildfail; không claim syntax đó simulated.

Các kiểm tra chạy lúc xây dựng nội dung (2026-11-06), không chạy trong trình duyệt. Kỳ vọng được tính tay trước khi chạy.

[2]

Tự kiểm tra

Tự kiểm tra: static-this-const

  1. Tạo ba Counter rồi gán alias_handle=first. Created bằng bao nhiêu?
  2. Main có làm data trong object được contents trỏ tới thành 55 không?
  3. First value 3 gọi add(4), còn second được sửa 50. Values cuối là gì?
  4. Counter::total() được gọi trước new trả gì trong main?
  5. Direct-write probe được parser chấp nhận nhưng Verilator CONSTWRITTEN. Báo thế nào?

Ghi rõ sharing và mutability riêng cho từng lớp dữ liệu

Dùng static cho dữ liệu thực sự dùng chung, this cho receiver hiện tại và const cho binding/field cần bảo vệ. Khi cần transaction bất biến, phải review cả alias tới object bên trong. Một const handle đơn lẻ không thay thế ownership hoặc deep-copy contract.

Nguồn và mức độ đối chiếu

  1. SystemVerilog Static Variables & Functions — bản chụp resources.zip, Nguồn đào tạo đã đọc theo section. Trích dẫn; nguồn đã đọc các mục liên quan.
  2. Thí nghiệm nguyên bản ex.b5.static-this-const, Bằng chứng thực nghiệm. Trích dẫn; nguồn đã đọc toàn văn.
  3. IEEE 1800-2023 SystemVerilog LRM, Class handles, construction, static and const properties. Chưa đối chiếu với văn bản nguồn (chưa mở).
  4. Thí nghiệm nguyên bản ex.b5.static-this-const, Source, self-checks, verification.json và mutation/capability probes. Trích dẫn; nguồn đã đọc toàn văn.
  5. SystemVerilog Static Variables & Functions — bản chụp resources.zip, The Default: Each Instance Gets Its Own Copy; Static Variables; Static Functions. Trích dẫn; nguồn đã đọc các mục liên quan.
  6. this keywords in classes — bản chụp resources.zip, Example without this keyword; Example with this keyword; Example for this keyword with static method. Trích dẫn; nguồn đã đọc các mục liên quan.
  7. Constant class properties in SV — bản chụp resources.zip, Global constants; Instance constants. Trích dẫn; nguồn đã đọc các mục liên quan.