New "features" in Delphi XE8 lazarus / 64-FPC development ---------------------------------------------------------------------- Thaddy · 2015-06-19 09:45 The most breaking one being: "LongInt and LongWord are now platform-dependent integer types." See: http://docwiki.embarcadero.com/RADStudio/XE8/en/What%27s_New_in_D elphi_and_C%2B%2BBuilder_XE8 ---------------------------------------------------------------------- marcov · 2015-06-19 09:59 I think that means they started giving meaning to longint and longword (e.g. size_t) or something and the ABI of aarch64 made that 64-bit. Still it is a bit silly, they'd better define a new type that more clearly reflected the meaning (like native* in the past). I read through the docs you reference, and couldn't really find any meaning there, so maybe the reasons are FM related, rather than compiler+rtl. ---------------------------------------------------------------------- Thaddy · 2015-06-19 10:45 Two new platform independent 32-bit integer types are introduced in XE8: FixedInt: 32-bit signed integer type. FixedUInt: 32-bit unsigned integer type. FixedInt and FixedUInt ensure portability, better integration and interoperability with 32-bit and 64-bit platforms. These two new types ensure cross-language support between Delphi and C++ for your applications. Frankly, I've lost the plot a bit with native, fixed, longint etc. At least this one will break code. In that case, why not fix Native, integer and uint? ---------------------------------------------------------------------- serbod · 2015-06-19 11:27 Very bizzare decision to name ordinal integer as FixedInt. Why not Int32/UInt32 (same, as Int64/UInt64)? ---------------------------------------------------------------------- Leledumbo · 2015-06-19 13:07 It's embarcadero. If anders is still there, he won't do such a stupid backward compatibility breaking changes. ---------------------------------------------------------------------- BeniBela · 2015-06-19 16:57 FixedInt? Omg, I hope you are not going to add this crap to FPC ---------------------------------------------------------------------- rtusrghsdfhsfdhsdfhsfdhs · 2015-06-28 07:35 How about GetTypeKind for generics? So i can actually know the type at compile time? ---------------------------------------------------------------------- Thaddy · 2015-06-28 09:01 For that to work you need RTTI and ultimately a Tpersistent descendant I guess. ---------------------------------------------------------------------- rtusrghsdfhsfdhsdfhsfdhs · 2015-06-28 09:27 That's resolved at compile time not runtime no need for RTTI... ---------------------------------------------------------------------- Thaddy · 2015-06-28 09:42 In that case your suggestion doesn't add much  value. is, as, cast, assignments will do the job. Why would you want that? You KNOW the type because YOU compiled the code. ---------------------------------------------------------------------- rtusrghsdfhsfdhsdfhsfdhs · 2015-06-28 09:52 Heh why? Because if the compiler knows the type at compile time it can inline better? An example is quicksort algorithm and other algorithms. THATS WHY! ---------------------------------------------------------------------- marcov · 2015-06-28 11:55 Quote from: Thaddy on June 19, 2015, 12:45:26 pmTwo new platform independent 32-bit integer types are introduced in XE8: FixedInt: 32-bit signed integer type. FixedUInt: 32-bit unsigned integer type. FixedInt and FixedUInt ensure portability, better integration and interoperability with 32-bit and 64-bit platforms. These two new types ensure cross-language support between Delphi and C++ for your applications. Hmm, reading the C++ reference, then maybe they are comparable to our ctypes.cint and cuint then.  Maybe they are working on some arch where "C" int=8bytes or so. ---------------------------------------------------------------------- jc99 · 2015-06-28 16:41 My I remind you of the history of integer: integer was supposed to hold that amount of bits the the processor could handle with one register. e.G: on 16-bit machine it was 16-bit on 32-bit big endian it was 32-bit big endian and 32-bit little endian it was 32-bit little endian. exception were the 64-bitter where integer stayed 32-bit. So ... Maybe they introduced FixedInt to ensure not only the bit-ness but also the endian-ness of a stored variable. But since most modern prozessors can switch their endian-ness I personally see no need for this. it's just another def in my jedi.inc: Code: [Select]{$ifdef fpc} type FixedInt=longint; //[EDIT] {$endif} To me there are much more compelling things in Delphi which I still miss/haven't found in Lazarus. e.G: Having a really good Project-Group-Management, to handle HUGE amount of Source-files, their test- and production-files (.lpi). ---------------------------------------------------------------------- marcov · 2015-06-28 17:33 Quote from: jc99 on June 28, 2015, 06:41:45 pmMy I remind you of the history of integer: integer was supposed to hold that amount of bits the the processor could handle with one register. e.G: on 16-bit machine it was 16-bit on 32-bit big endian it was 32-bit big endian and 32-bit little endian it was 32-bit little endian. exception were the 64-bitter where integer stayed 32-bit. Integer is the base integer type of Pascal. The connection to register is implied, but only because the calculations of the base type must be fast. And a x86_64 has 32-bit (sub-)registers too, so that is not the problem. Those processors can't switch endianess, but some are agnostic to it, iow the wiring to the chipset/memory determines endianess.  Those processors can't switch endianess runtime. If the types had an associated endianess, there would be directives {$endianess} or so to signal  and define such types. ---------------------------------------------------------------------- jc99 · 2015-06-28 19:17 Quote from: marcov on June 28, 2015, 07:33:45 pmInteger is the base integer type of Pascal. The connection to register is implied, but only because the calculations of the base type must be fast. And a x86_64 has 32-bit (sub-)registers too, so that is not the problem. Those processors can't switch endianess, but some are agnostic to it, iow the wiring to the chipset/memory determines endianess.  Those processors can't switch endianess runtime. If the types had an associated endianess, there would be directives {$endianess} or so to signal  and define such types. So we agree in the fact that integer, despite of it being a base-type of Pascal, changed it's representation over the years. (I personally know, with BP7 and the ability/need  to write 32-bit- code I had to change a HUGE amount of code to be compatible to old data-files.) With modern processors, I don't mean new representation of old architectures. I am talking of ARM (e.G), Arcon did a good job designing this Beast. And ARM-processors are aware of endianess, and can act accordingly. Emdarcadero just felt the need to introduce this new type. About the x64 - I think you also got me wrong. I am REALLY glad that integer stayed 32-bit for more than 20 years. And I am also glad about that binary-datafiles are less important nowadays, thanks to CSV, XML and JSON (and lots of cheap storage-space ). ---------------------------------------------------------------------- marcov · 2015-06-28 19:53 Quote from: jc99 on June 28, 2015, 09:17:18 pmSo we agree in the fact that integer, despite of it being a base-type of Pascal, changed it's representation over the years. Yes, and no, it was always architecture dependent, just not automatically register size. That's also why Pascal, like most C compilers didn't go to 64-bit integers on 64-bit systems. Basically you are lugging around a lot of useless zeroes in most calculations. Quote(I personally know, with BP7 and the ability/need  to write 32-bit-code I had to change a HUGE amount of code to be compatible to old data-files.) QuoteWith modern processors, I don't mean new representation of old architectures. I am talking of ARM (e.G), Arcon did a good job designing this Beast. And ARM-processors are aware of endianess, and can act accordingly. PowerPC and MIPS too, but only on the chip or chipset design table. Not at runtime to my best knowledge. (and even if it were, then only as startup state, and after the startup it basically would be a different architecture as far as applications were concerned). QuoteEmdarcadero just felt the need to introduce this new type. Yes, but it might not be machine related, just something they need in e.g. FM in combination with some limitation of e.g. the new ARM64 iOS ABI. Anyway, at this point it is all speculation. ---------------------------------------------------------------------- jc99 · 2015-06-28 23:09 Quote from: marcov on June 28, 2015, 09:53:03 pmYes, and no, it was always architecture dependent, just not automatically register size. "Architecture dependent", is the right word, I think there was never a 8-bit integer even on 6510-8-bit-machines. Quote from: marcov on June 28, 2015, 09:53:03 pmThat's also why Pascal, like most C compilers didn't go to 64-bit integers on 64-bit systems. Basically you are lugging around a lot of useless zeroes in most calculations. I know there was a big debate about that in the delphi/pascal-scene. The other "new features" are about a community-bar where you could buy more stuff, did I get that right ? Please don't adopt these ... ---------------------------------------------------------------------- Basile B. · 2015-06-29 02:44 Quote from: Fiji on June 28, 2015, 09:35:53 amHow about GetTypeKind for generics? So i can actually know the type at compile time? This is a good feature they've added (since XE7 actually) however i don't like the syntax because you don't know that the branch is a compile time one. In D for example you clearly know you're in a compile time branch because instead of Code: [Select]if GetTypeKind(T) = tkInteger then begin end; you have Code: [Select]static if (is(T == int)) {} the static keyword changes everything while in Delphi you have no particular clue that indicates you're in a compile-time or a run-time statement. ---------------------------------------------------------------------- skalogryz · 2015-06-29 03:11 Quote from: Fiji on June 28, 2015, 09:35:53 amHow about GetTypeKind for generics? So i can actually know the type at compile time? Wait wait. GetTypeKind to write a type specific code? It kinda sounds as an approach opposite to generic. I can easily imagine generics with methods code written with huge case GetTypeKind () statements. ---------------------------------------------------------------------- Basile B. · 2015-06-29 03:56 Quote from: skalogryz on June 29, 2015, 05:11:23 amQuote from: Fiji on June 28, 2015, 09:35:53 amHow about GetTypeKind for generics? So i can actually know the type at compile time? Wait wait. GetTypeKind to write a type specific code? It kinda sounds as an approach opposite to generic. You have a completly obsolete vision of Generics. The problem with FPC/Delphi generics is that they started as a feature for classes only. This limits something that could be much more powerfull! Instead they should have been defined, since the begining, as a kind of "namespace" in which the parameters can be used, whatever is the language construct: Code: [Select]template   type PT = ^T;   type TFoo = class   end;   type IBaz = interface   end;   function Baz(param: T): C;  // and so on... end; Read this and will start understnading how FPC generics are retarded. ---------------------------------------------------------------------- skalogryz · 2015-06-29 05:28 Quote from: BBasile on June 29, 2015, 05:56:33 amYou have a completly obsolete vision of Generics. The problem with FPC/Delphi generics is that they started as a feature for classes only. This limits something that could be much more powerfull! Instead they should have been defined, since the begining, as a kind of "namespace" in which the parameters can be used, whatever is the language construct: ... Really? a whole module as a template? with parameters? I wonder the number of parameters need for such "namespace". Surprisingly, someone finds less readable code more powerful. Rest in piece, good-old structured programming. ---------------------------------------------------------------------- taazz · 2015-06-29 06:13 Quote from: BBasile on June 29, 2015, 05:56:33 amRead this and will start understnading how FPC generics are retarded. OK I tried to read the thing but it got me nowhere with D specifics and all that (I hate what I've seen so far to be honest) but since you seem to be a bit more familiar with the concept can you please tell me what is missing from the current implementation in FPC? keep in mind that templates are already possible in fpc with out generics with a number of parameters (if I understood correctly the "parameters" the document referes to). In any case what is it that you miss exactly? ---------------------------------------------------------------------- Basile B. · 2015-06-29 06:28 Not a whole module. I shouldn't use the word 'namespace'. I rather meant a "definition scope" where the parameters are valid. what misses: - template (as said upper: a defintion scope for a set of parameters). Code: [Select]template Foo   // declarations end; - global functions templates, this would allow to write algorithms for every array type. Code: [Select]function Fold(arr: array of T; folder: function(p: T): T): T; begin end; function indexOf(arr: array of T; value: T): integer; begin end; actually this is my bigest doleance. I've started to explore how it would be possible now (even if in term of performance it's a failure right now): * https://github.com/BBasile/ArrayOps/tree/master/src and i've spotted someone who would also need this (look at the monkey work this galérien has to do just because global generic func/proc miss !!!): * https://raw.githubusercontent.com/Janilabo/MIMU/master/MIMU.pas Maybe i'll add more later. ---------------------------------------------------------------------- kazalex · 2015-06-29 07:46 Quote from: skalogryz on June 29, 2015, 05:11:23 amI can easily imagine generics with methods code written with huge case GetTypeKind () statements. It is possible to do it and rigth now, without GetTypeKind. PTypeInfo(TypeInfo(T)).Kind... But it works in runtime. "If GetTypeKind(T) = .." Or "Case TypeKind(T) Of" is a constant expression, which can be used at inlined method for selecting one code branch at compile time. ---------------------------------------------------------------------- marcov · 2015-06-29 08:31 Quote from: jc99 on June 29, 2015, 01:09:25 amQuote from: marcov on June 28, 2015, 09:53:03 pmYes, and no, it was always architecture dependent, just not automatically register size. "Architecture dependent", is the right word, I think there was never a 8-bit integer even on 6510-8-bit-machines. Most compiled systems are backported from mini computers (typically 16-bit or better) to micros. So the 8-bit situation was always had to be adapted. QuoteQuote from: marcov on June 28, 2015, 09:53:03 pmThat's also why Pascal, like most C compilers didn't go to 64-bit integers on 64-bit systems. Basically you are lugging around a lot of useless zeroes in most calculations. I know there was a big debate about that in the delphi/pascal-scene. I think I encountered it in 2002-2003, around the time that the compiler devs started working on the Itanium and later the x86_64 ports. Partially also because I had access to an Alpha at work, and did some C on it. QuoteThe other "new features" are about a community-bar where you could buy more stuff, did I get that right ? Please don't adopt these ...  We are only language and core libs compatible. Still, I think the base premise of structuring the installation of components is very good. I don't know how it works in practice (and I doubt Embarcadero will maintain it well for older Delphi versions in time). I don't have XE8, so I don't know how it works in practice. ---------------------------------------------------------------------- skalogryz · 2015-06-29 12:13 Quote from: kazalex on June 29, 2015, 09:46:51 amIt is possible to do it and rigth now, without GetTypeKind. PTypeInfo(TypeInfo(T)).Kind... But it works in runtime. "If GetTypeKind(T) = .." Or "Case TypeKind(T) Of" is a constant expression, which can be used at inlined method for selecting one code branch at compile time. That's exactly the problem. Why would a generic need to know the type it implements. If there's a type specific code written in generic, then it limits generic use to these types only. ---------------------------------------------------------------------- jc99 · 2015-06-29 14:37 Quote from: skalogryz on June 29, 2015, 02:13:48 pmThat's exactly the problem. Why would a generic need to know the type it implements. If there's a type specific code written in generic, then it limits generic use to these types only. That's not exactly true. You implement a special treatment for some types and another for everything else. e.G: Code: [Select]If GetTypeKind(T) = .. then   [...] // Handling for type .. else   [...]; // Handling for all other types .. But you are right that these constructs limit the generality. So they should be handled with care. ---------------------------------------------------------------------- kazalex · 2015-06-29 16:23 Quote from: skalogryz on June 29, 2015, 02:13:48 pmThat's exactly the problem. Why would a generic need to know the type it implements. If there's a type specific code written in generic, then it limits generic use to these types only. This is not necessarily so. Code: [Select]Case TypeKind(T) Of  tkDynArray: OptimizedForDynArrayCodeBranch;  tktkInterface : VeryInterfaceSpecificCodeBranch; Else  UniversalAndMayBeUnoptimalCodeBranchForAllOthers; End; ---------------------------------------------------------------------- marcov · 2015-06-29 16:49 Quote from: kazalex on June 29, 2015, 06:23:33 pm This is not necessarily so. Code: [Select]Case TypeKind(T) Of  tkDynArray: OptimizedForDynArrayCodeBranch;  tktkInterface : VeryInterfaceSpecificCodeBranch; Else  UniversalAndMayBeUnoptimalCodeBranchForAllOthers; End; That doesn't explain the inline support. I think it is simpler, to avoid a systems of events to "handle" runtime types or different base classes for strings, objects (owner-free options) etc, like in fgl. Delphi's generic support (and mostly, FPC's) was simply bad for cases where you had a base type for objects, valuetypes and automatied types. The handlers were always on a event/callback basis, incurring unnecessary overhead. ---------------------------------------------------------------------- rtusrghsdfhsfdhsdfhsfdhs · 2015-06-30 14:12 GetTypeKind is something like std::is_same. What can it be used for? Well for comperator in QuickSort and other algorithm. For those who think this is stupid go benchmark qsort vs std::sort. Why rely on RTTI if you can get the information at compile time. It can also be used to launch an algorithm for that specific type which it was optimized to.