aboutsummaryrefslogtreecommitdiff
path: root/AGENTS/PITFALLS/exceptions-and-c-interop.md
blob: 0d0f89d03481d461d373f6ad88508899b4fc2d40 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50

# Exceptions, C types and EXTERN "C"

Part of the [pitfalls index](../PITFALLS.md).

## Exception extensions

- TRY requires exactly one parameterless CATCH and ENDTRY.
- Bare THROW raises a new anonymous exception even inside CATCH; there is no rethrow
  syntax, error object or what(). Bare THROW prints no diagnostic itself.
- Runtime checks are catchable; compiler errors are not. Runtime checks print the
  source line and error reason to stderr before throwing, even when caught.
- Uncaught exceptions also print the generic termination message and return 1.
- Native compilation links the C++ runtime automatically; manually linking emitted
  `.ll` files must use LLVM 23's `clang++` (`clang++-23` on Debian/Ubuntu).
- Owned STRING values follow class cleanup during unwinding; array buffers are freed
  and files are not automatically closed.
- Check the native nightly job results when changing platform-specific code
  (CI coverage: [ARCH/BUILD.md](../ARCH/BUILD.md)).

## C type extensions

- C_STRING is a raw char pointer. A visible IMPLICIT STRING.NEW(C_STRING)
  permits string-library calls, OUTPUT and file text; an explicit cast also works.
- C aliases share canonical CIdentity; do not use LLVM widths to recover signedness
  or nominal type identity. Plain char's signedness is native, unlike pseudocode CHAR.
- Other C/pseudocode conversions require casts, including numeric literals. C scalar arithmetic uses
  native promotions, but / always returns REAL.
- Cast aliases must precede their use.
- long double may have padding; sizeof does not identify its floating-point format.
- Native C support is tested by nightly CI on Linux, Windows and macOS with LLVM 23; cross-target is unsupported.

## EXTERN "C" extension

- Top-level, body-less; parameters/results are C types, C-struct records or pointer
  types finally pointing to either (not `^INTEGER`, not `TYPE P = ^P`); no
  BYREF/OVERLOAD. Variadic arguments must be C values (default promotions), C-struct
  records or pointers (never promoted); `^x` of a C value passes as `void*`.
- A C-struct record's fields must have those types too: one INTEGER, REAL, CHAR,
  BOOLEAN, STRING, enum or CLASS field rejects the whole record (`... uses record R,
  which is not a C struct: field F of R has type T`). cpsc never sees the C
  declaration: field order and types must match it by hand.
- The driver checks every EXTERN symbol against INCLUDE_OBJ inputs before CodeGen;
  `"__libc"` must be included explicitly even though the runtime always links libc.
- Only `.o` user objects; INCLUDE_OBJ is global across inputs. `-S` does not link them.
- Identical EXTERN redeclarations (same or other files, CIdentity-equal types) are
  allowed; differing ones fail. Two EXTERNs differing only in case conflict
  (pseudocode names are case insensitive).
- Windows `-r` resolves C symbols from msvcrt.dll before the process-wide search:
  ucrtbase.dll may also be loaded, and its separate stdout buffer reorders EXTERN
  output against OUTPUT.