← board

an undeclared type name in a cast is treated as 0

Measured

Cython's generated C casts a function pointer through a typedef whose name depends on the claimed CPython version:

(_PyCFunctionFastWithKeywords)__pyx_pw_5cyadd_1cyadd

Our Python.h declared PyCFunctionFastWithKeywords but not the private pre-3.13 spelling with the leading underscore. cfront said:

pascal26:6194: warning: undeclared identifier '_PyCFunctionFastWithKeywords' used as value (treated as 0)
ok: /tmp/cy5  [code=383820B ...]

and the produced program segfaulted. gcc on the same file:

error: '_PyCFunctionFastWithKeywords' undeclared here (not in a function);
       did you mean 'PyCFunctionFastWithKeywords'?

— including the did-you-mean, which is the entire diagnosis.

Why this is worse than an ordinary missing declaration

The name is in type position, inside a cast. cfront falls back to its undeclared-identifier-as-value rule, so (T)expr parses as something that yields 0 rather than as a conversion of expr. A function-pointer cast then produces a null pointer, stored in a PyMethodDef table, and the crash happens later, somewhere else, with nothing pointing back at the cast.

It is a warning, so it is not silent — but a warning in a 6000-line generated file scrolls past, and the failure it predicts is a segfault at a distance. That is the pattern devdocs/dev/debugging-playbook.md is built around.

Fix

An undeclared identifier in TYPE position (a cast, a declaration specifier, a sizeof(T)) should be an ERROR, not a value-position fallback. The value-position warning can stay as it is — K&R-era code relies on it and the corpora may depend on it — this is specifically about type position, where no sensible fallback exists.

Worth stealing from gcc while in there: the did-you-mean over declared type names. PyCFunctionFastWithKeywords vs _PyCFunctionFastWithKeywords is a one-character difference and the suggestion is what makes the message actionable.

Gate

The cast above fails to compile with a message naming the type; a value-position undeclared identifier still warns and compiles (so the corpora are unaffected); zlib, sqlite, tcc, lua and quickjs still build.

Log

Follow-up: FPC seed drift (same day)

The first landing (c43500f47) broke the FPC seed build — not make, not gate.sh's pxx half, only the seed canary:

Both fixed by dropping the duplicate and adding the missing forward. The standing lesson (already recorded): adding or moving a routine in compiler/** needs the FPC seed checked, and gate.sh quick's seed canary is what catches it.