Then is question separate: when record align set and make one field have other alignment then what is take precedence (e.g. is field align is all time must fit record align or can be more big for one field and ignore record align because this is small contradict with documentation that is exist)
All of this will end up in the docs. The Unleashed documentation acts as an "override" on top of the stock FPC documentation - by default you read the FPC docs, and where Unleashed adds or changes a feature, the Unleashed docs describe it in detail (including any place where the behaviour differs from stock).
So I propose adding a new type of loop, designed specifically for infinite loops:
loop
// iterating forever
end;
Going to pass on this one.
while true do ... already does the job with a couple of extra tokens, and a dedicated
loop ... end; construct earns its keep only if multiple users actually want it - right now it sounds like you'd be the main consumer. If others in the thread chime in saying they'd use it too, I'd reconsider.
Another suggestion taken from my game's source code is to change the calling convention from winapi to nativecall.
The winapi calling convention in the context of the current Free Pascal is misleading because it is not Windows-specific at all—it defines the native calling convention for the current platform. Therefore, changing it to nativecall would resolve the confusion caused by the unfortunate name.
For the purposes of my project, I changed the name of this convention using a macro, but macros cause incorrect syntax highlighting and break code editor features such as code folding.
A full rename would break a lot of existing code - every unit using
winapi (Windows.pas, ShellAPI, GDI, OpenGL bindings, third-party libs, etc.) would stop compiling. Not worth the breakage.
Adding
nativecall as an alias for
winapi would be doable in theory, but I'd rather not. Reasons:
- Two names for the same thing = style fragmentation. One file uses winapi, next file uses nativecall, same convention under the hood. Ends up in style debates and inconsistent codebases - exactly what Pascal's "one obvious way" philosophy tries to avoid.
- nativecall is itself misleading. On Win32, winapi resolves to stdcall, but FPC's actual "native" / default convention on i386 is register. So nativecall would mean "Windows-native", not "platform-native" - the new name trades one mild confusion for another.
- Stock FPC compatibility loss. Code using nativecall won't compile in stock FPC. Unleashed already adds plenty of one-way features (inline vars, union, embed, etc.) - I'd rather spend that "incompatibility budget" on actual new functionality, not on renaming an existing keyword.
- Naming churn is expensive. Every keyword in the language is something every reader has to learn. Adding a second name for the same concept doubles the surface area without adding capability.
So: passing on this one too. But appreciate the suggestion - it's the kind of friction-point that's worth flagging even if the answer ends up being "no".
One more suggestion. Since the Unleashed dialect is becoming a distinct dialect, I propose not calling it Free Pascal Unleashed, but rather Unleashed Pascal—short, concise, and clearly indicating its distinctiveness. It would also be a good idea to rename the compiler itself to UPC (Unleashed Pascal Compiler). But that can wait, since it's not essential right now.
Same answer as the others - passing on this. Reasons:
- It IS still 99% FPC. Unleashed is a fork that tracks upstream changes. The compiler core, RTL, code generation, target support - all FPC. Unleashed adds a language layer on top via {$mode unleashed}, plus a handful of compiler patches. Calling it a separate language overstates how separate it actually is.
- Renaming the binary breaks every existing tooling integration. fpcupdeluxe configs, IDE settings, build scripts, CI / CD pipelines, Makefiles - all hardcoded around fpc / ppcx64 / etc. Switching to upc / ppcupc would break every user's setup the day they update. Massive cost for cosmetic gain.
- Theoretical upstream-compat matters. As @creaothceann pointed out, the changes are theoretically upstream-compatible. Keeping the FPC name signals that intent - this is a fork that might one day merge features back, not a hostile breakup.
- Brand recognition. "Free Pascal" carries decades of recognition. "FPC Unleashed" leverages that. "Unleashed Pascal" / "UPC" starts from zero and asks every newcomer "what's this thing?" instead of "what's the difference?".
For informal references in conversation, "Unleashed Pascal" or just "Unleashed" is fine - I use it that way myself. But the project name stays "FPC Unleashed" and the compiler binary stays
fpc.
That said - I'm not rejecting the idea outright.
Unleashed Pascal Compiler sounds good, even kind of proud

