Appendix F — Unspecified and implementation-defined behavior
Tycho is designed so that this register is small: value semantics removes the aliasing undefined behavior of pointer languages, defined integer wrap removes overflow undefined behavior, and the fail-closed aborts of §30.2 convert the remaining partial operations into clean termination. What is left is collected here. A conforming program MUST NOT depend on anything in the "unspecified" list.
F.1 Unspecified behavior
| # | Behavior | Reference | Status |
|---|---|---|---|
| 1 | Argument / operand evaluation order within one expression (order of side effects among a call's arguments or a binary operator's operands). *Exceptions:* a side-effecting index in an assignment place (a[f()] = g()) and the holes of an f-string (f"{a()}{b()}") are sequenced left-to-right — specified, not in this list. | §13.4 | probed; arguments/operands inherited from the target, not sequenced by Tycho |
| 2 | Floating-point reduction reassociation in parallel for: the result MAY differ across thread counts. (Integer reductions are deterministic and are not in this list.) | §22 | defined boundary |
| 3 | Using a typed handle after a close(h) nested in a branch or loop — passes null to C; a logic bug, not memory corruption. A use after a close(h) statement in the same block is compile-rejected. | §25 | defined boundary |
| 4 | Behavior on the far side of the FFI boundary — C-side global/static races and misuse. | §26 | outside all guarantees |
An out-of-range shift count (count ≥ width yields 0, negative aborts — §13.2) and an out-of-range to_int(float) (NaN / out-of-range aborts — §8.5; the sized conversions are total) are defined, not unspecified.
F.2 Implementation-defined behavior
An implementation MUST document its choice for each of these; none but the last affects the value semantics of a program.
| Behavior | Reference |
|---|---|
Textual rendering of NaN/inf by str (e.g. -nan vs nan). The float *values* are IEEE-754 and fully defined; only their string form varies. | §30.5 |
| The concurrent-task ceiling (default 1024) and whether it is overridable at run time. | §21 |
The parallel for worker count (default: one per CPU), whether it is overridable, and any fixed upper bound on it (the reference caps the chunk count at 64, so ncpu() above 64 is not the width used). | §22 |
| Diagnostic message text for all errors and aborts (this specification constrains the *presence* of an error/abort, never its wording). | §1.1 |
An unpacked struct's layout, and so the value size_of$(T) yields for an align(N) struct. The one guarantee is that the value is a multiple of N. The reference lays the fields out in declaration order at the host C compiler's natural alignment, then rounds the size up to N; on every target it builds for, two u8 fields under align(8) are 8 bytes. This row is the one exception to the sentence above: size_of$ makes it a value. | §17.1a, §17.1b |
F.3 Explicitly *not* implementation-defined
For the avoidance of doubt, the following are fixed by this specification and an implementation MUST NOT vary them, even where its backend's native types differ:
The required 64-bit int width is normative for *every* conforming implementation; it is not implementation-defined. The reference compiler (tychoc) realizes int as a fixed-width 64-bit C type — typedef int64_t tycho_int; in the emitted prelude, which is the single width authority for int, the int-carried char representation, array/slice length headers, map keys and the FFI crossing signatures — and emits long long-suffixed integer literals so that constant arithmetic is evaluated at 64-bit rank. int64_t does not vary with the C data model, so the lowering is 64-bit on LP64, LLP64 and ILP32 alike, and a build in which it is not is rejected outright by the always-on _Static_assert(sizeof(tycho_int)==8, "tycho int must be 64 bits"); carried in the same prelude.