Skip to content

Conditional Compilation

Andrew Lind edited this page Jun 23, 2026 · 3 revisions

Haxe #if FLAG / #elseif FLAG / #else / #end map to the C++ preprocessor (#ifdef / #elif defined(FLAG) / #else / #endif), and boolean conditions over flags map each flag through defined(…) (#if (DREAMCAST && !DEBUG)#if (defined(DREAMCAST) && !defined(DEBUG)); version comparisons like haxe_ver >= 4 have no defined(…) mapping and stay a hard error).

The escape hatches:

  • __cpp__("…", a, b) injects raw C++ verbatim (Haxe's cpp.Syntax.code). {0}, {1}, … placeholders are replaced by the transpiled arguments, so real Hatchet expressions can be spliced into hand-written C++ — e.g. __cpp__("::fmaxf({0}, {1})", v, lo)::fmaxf(v, lo). In Haxe this is normally written untyped __cpp__(…) to silence the unknown-identifier error on __cpp__; Hatchet only ever targets C++, so it recognises the call with or without the untyped wrapper.
  • untyped <expr> is Haxe's typer escape hatch: the operand is still parsed and transpiled like any other expression, but its static type is treated as opaque (Dynamic) so type-driven checks relax. It does not by itself pass anything through verbatim — raw injection is __cpp__'s job (the two are commonly paired).
  • A statement-level @:include("…") emits an #include at that point.
  • @:cppFileCode('…') injects verbatim C++ in a body.

See Metadata for the full @:include / @:cppFileCode semantics and the rest of the metadata Hatchet honours.

Clone this wiki locally