# K07 — `TaskHandle_t`, explicit `start()` and static trampoline K07 isolates the exact C/C++ task-entry boundary. A local `CounterTask` object is constructed without touching the FreeRTOS heap. Only an explicit `start()` calls `xTaskCreate()` and passes the stable object address as `void*` context. The kernel later calls a static, non-virtual trampoline, which recovers the typed object and invokes its private `run()` member. ```text CounterTask object -> start() -> xTaskCreate(static trampoline, context=&object) -> kernel chooses task -> trampoline(void*) -> static_cast(context) -> object.run() -> state=completed, handle=nullptr, vTaskDelete(nullptr) ``` The wrapper is non-copyable and non-movable because a live kernel task retains its object address. The destructor does not attempt asynchronous task deletion. ## Three distinct address domains The checked Hazard3 run records: ```text C++ object = 0x800fffcc (local object on the retained main stack) TCB/handle = 0x800038b0 (dynamic kernel object in ucHeap) task stack = 0x800034a0..0x80003890 result = 500500 ``` The object address remains identical before start, in `xTaskCreate` context, inside the trampoline, inside `run()` and at completion. The numeric handle is the TCB address and is deliberately different from the C++ object. ## Lifecycle evidence | Point | Evidence | | --- | --- | | 1 | object constructed; heap unchanged; handle null | | 2 | state `starting` inside explicit start | | 3 | state `ready`; typed object passed as raw context | | 4 | `xTaskCreate` returned; handle now identifies the TCB | | 5 | scheduler not yet started; object still at same address | | 6 | static trampoline receives the original object address | | 7 | state `running` before member body | | 8 | body records current handle, stack bounds and result | | 10 | state `completed`, handle cleared, current task self-deletes | | 11–12 | raw verifier checks identity/lifecycle and emits PASS | ## Build ```sh make check ``` Expected summary: ```text PASS host: explicit start, stable context, duplicate/failure states PASS ABI: static trampoline; no vtable, RTTI or hosted runtime PASS task01: explicit start + stable context + trampoline ``` ## Debug ```gdb b explicit_task_debug_checkpoint p g_checkpoint_trace p/x g_object_before_start p/x g_trampoline_context p/x g_run_this p/x g_handle_after_start p/x g_tcb_address p/x g_stack_low p/x g_stack_high p/x g_stack_local p g_counter_result p g_task_wrapper_pass ``` ## Scope boundary K07 uses dynamic kernel storage only to study entry and identity. K08 compares dynamic and caller-supplied static TCB/stack policies and the timing of idle-task cleanup. A `Task` destructor still does not force-delete a running task.