SystemVerilog OOP Mastery · All levels

No Destructors or GC APIs (Handle Lifetime Semantics): Code Examples

Code Examples for No Destructors or GC APIs (Handle Lifetime Semantics).

Code examples

File resource lifecycle: RAII/try-with-resources vs explicit close

systemverilog
// C++: deterministic destructor cleanup
class FileGuard {
  FILE* fp;
public:
  explicit FileGuard(const char* path) { fp = fopen(path, "w"); }
  ~FileGuard() { if (fp) fclose(fp); }
};

void run_cpp() {
  FileGuard g("out.log");
} // auto-close at scope exit

// Java: try-with-resources
try (var in = java.nio.file.Files.newInputStream(java.nio.file.Path.of("in.bin"))) {
  // use stream
}

// SystemVerilog: explicit close protocol
class file_session;
  int fd;
  bit closed;

  function new(string path);
    fd = $fopen(path, "w");
    closed = 0;
  endfunction

  function void close();
    if (!closed && fd) begin
      $fclose(fd);
      closed = 1;
    end
  endfunction
endclass

task use_file();
  file_session s = new("out.log");
  // ... writes ...
  s.close();
  s = null;
endtask

C++/Java can tie cleanup to scope syntax. In SV, cleanup is a normal method you must call in every intended exit path.

Lock handling: RAII lock guards vs explicit acquire/release discipline

systemverilog
// C++: lock_guard auto releases lock
std::mutex m;
void critical_cpp() {
  std::lock_guard<std::mutex> g(m);
  // critical section
}

// SystemVerilog: explicit acquire/release
class lock_user;
  semaphore sem;
  function new(); sem = new(1); endfunction

  task critical_sv(bit fail_fast);
    sem.get(1);
    if (fail_fast) begin
      sem.put(1);
      return;
    end
    // critical section
    sem.put(1);
  endtask
endclass

No destructor means no automatic unlock-on-scope-exit idiom. SV code must explicitly release resources before every return branch.

Related topics