Scope
- Macro
- August 22, 2025
Table of Contents
Scope
Scope
Description
Run a scoped block and automatically deinitialize the object at the end. Executes scope_body
and ensures obj_deinit(obj)
is called afterward, regardless of the block’s control flow. This is similar to RAII-style resource management in C++ but implemented manually via a macro. The object is passed by pointer. It is not copied or moved. This macro ensures the object is only evaluated once by capturing it internally using TYPE_OF
. The memory pointed to by obj
is not cleared after deinitialization; if zeroing is needed, do it inside obj_deinit
. Parameters:
Parameters
Name | Direction | Description |
---|---|---|
obj | in | Pointer to the object to manage. |
obj_deinit | in | Function or macro to deinitialize the object. |
scope_body | in | Block of code that uses the object. MyStruct s = MyStructInit(); Scope(&s, MyStructDeinit, { UseStruct(&s); }); |
Success
Always continues execution after scope.
Failure
Caller must handle errors inside the scoped body.
Usage example (Cross-references)
- In
MisraDoc.c:108
:
Project project = {0};
Scope(&project, ProjectDeinit, {
// read project config
Str config = StrInit();
- In
MisraDoc.c:111
:
// read project config
Str config = StrInit();
Scope(&config, StrDeinit, {
if (!ReadCompleteFile(config_path, &config.data, &config.length, &config.capacity)) {
LOG_FATAL("Failed to read config file.");
- In
MisraDoc.c:121
:
// recursively explore directories and get files that need documentation
Strs file_paths = VecInit();
Scope(&file_paths, VecDeinit, {
// temporary vector to store all directory paths to explore files in
Strs dir_paths = VecInitWithDeepCopy(NULL, StrDeinit);
- In
MisraDoc.c:124
:
// temporary vector to store all directory paths to explore files in
Strs dir_paths = VecInitWithDeepCopy(NULL, StrDeinit);
Scope(&dir_paths, VecDeinit, {
VecMerge(&dir_paths, &project.source_directories);
VecMerge(&dir_paths, &project.test_directories);
- In
MisraDoc.c:135
:
SysDirContents dir_contents = SysGetDirContents(dir_name.data);
Scope(&dir_contents, VecDeinit, {
VecForeach(&dir_contents, dir_entry, {
// if it's a directory then store it for exploration later on
- In
MisraDoc.c:166
:
VecForeach(&file_paths, file_path, {
Str file_contents = StrInit();
Scope(&file_contents, StrDeinit, {
if (!ReadCompleteFile(
file_path.data,
- In
MisraDoc.c:178
:
Str output_path = StrInit();
Scope(&output_path, StrDeinit, {
StrMerge(&output_path, &file_path);
LOG_INFO("{}", output_path);
- In
MisraDoc.c:185
:
Str md_code = StrInit();
Scope(&md_code, StrDeinit, {
// Create template strings for StrWriteFmt with escaped braces
const char* mdHeader =
- In
MisraDoc.c:217
:
// dump code to output path
FILE* f = fopen(output_path.data, "w");
Scope(f, fclose, { fwrite(md_code.data, 1, md_code.length, f); });
});
});