FPC and Lazarus coding style lazarus / 64-FPC development ---------------------------------------------------------------------- Okoba · 2026-02-02 20:48 Hello, Normally I do not look at the code of FPC or Lazarus, but today I was looking at some of the units, and it was hard for me to read the codes, especially the FPC. The code seems disturbing. It seems no spacing, format, or even case of keywords is written with a rule. I wanted to ask how this is managed at the level of such big projects. Do professional developers not care about this stuff, or are these codes old and people have no time to clean them up or something I, as a normal developer, cannot understand? Please note that I do not want to begin a discussion to say bad stuff about people who created such great projects that I use daily. I am just curious about the development style and needs of such projects that lead to this type of code. Here is a sample form typinfo unit, you can see even a simple "if" is written as "if" or "If" or spacing looks wrong. And this is not part of the compiler; the compiler codes look much scarier to me with so much web of ifs. Code: Pascal  [Select][+][-]window.onload = function(){var x1 = document.getElementById("main_content_section"); if (x1) { var x = document.getElementsByClassName("geshi");for (var i = 0; i Function GetEnumValue(TypeInfo : PTypeInfo;const Name : string) : Integer;   Var PS : PShortString;      PT : PTypeData;      Count : longint;    sName: shortstring; begin  If Length(Name)=0 then    exit(-1);  sName := Name;  PT:=GetTypeData(TypeInfo);  Count:=0;  Result:=-1;   if TypeInfo^.Kind=tkBool then    begin    If CompareText(BooleanIdents[false],Name)=0 then      result:=0    else if CompareText(BooleanIdents[true],Name)=0 then      result:=1;    end else   begin     PS:=@PT^.NameList;     While (Result=-1) and (PByte(PS)^<>0) do       begin         If ShortCompareText(PS^, sName) = 0 then           Result:=Count+PT^.MinValue;         PS:=PShortString(pointer(PS)+PByte(PS)^+1);         Inc(Count);       end;     if Result=-1 then       Result:=GetEnumeratedAliasValue(TypeInfo,Name);   end;end;  Sample from compiler. I can not even follow the parenthesis. Code: Pascal  [Select][+][-]window.onload = function(){var x1 = document.getElementById("main_content_section"); if (x1) { var x = document.getElementsByClassName("geshi");for (var i = 0; i  if (taicpu(p).condition <> C_None) and        (taicpu(p).oper[0]^.typ = top_ref) and        GetNextInstruction(p, hp1) and        { Check individually instead of using MatchInstruction in order to save time }        (hp1.typ = ait_instruction) and        (taicpu(hp1).condition = C_None) and        (taicpu(hp1).oppostfix = PF_None) and        (taicpu(hp1).ops = 2) and        (          (            (taicpu(hp1).opcode = A_MOVZ) and            (taicpu(hp1).oper[1]^.val in [0, 1])          ) or          (            (taicpu(hp1).opcode = A_MOV) and            (getsupreg(taicpu(hp1).oper[1]^.reg) = RS_XZR)        )        ) and        GetNextInstruction(hp1, hp2) and        MatchInstruction(hp2, A_B, [PF_None]) and        (taicpu(hp2).condition = C_None) and        (taicpu(hp2).oper[0]^.typ = top_ref) and        GetNextInstruction(hp2, hp3) and        (hp3.typ = ait_label) and        (tasmlabel(taicpu(p).oper[0]^.ref^.symbol) = tai_label(hp3).labsym) and        GetNextInstruction(hp3, hp4) and      { As before, check individually instead of using MatchInstruction in order to save time }        (hp4.typ = ait_instruction) and        (taicpu(hp4).condition = C_None) and        (taicpu(hp4).oppostfix = PF_None) and        (taicpu(hp4).ops = 2) and        (taicpu(hp4).oper[0]^.reg = taicpu(hp1).oper[0]^.reg) and        (        (            (taicpu(hp4).opcode = A_MOVZ) and            (            (                { Check to confirm the following:                - First mov is either "movz reg,#0" or "mov reg,xzr"                - Second mov is "movz reg,#1"                }                (                (taicpu(hp1).oper[1]^.typ = top_reg) { Will be the zero register } or                  (taicpu(hp1).oper[1]^.val = 0)              ) and                (taicpu(hp4).oper[1]^.val = 1)            ) or              (                { Check to confirm the following:                - First mov is "movz reg,#1"                  - Second mov is "movz reg,#0"                }                MatchOperand(taicpu(hp1).oper[1]^, 1) and                (taicpu(hp4).oper[1]^.val = 0)              )            )          ) or          (            { Check to confirm the following:            - First mov is "movz reg,#1"              - Second mov is "mov reg,xzr"            }            (taicpu(hp4).opcode = A_MOV) and          (getsupreg(taicpu(hp4).oper[1]^.reg) = RS_XZR) and            MatchOperand(taicpu(hp1).oper[1]^, 1)          )        ) and        GetNextInstruction(hp4, hp5) and        (hp5.typ = ait_label) and      (tasmlabel(taicpu(hp2).oper[0]^.ref^.symbol) = tai_label(hp5).labsym) then        begin          Invert := MatchOperand(taicpu(hp1).oper[1]^, 1); { if true, hp4 will be mov reg,0 in some form }          if Invert then            taicpu(p).condition := inverse_cond(taicpu(p).condition);           tai_label(hp3).labsym.DecRefs; ---------------------------------------------------------------------- Martin_fr · 2026-02-02 21:04 Well, I am not part of FPC, and hence can't give many details on those code samples. I am part of the Lazarus team though. One generic remark I can provide: In some part code formatting, will always be something that happened over time. Well, unless you had strict automatic linters checking every commit from day one before it even gets committed. Anyway, once you have it in, the cost of changing it (to match other code) is most often higher than the cost of having to read code that isn't exactly formatted as one expects. The reason for this is, that old commits are part of the development. Things like  "git blame" or simple diffs between commits, are helpful tools in understanding why code exists, and what it does. A pure formatting commit, could hit lots of lines, and git blame would require extra steps to find any commit that actually functionally changed a given bit of code. In the Lazarus section we have different bits of code maintained by different people. And that leads to different styles, in each those section. ---------------------------------------------------------------------- Martin_fr · 2026-02-02 21:08 Quote from: Okoba on February 02, 2026, 09:48:04 pmI can not even follow the parenthesis.Off topic, but the Lazarus 5.0 will have rainbow brackets. ---------------------------------------------------------------------- 440bx · 2026-02-02 23:02 Quote from: Okoba on February 02, 2026, 09:48:04 pmSample from compiler. I can not even follow the parenthesis.  < code snippet > Actually, as far as matching parentheses, that code is unusually good.  I've seen a lot worse than that.  At least in that snippet the opening and closing parentheses are easy to visually match (it also helps that both, Lazarus and the editor I use, match parentheses anyway.) You're right that there doesn't seem to be a set of formatting rules that is strictly followed but, overall, while I wouldn't say it's great, it isn't that bad. Quote from: Martin_fr on February 02, 2026, 10:08:34 pmOff topic, but the Lazarus 5.0 will have rainbow brackets. in that case, the absence of a pot of gold at the end of the bracket should be considered a bug.  Maybe that bug should be preemptively reported to ensure this new feature is implemented correctly. ---------------------------------------------------------------------- LeP · 2026-02-02 23:07 In Delphi there is this kind of help (see image attached), and for parenthesis you can select one and the corresponding will be highlighted (in blue, see second images). If one code correctly, this kind of graphical help will not be necessary. I see many developers that use notepad, word, edlin and countless other tools for writing code... then when you edit these sources in the Lazarus IDE, the formats don't work (for example, TABS or LF), and the code appears haphazard and unreadable (in Delphi is worse, really worse). There have been other threads in this forum on these topics, and apparently it seems like a fairly common practice to skip the IDE and use third-party editing applications. If this is the case, I don't think the code visibility problem will ever be solved. ---------------------------------------------------------------------- Martin_fr · 2026-02-02 23:15 Off topic: Quote from: LeP on February 03, 2026, 12:07:14 amIn Delphi there is this kind of help (see image attached), and for parenthesis you can select one and the corresponding will be highlighted https://wiki.lazarus.freepascal.org/New_IDE_features_since#Outline_for _Pascal_Sources And matching bracket at caret highlight we also have (just set a color in the settings) And we also have highlight of begin/end pairs at caret, and a ton of other.... Quote the formats don't work (for example, TABS or LF)Don't know what the LF issues are. But tabs can be set any way you want. Including elastic. ---------------------------------------------------------------------- LeP · 2026-02-02 23:27 Quote from: Martin_fr on February 03, 2026, 12:15:29 amOff topic: https://wiki.lazarus.freepascal.org/New_IDE_features_since#Outline_for _Pascal_Sources And matching bracket at caret highlight we also have (just set a color in the settings) Thanks, I didn't know about those. ---------------------------------------------------------------------- Martin_fr · 2026-02-02 23:31 Back on the original question Quotea simple "if" is written as "if" or "If" or spacing looks wrong The upper/lower wouldn't bother me. Not for keywords anyway, minimal for vars/idents if/when inconsistent. The indent (e.g. the one "else") is indeed unfortunate. If that was code I would work on (which it isn't) then I would consider fixing it, if and likely only if, I had other functional changes in the same code block to make. The compiler code with the brackets... Despite the many all lowercase names, it is actually very readable, and the format/layout is helpful, even if I would come from a different style (I don't, but if). The issues here is not so much the code, but the enormous underlying data structures, that aren't just self explaining. Without knowing how this (my guess) node-tree of instructions is build, the code cannot be understood.... And some of the abbreviations aren't self explaining either. So to understand this code, there is some initial read up needed, to get all that context. But that is not "code formatting" related. You could argue (but even that isn't formatting, despite affecting it), that the long if conditions could be moved into groups in a serious of methods on the target object. Code: Pascal  [Select][+][-]window.onload = function(){var x1 = document.getElementById("main_content_section"); if (x1) { var x = document.getElementsByClassName("geshi");for (var i = 0; i ortaicpu.is_operater_foobaror... It affects formatting by reducing long statements. But it primarily is code-design. By moving functionality into classes or functions.... And, as I don't really have done my due diligence in reading up and understanding the code => this may even be a proposal to make it worse. I have in some of my code similar issues. And in some of it, I will probably keep it. ---------------------------------------------------------------------- Curt Carpenter · 2026-02-03 00:14 For what it's worth, I've found that reformatting a program to fit my own personal style quirks is one of the best ways to study it, at least initially.  It forces me to go over the code line by line and helps me be patient with the learning process.   Note too that where "style" is concerned, case sensitive languages and  programs drive me nuts -- a hangover from ancient habits that began with punched cards and teletype I suppose. ---------------------------------------------------------------------- H₂SO₄ · 2026-02-03 06:01 Quote from: Curt Carpenter on February 03, 2026, 01:14:39 amI've found that reformatting a program to fit my own personal style quirks is one of the best ways to study it, at least initially. I've had the same experience; I think that manually reformatting forces you to mentally parse at least the control flow structure, which is already better than just skimming the code. Quote from: Curt Carpenter on February 03, 2026, 01:14:39 amNote too that where "style" is concerned, case sensitive languages and  programs drive me nuts I'm the complete opposite - case insensitive languages drive me nuts because of how inconsistent (actually, I'd rather call it sloppy) your colleagues are allowed to be ---------------------------------------------------------------------- Joanna · 2026-02-03 12:41 I agree with curt. If you don’t like the style change it for yourself. ---------------------------------------------------------------------- Thaddy · 2026-02-03 12:56 The compiler code itself uses indeed a different, to many unfamiliar way, of naming and formatting rules but it is standardized dating from tp days or earlier. Most- but - not all code elsewhere uses basically the same convention as Delphi does. ---------------------------------------------------------------------- Zvoni · 2026-02-03 13:42 Quote from: Martin_fr on February 03, 2026, 12:31:26 amThe indent (e.g. the one "else") is indeed unfortunate. If that was code I would work on (which it isn't) then I would consider fixing it, if and likely only if, I had other functional changes in the same code block to make. Which "else" would that be? the only "fishy" formatting i see is Line 18 to Line 21, which indents to the same level of the "Begin" in Line 17 resp. the "end" in Line 22 ---------------------------------------------------------------------- Martin_fr · 2026-02-03 14:19 Quote from: Zvoni on February 03, 2026, 02:42:03 pmQuote from: Martin_fr on February 03, 2026, 12:31:26 amThe indent (e.g. the one "else") is indeed unfortunate. If that was code I would work on (which it isn't) then I would consider fixing it, if and likely only if, I had other functional changes in the same code block to make. Which "else" would that be? the only "fishy" formatting i see is Line 18 to Line 21, which indents to the same level of the "Begin" in Line 17 resp. the "end" in Line 22 Line 23. The else has no indent at all. But all other code in the procedure's begin/end is indented. About line 18 to 21: That is a common style. The "begin (and it's end) are themself indented. The code they enclose is not further indented, as the begin/end already is. I.e., the begin/end is part of the indented code. This is logical if you have "if then" followed by an indented statement on the next line(s). The begin/end is one compound statement. It gets indented for the "if". ---------------------------------------------------------------------- Okoba · 2026-02-03 14:48 @Martin_fr thank you for the input. The link to the wiki was new to me, I enabled the rainbow colors. Btw do you know how to enable the spell checker? I can not find the SynEditSpellCheckerDsgn package. I am using the Trunk. ---------------------------------------------------------------------- Martin_fr · 2026-02-03 14:56 Should have posted the link here: https://forum.lazarus.freepascal.org/index.php/topic,73393.0.html ---------------------------------------------------------------------- Zvoni · 2026-02-03 15:29 Quote from: Martin_fr on February 03, 2026, 03:19:44 pmQuote from: Zvoni on February 03, 2026, 02:42:03 pmQuote from: Martin_fr on February 03, 2026, 12:31:26 amThe indent (e.g. the one "else") is indeed unfortunate. If that was code I would work on (which it isn't) then I would consider fixing it, if and likely only if, I had other functional changes in the same code block to make. Which "else" would that be? the only "fishy" formatting i see is Line 18 to Line 21, which indents to the same level of the "Begin" in Line 17 resp. the "end" in Line 22 Line 23. The else has no indent at all. But all other code in the procedure's begin/end is indented. About line 18 to 21: That is a common style. The "begin (and it's end) are themself indented. The code they enclose is not further indented, as the begin/end already is. I.e., the begin/end is part of the indented code. This is logical if you have "if then" followed by an indented statement on the next line(s). The begin/end is one compound statement. It gets indented for the "if". Would have to disagree. The „else“ in line 23 is indented to the „if“ in line 16, which is correct, considering the begin/end in line 17/22 is, strictly speaking, not necessary ---------------------------------------------------------------------- dsiders · 2026-02-03 16:24 Quote from: Martin_fr on February 02, 2026, 10:08:34 pmQuote from: Okoba on February 02, 2026, 09:48:04 pmI can not even follow the parenthesis.Off topic, but the Lazarus 5.0 will have rainbow brackets. Which I hope will not be enabled by default. ---------------------------------------------------------------------- Okoba · 2026-02-03 16:26 Quote from: Martin_fr on February 03, 2026, 03:56:19 pmShould have posted the link here: https://forum.lazarus.freepascal.org/index.php/topic,73393.0.html Oh I was sure I asked the question already! I thought maybe I was sleep or loosing my mind ---------------------------------------------------------------------- PascalDragon · 2026-02-03 21:57 Quote from: Okoba on February 02, 2026, 09:48:04 pmNormally I do not look at the code of FPC or Lazarus, but today I was looking at some of the units, and it was hard for me to read the codes, especially the FPC. The code seems disturbing. It seems no spacing, format, or even case of keywords is written with a rule. I wanted to ask how this is managed at the level of such big projects. Do professional developers not care about this stuff, or are these codes old and people have no time to clean them up or something I, as a normal developer, cannot understand? The compiler itself does have a more or less fixed coding style (if unorthodox) that is tried to be adhered to. Especially with newly added code. The RTL is much less strict not to mention the packages. They usually depend on whoever adds the code though the general idea is to at least adhere to the style of the surrounding code. And there is indeed no intentation to fix this cause as Martin_fr mentioned this adds unnecessary noise to the commit log and that is more imporant than consistent style. ---------------------------------------------------------------------- Warfley · 2026-02-06 18:47 Quote from: Okoba on February 02, 2026, 09:48:04 pmNormally I do not look at the code of FPC or Lazarus, but today I was looking at some of the units, and it was hard for me to read the codes, especially the FPC. The code seems disturbing. It seems no spacing, format, or even case of keywords is written with a rule. I wanted to ask how this is managed at the level of such big projects. Do professional developers not care about this stuff, or are these codes old and people have no time to clean them up or something I, as a normal developer, cannot understand? I've worked with multiple big projects and there is only one unbreakable rule about formatting: You never change a line just for formatting. If you look at a merge request you want to see what they did, so you look at what they changed. If they formatted 1000 lines and added 2, good luck finding that in the diff. Additionally if two people work on the same file and format it, they will get merge conflicts for the 1000 lines. Or most importantly, if you want to see why something was changed, you look into the history, if it is full of re-formats it's difficult to find the change that actually caused the behavior It will happen over time that different code styles get into the code base. FPC is a 30 year old code base that went through many different developers. You have snake casing vs camel casing vs no casing in there. You have descriptive variable names, abbreviations and single char names, you have german and english identifiers. All mixed. Yeah it's a mess, but you cannot clean it up. Also, readability does not really depend on such superficial metrics. When I first looked into the FPC code base I thought the same thing as you, but once you get used to it, which takes around 30 minutes, it's not an issue anymore. FPC is very well structured semantically and once you get over the superficial inconsistencies it is really easy to read, understand and modify the code. Something I cannot say about most (enterprise) Java or C++ code bases I have worked in ---------------------------------------------------------------------- Martin_fr · 2026-02-06 19:07 Semi off topic: As in not about the specific coding style, but how to deal with style one isn't used to. The IDE has an IMHO excellent feature to help reading unfamiliar code, especially if style means that you find it hard to track identifiers, groups of them, .... => https://wiki.lazarus.freepascal.org/New_IDE_fe atures_since#Multiple_user_defined_word_highlight/markup => Just (with the press of one key) color any identifier of interest. You can use as many colors as you need. ---------------------------------------------------------------------- Wallaby · 2026-02-06 22:10 Quote from: Martin_fr on February 06, 2026, 08:07:08 pmThe IDE has an IMHO excellent feature to help reading unfamiliar code... You can use as many colors as you need. On a related note, there is a great feature called Outline that connects block boundaries with a line and more importantly - colour. Makes it super easy to see where each block begins and ends. Wondering why it's not enabled by default...? ---------------------------------------------------------------------- Martin_fr · 2026-02-07 01:08 Quote from: Wallaby on February 06, 2026, 11:10:19 pmSee reply @ https://forum.lazarus.freepascal.org/index.php?topic=73413 ---------------------------------------------------------------------- Curt Carpenter · 2026-02-07 02:01 Quote from: Wallaby on February 06, 2026, 11:10:19 pmQuote from: Martin_fr on February 06, 2026, 08:07:08 pmThe IDE has an IMHO excellent feature to help reading unfamiliar code... You can use as many colors as you need. On a related note, there is a great feature called Outline that connects block boundaries with a line and more importantly - colour. Makes it super easy to see where each block begins and ends. Wondering why it's not enabled by default...? Would like to try it.  How do you turn it on? ---------------------------------------------------------------------- Curt Carpenter · 2026-02-07 02:08 Quote from: Warfley on February 06, 2026, 07:47:29 pmI've worked with multiple big projects and there is only one unbreakable rule about formatting: You never change a line just for formatting. I can see that for team projects.   But even in that context, reformatting of a copy of a source can be a big aid to understanding.  Having a style standard is important in that context too (although, full disclosure, it's been decades since I work on a team project). ---------------------------------------------------------------------- Wallaby · 2026-02-07 03:39 Quote from: Curt Carpenter on February 07, 2026, 03:01:47 amWould like to try it.  How do you turn it on? Here ---------------------------------------------------------------------- Martin_fr · 2026-02-07 08:21 Quote from: Wallaby on February 07, 2026, 04:39:45 amQuote from: Curt Carpenter on February 07, 2026, 03:01:47 amWould like to try it.  How do you turn it on? Here And look at the list, and decide which ones you want on. E.g. if you have "if" then every "if" even with just one single line after the "then", and no "begin" will have an outline. ---------------------------------------------------------------------- Curt Carpenter · 2026-02-08 15:10 Thank you.  Looks very helpful.