dummzeuch 1505 Posted February 25 23 minutes ago, emileverh said: I know it's a compiler problem, but why can they do it with classes and not with records.... Because a Class instance is a pointer. And before you ask: You can actually have forward declaration for pointers to records. 1 Share this post Link to post
Uwe Raabe 2057 Posted February 25 44 minutes ago, emileverh said: but why can they do it with classes and not with records.... You have already been told: 2 hours ago, Vandrovnik said: In forward declaration of a class, compiler immediatelly knows the size of that type. For records, their size would be unknown in forward declaration. 1 Share this post Link to post
JonRobertson 72 Posted February 25 8 hours ago, Uwe Raabe said: You have already been told: 10 hours ago, Vandrovnik said: In forward declaration of a class, compiler immediatelly knows the size of that type. For records, their size would be unknown in forward declaration. The Delphi compiler is also a single pass compiler, unlike C/C++. Being a single pass compiler is one of the reasons that Delphi builds projects much faster than a similar C++ project. I would expect changing Delphi to support multi-pass compiling would be a huge task with few benefits. But I don't know much about writing a compiler. 2 Share this post Link to post
Vincent Parrett 750 Posted February 25 (edited) 14 hours ago, emileverh said: forward declaration of records, just like a class Embarcadero would need to move to a multi pass compiler to achieve this - something they have always resisted. I can understand this 10-15 yrs ago, but on modern hardware the compiler performance loss from multiple passes would not be that noticable. Edit : FWIW - in a multipass compiler, forward declarations are not usually needed (Java, C# for example don't use forward declarations). Edited February 25 by Vincent Parrett addition 1 Share this post Link to post
Attila Kovacs 629 Posted February 25 (edited) 3 minutes ago, Vincent Parrett said: compiler performance loss from multiple passes would not be that noticable. I'd say they undo every change they did in the last 17 years and go back to the compiler speed of D2007. Edited February 25 by Attila Kovacs 1 Share this post Link to post
Cristian Peța 103 Posted February 26 17 hours ago, emileverh said: I know it's a compiler problem, but why can they do it with classes and not with records.... It's not a compiler problem, but record variables are not class variables and when you declare a record variable it is allocated automatically. You enter into a infinite loop of circular allocation. type TRecA = record; TRecB = record FieldA: TRecA; end; TRecA = record FieldB: TRecB; end; var a: TRecA; //infinite circular allocation of memory Share this post Link to post
Tommi Prami 130 Posted February 26 8 hours ago, Vincent Parrett said: Embarcadero would need to move to a multi pass compiler to achieve this - something they have always resisted. I can understand this 10-15 yrs ago, but on modern hardware the compiler performance loss from multiple passes would not be that noticeable. Even something like 1.5 pass compiler that would enable some functionality or extend existing would be cool to have... -Tee- Share this post Link to post
Uwe Raabe 2057 Posted February 26 23 hours ago, emileverh said: forward declaration of records, just like a class Actually there is a way to achieve that using generics: type TRecB<T> = record FieldA: T; FieldB: Integer; FieldC: string; end; type TRecA = record Secret: string; end; type TRecB = TRecB<TRecA>; 5 Share this post Link to post
David Heffernan 2345 Posted February 26 3 hours ago, Cristian Peța said: It's not a compiler problem, but record variables are not class variables and when you declare a record variable it is allocated automatically. You enter into a infinite loop of circular allocation. type TRecA = record; TRecB = record FieldA: TRecA; end; TRecA = record FieldB: TRecB; end; var a: TRecA; //infinite circular allocation of memory This isn't really a great example. The sort of thing that I want to do with records, but cannot, is this: type A = record; B = record; A = record function foo: B; end; B = record function bar: A; end; I can get round this using helpers right now, but I don't understand why I can't do this directly as above. 2 Share this post Link to post
PeterBelow 238 Posted February 27 On 2/25/2024 at 3:00 PM, emileverh said: I know it's a compiler problem, but why can they do it with classes and not with records.... Because classes are reference type and records are value types. A variable/field of a reference type will always have a a known size, sizeof(pointer). A value type does have the size defined by the type and that would be unknown at the point of the foreward declaration. A one-pass compiler cannot handle that. Share this post Link to post
Fritzew 51 Posted February 27 4 minutes ago, PeterBelow said: A one-pass compiler cannot handle that. And this is the problem. I think it is time for a two-pass compiler in Delphi. But the problem I see there is that Emabarcadero has not the power to switch. If I see what Remobjects can do with her compilers......... Share this post Link to post
David Heffernan 2345 Posted February 27 1 hour ago, PeterBelow said: Because classes are reference type and records are value types. A variable/field of a reference type will always have a a known size, sizeof(pointer). A value type does have the size defined by the type and that would be unknown at the point of the foreward declaration. A one-pass compiler cannot handle that. None of that applies to my example above. Share this post Link to post
Brandon Staggs 278 Posted February 27 1 hour ago, David Heffernan said: None of that applies to my example above. Beg to differ. At the point you declare an instance of TRecA inside of TRecB, the compiler does not yet know how much memory a TrecA instance takes. type TRecA = record; TRecB = record FieldA: TRecA; end; TRecA = record FieldB: TRecB; end; Share this post Link to post
David Heffernan 2345 Posted February 27 1 minute ago, Brandon Staggs said: Beg to differ. At the point you declare an instance of TRecA inside of TRecB, the compiler does not yet know how much memory a TrecA instance takes. type TRecA = record; TRecB = record FieldA: TRecA; end; TRecA = record FieldB: TRecB; end; That's not my example. Nobody wants to do this with a value type because it's a non terminating recursion. Have a look at my example code to see what I'm actually talking about. Share this post Link to post
Brandon Staggs 278 Posted February 27 1 minute ago, David Heffernan said: That's not my example. Nobody wants to do this with a value type because it's a non terminating recursion. Have a look at my example code to see what I'm actually talking about. Ah, got it. Still, you want to return an instance of a type that is not yet defined for the compiler. Maybe you should be able to, I suppose. Share this post Link to post
Ian Branch 127 Posted February 29 Case on Strings. i.e. case myStringVariable of 'A': do something; 'Test': do something; etc end; 3 Share this post Link to post
mitch.terpak 5 Posted February 29 (edited) For Linux64 to not compile to something 5-20x slower then Windows. Edited February 29 by mitch.terpak Share this post Link to post
Dalija Prasnikar 1396 Posted February 29 23 minutes ago, mitch.terpak said: For Linux64 to not compile to something 5-20x slower then Windows. Forget about that. While there is always a possibility that speed may be slightly improved, slowness is a feature of LLVM backend. 1 Share this post Link to post
Stefan Glienke 2002 Posted February 29 3 minutes ago, Dalija Prasnikar said: Forget about that. While there is always a possibility that speed may be slightly improved, slowness is a feature of LLVM backend. If it at least would produce binaries that are faster than what classic compiler for Windows produces ... But due to their currently super old LLVM version (hopefully they upgrade that once they are done on the C++ side which personally I could not care less about), they apparently had to turn off some important optimization steps which causes the binary produced by the Linux compiler to be approx as good as -O0 1 2 Share this post Link to post
David Heffernan 2345 Posted February 29 18 minutes ago, Stefan Glienke said: If it at least would produce binaries that are faster than what classic compiler for Windows produces ... Delphi produces native code, and therefore is fast 1 6 1 Share this post Link to post
Vandrovnik 214 Posted February 29 32 minutes ago, David Heffernan said: Delphi produces native code, and therefore is fast Even native code may run slow, when compiler does not use registers efficiently, uses superfluous jumps etc. Share this post Link to post
David Heffernan 2345 Posted February 29 12 minutes ago, Vandrovnik said: Even native code may run slow, when compiler does not use registers efficiently, uses superfluous jumps etc. Not according to Embarcadero. According to Embarcadero Delphi is blazing fast because it uses native code. We all know that to be absolute marketing BS and in fact Delphi compilers produce shitty code that often runs very slowly. Yes, my original post was sarcasm. 2 Share this post Link to post
Vandrovnik 214 Posted February 29 24 minutes ago, David Heffernan said: Not according to Embarcadero. According to Embarcadero Delphi is blazing fast because it uses native code. We all know that to be absolute marketing BS and in fact Delphi compilers produce shitty code that often runs very slowly. Yes, my original post was sarcasm. I was not sure about the sarcasm, but decided to reply, so that someone does not believe it blindly 🙂 Share this post Link to post
Dalija Prasnikar 1396 Posted February 29 2 hours ago, Stefan Glienke said: But due to their currently super old LLVM version (hopefully they upgrade that once they are done on the C++ side which personally I could not care less about), they apparently had to turn off some important optimization steps which causes the binary produced by the Linux compiler to be approx as good as -O0 Imagine how slow would compilation be with those optimizations turned on. I hope than newer LLVM could be faster, but I wouldn't keep my hopes up https://discourse.llvm.org/t/if-llvm-is-so-slow-is-anything-being-done-about-it/75389 Share this post Link to post
Stefan Glienke 2002 Posted February 29 (edited) 13 hours ago, Dalija Prasnikar said: Imagine how slow would compilation be with those optimizations turned on. I said this before and I say it again - nobody should care how long the compiler churns on producing a release config build. Also: the FE is still written by Embarcadero and I don't know how much time is spent there compared to the LLVM BE and how much of that could be improved by tweaking some settings. Given their usual attitude of "making it barely work" and leaving optimizing for later until everyone and their cat/dog complains and then waiting even a few years longer until tinkering around the edges I can only imagine how well done the FE is. Also, keep in mind that the Windows compilers regressed heavily with all the new language features introduced in the past 15 years and that it was mostly due to the efforts of Andreas Hausladen that we gained back some of that speed in the recent versions while still being way behind what it could be imo. Currently reading through the thread (not done yet but just leaving my thoughts as I go through) and this comment was interesting: Quote The way this breaks down varies from file to file, but the general rule of thumb is that clang frontend is the most time-consuming followed by IR optimizations, LLVM codegen, and clang codegen usually being tiny. I’d say the frontend taking 50-60% of the time is close to average, with IR optimizations usually 20-30% of time. Interestingly later someone comments that if you compile a different project it turns around into the opposite - and then there is this statement: Quote And I would tend to attribute much of the 9x compile time increase for the debug build to wrangling dwarf information, exacerbated by huge STL files. This is something I have actually seen with the non-Windows Delphi compilers: when I throw some generic-heavy code at them they take a ridiculous amount of time to compile - and some of the optimizations done by Andreas Hausladen actually resolved around generics. I would not be surprised if such an issue still exists either in the BE or in the LLVM code when generating debug symbols due to all the long full-qualified type names. Edited March 1 by Stefan Glienke 1 Share this post Link to post