Structures
Structures are value types in XXML that are allocated on the stack rather than the heap, providing efficient, lightweight data containers with automatic RAII cleanup.
Overview
Structures provide an alternative to classes when you need high-performance, stack-allocated data containers. They're ideal for small, short-lived data aggregates.
| Feature | Description |
|---|---|
| Stack Allocation | Memory allocated with alloca, not malloc |
| Value Semantics | Properties store values directly (not pointers) |
| RAII Cleanup | Automatic destructor call when leaving scope |
| No Inheritance | Structures cannot extend other types |
| Template Support | Full template parameter support |
Basic Syntax
xxml
[ Structure <StructureName>
[ Public <>
Property <field1> Types Integer^;
Property <field2> Types String^;
Constructor Parameters (Parameter <f1> Types Integer%, Parameter <f2> Types String%) -> {
Set field1 = f1;
Set field2 = f2;
}
Destructor Parameters () -> {
// Cleanup code (optional)
}
Method <someMethod> Returns Integer^ Parameters () -> {
Return field1;
}
]
]Structure vs Class
Understanding when to use structures versus classes is key to writing efficient XXML code.
| Feature | Class | Structure |
|---|---|---|
| Storage | Heap (malloc) | Stack (alloca) |
| Inheritance | Supported | Not supported |
| Properties | Store pointers | Store values directly |
| Default Passing | By reference | By value (copy) |
Memory Model Comparison
Class (Heap Allocation):
text
Variable: [ptr] ──────> Heap: [vtable_ptr][field1_ptr][field2_ptr]...
│ │
v v
[vtable] [field value]Structure (Stack Allocation):
text
Stack Frame: [field1_value][field2_value]...
└──── embedded directly ────┘Example: Vec2 Structure
vec2.xxml
[ Structure <Vec2>
[ Public <>
Property <x> Types Double^;
Property <y> Types Double^;
Constructor Parameters (
Parameter <px> Types Double%,
Parameter <py> Types Double%
) -> {
Set x = px;
Set y = py;
}
Method <length> Returns Double^ Parameters () -> {
Return x.multiply(x).add(y.multiply(y)).sqrt();
}
]
]
[ Entrypoint
{
// v is allocated on the stack, not the heap
Instantiate Vec2 As <v> = Vec2::Constructor(
Double::Constructor(3.0),
Double::Constructor(4.0)
);
// v.length() returns 5.0
Run Console::printLine(v.length().toString());
// v is automatically cleaned up when the entrypoint exits
Exit(0);
}
]Note
Structures are allocated on the stack using LLVM's
alloca instruction, providing no heap overhead, automatic cleanup when the function returns, and better cache locality.Template Structures
Structures support template parameters just like classes:
xxml
[ Structure <Pair> <T Constrains None, U Constrains None>
[ Public <>
Property <first> Types T^;
Property <second> Types U^;
Constructor Parameters (Parameter <f> Types T%, Parameter <s> Types U%) -> {
Set first = f;
Set second = s;
}
]
]
// Usage
Instantiate Pair<Integer, String> As <p> = Pair<Integer, String>::Constructor(
Integer::Constructor(42),
String::Constructor("hello")
);When to Use Structures
Good Use Cases
- Small, short-lived data aggregates
- Performance-critical code (avoid heap allocation overhead)
- Simple data containers without inheritance needs
- Interop with C/C++ value types
xxml
// Good: Small coordinate pair
[ Structure <Point>
[ Public <>
Property <x> Types Integer^;
Property <y> Types Integer^;
]
]
// Good: RGB color value
[ Structure <Color>
[ Public <>
Property <r> Types Integer^;
Property <g> Types Integer^;
Property <b> Types Integer^;
]
]When to Use Class Instead
- When inheritance is needed
- For large data structures
- When polymorphism or virtual methods are required
xxml
// Use Class: Needs inheritance
[ Class <Shape> Final Extends None
[ Public <>
Method <area> Returns Double^ Parameters () -> { ... }
]
]
// Use Class: Large data structure
[ Class <LargeBuffer> Final Extends None
[ Private <>
Property <data> Types Array<Integer>^; // Large array
]
]Warning
Keep structures small (under 64 bytes recommended). Large structures may cause stack overflow; use classes for large objects.
Limitations
- No Inheritance: Structures cannot use
Extends - No Polymorphism: No virtual methods or dynamic dispatch
- Stack Size: Large structures may cause stack overflow
- No Final Modifier: Structures are implicitly final
Next Steps
Learn about Classes for heap-allocated objects with inheritance, or explore Generics for template programming.