Just too early for that.
The whole "bitpacked" "boolean" thing is for the birds. There should be a consistent, unique way of defining bit fields and, if the C way is going to be adopted then stick to bit counts, no "bitpacked", no boolean, just bit counts, clear simple, unambiguous and easy.
Fair point that
boolean bitsize 1 is verbose for what's conceptually just "one bit". But before going C-style, let me lay out what Pascal already offers - three types are natively 1-bit in a
bitpacked context, no modifier needed:
bitpacked record
a: boolean; { 1 bit - boolean }
b: 0..1; { 1 bit - subrange }
c: (k0, k1); { 1 bit - 2-variant enum }
end;
Wider sub-byte fields work the same way - the compiler picks the natural width:
- 0..3 or a 4-variant enum -> 2 bits
- 0..7 or a 5-to-8-variant enum -> 3 bits
- etc.
And
bitsize N is the explicit override for cases where the natural width doesn't match - e.g.
integer bitsize 3 or
bytebool bitsize 1 (take an 8-bit bytebool and force it to 1 bit while keeping the bytebool type identity).
Comparison - same 1-bit flag field, three styles:flag: boolean bitsize 1; { 24 chars - verbose, explicit }
flag: 0..1; { 11 chars - Pascal subrange }
flag: 1; { 8 chars - C-style proposal }
C-style saves 3 chars over subrange. The question is whether that's worth bringing in. My take: no, and here's why.
1. It breaks the "field : typename" idiom. After the colon Pascal expects a type.
flag: 1 is a literal where a type should be - the whole "field = name, colon, type" intuition goes out the window. Subrange
0..1 is still a type (range type), so it doesn't break this rule.
2. Ambiguity at N >= 8. What does
field: 8 mean? 8 bits unsigned (
0..255)? 8 bits signed (
-128..127)? In C this depends on the underlying
unsigned int vs
int declaration - Pascal has no ambient storage type to fall back on, so we'd have to pick one. If
field: 8 means
0..255, it overlaps with
field: byte - redundant. If signed, it surprises C porters.
3. Narrow useful range. For
N in {8, 16, 32, 64} you already have named types (
byte,
word,
longword,
int64). C-style is only useful for
N in {2..7} - a narrow band where
0..N-1 subrange is just as readable.
4. Composability problem with bitsize. What does
flag: 5 bitsize 1 mean? Contradiction -
: 5 says 5 bits,
bitsize 1 says 1. We'd have to ban the combination or pick a winner. More edge cases to document.
5. bitsize N has a different job. It's the explicit override for types whose natural width != the requested width.
bytebool bitsize 1 says "take this 8-bit boolean type and pack it to 1 bit anyway". C-style
: 1 can't express this - there's no type to apply an override to.
Where I think the actual fix is - leading with the cleaner pattern in docs.You're right that
boolean bitsize 1 is the worst example I could have led with - it makes the syntax look heavier than it needs to be. The cleaner form is just
bitpacked on the inner record:
union size 1
BitField: byte;
bitpacked record
ImageUsesLargePages, IsProtectedProcess,
IsImageDynamicallyRelocated, SkipPatchingUser32Forwarders,
IsPackagedProcess, IsAppContainer,
IsProtectedProcessLight, IsLongPathAwareProcess: boolean;
end;
end;
bitpacked forces each
boolean to 1 bit automatically - no per-field annotation. For non-boolean small fields, subrange:
bitpacked record
priority: 0..7; { 3 bits }
flags: 0..15; { 4 bits }
end;
And
bitsize N sits on top of all of this as the override when natural width doesn't match what you want. Most code won't need it.
Summary - three mechanisms cover the use cases:- boolean / subrange / enum inside a bitpacked record - natural bit width, no annotation
- bitsize N on any type - explicit width override
- union size N - container budget check
C-style
: N would be a fourth mechanism that mostly duplicates subrange with a 3-char savings, while adding ambiguity, idiom-break and composability headaches. Trade isn't worth it.
Pascal is supposed to read like a book.
flag: 0..1 reads as "flag, range 0 to 1" - any Pascal programmer understands it cold, no lookup required.
flag: 1 reads as... what? Either you already know C's bit-field syntax, or you have to consult the docs and memorise a new convention. That's a tax on every future reader of the code, paid so the writer can save three characters. Wrong trade for a language that values readability over compression.
EDIT:I think the second form isn't really needed, SizeOf can already do that. (Which would effectively reduce the necessary compiler change to the first form.)
You're right,
union type T goes out. Wasn't implemented yet anyway -
union size sizeof(T) covers the same case without a separate form.