are you kidding me ? for years Embarcadero says that String is not a place to hold binary data, stop using them as a blob container, and now this trick with InputQuery ?!
are you kidding me ? for years Embarcadero says that String is not a place to hold binary data, stop using them as a blob container, and now this trick with InputQuery ?!
InputQuery( 'Login', ['Username', #1'Password:'], ['', ''],
procedure(const AResult: TModalResult; const AValues: array of string)
begin
end);
InputQuery( 'Login', ['Username', #1'Password:'], ['', ''],
procedure(const AResult: TModalResult; const AValues: array of string)
begin
end);
One of those WTF?! moments :-) I scratched my head when I read it in the What's new posts.
ReplyDeleteanother one, traditionnaly, Integer and Cardinal were platform dependants when LongInt and LongWord were fixed size...NativeInt was the first derogation with Integer fixed as a 32bits value, now LongInt and LongWord are dynamics...a new retrocompatibiliy nightmare.
ReplyDeletePaul TOTH On the #1 in the string, this is still a string, not binary data. The special marker is for making the password behave like a password. I can understand it is borderline, but doesn't seem so odd.
ReplyDeleteSpeaking of the LongInt this is a platform specific data type and has always been. But on Windows in both 32bit and 64bit it happens to be the same (an odd decision by Microsoft). And the type is used in APIs. On all other platforms, for example iOS, this is a type that changes. By making it flexible, many iOS calls are the same, regardless of the bitness. If not, you'd have many iOS called plagued with IFDEFS for 32/64 bit. Which would be much worse (see Xcode 64bit migration docs, as an example).
I really don't see any retro compatibility nightmare.
Marco Cantù I desagree with this vision of things, from my point of view Delphi has it's own definitions that do not rely on Microsoft nor Apple but Turbo Pascal's history. If the iOS API needs a fixed 32 bits int they should be declared with a fixed LongInt, and if it have to be platform specific it have to be declared with a dynamic Integer...just because that how Pascal call them. changing the meaning of thing can just add confusion. As sayd in Delphi 6 help : The generic integer types are Integer and Cardinal; use them as much as possible because they give better performance with the CPU and operating system used.
ReplyDeleteSplitting hairs we are today, eh? :D
ReplyDeleteAs a rule of thumb: I tend to agree with Paul TOTH regarding integers. The VCL and RTL should be consistent and not have a type that changes at compile time for different platforms, because there are way too many things that can go wrong with that in applications. Changing the bitness may be OK for APIs but is going to cause A LOT of trouble for application-generated data files, leading to difficult to find potential bugs if someone wishes to use the same data files across platforms (which, quite frankly, I see as a potentially common occurrence... why would you want to change some code that is working on a platform to adjust to a new one?). That said, I agree with Marco on the string thing: that's not a binary buffer, that's a marker for a string - no problem there.
The point is LongInt follows the platform and it did so for Win16, Win32, and Win64.
ReplyDeleteNativeInt follows the CPU bits. Integer is language specific and more agnostic.
The fact there is a discrepancy is because Microsoft is at odds with all other platforms. Remember we need to be tied to the platform and the C/C++ language, or supporting C++Builder would become a mess.
LongInt is a type often used in API declarations, more than in developers code. And we want those to be as smooth to migrate as possible. Developers code should generally use CPU agnostic or CPU specific types (Integer, NativeInt, Cardinal, NativeUint).
I know it is true that in the past the assumptions were different.
I would like to know, why FixedInt and FixedUInt types where added. I mean, Delphi XE already had Int32 and UInt32, which are much clearer types. Or are some newer versions missing those types?
ReplyDeletePaul TOTH Marco Cantù Emba got Longint/Longword right. They map to C++ long int and unsigned long int. They are expected to follow the underlying platform.
ReplyDeleteMarco Cantù The distinction between Integer and LongInt is not really as you call it. Integer is C++ int and LongInt is C++ long int. That's all.
ReplyDeleteI'm a Delphi developper and I really don't care about how C++ #defines types :)
ReplyDeleteBTW: http://docwiki.embarcadero.com/Libraries/XE8/en/System.Longint
Delphi: type Longint = Integer;
C++: typedef int Longint;
well done !
Paul TOTH I'm a Delphi developer who does a lot of interop code. I care deeply about type mappings onto the underlying platform types.
ReplyDeleteThat documentation is just wrong. Quite clearly Delphi Integer is not the same as Delphi Longint.
For years, many developers have taken the narrow view that Delphi is used for desktop apps, naive apps, things which are complete within themselves. Sorry, but as David Heffernan points out, interop matters.
ReplyDeleteWell, I don't understand what is a problem with interop when we says that Integer is platform dependand and LongInt a fixed size 32bits...just like it was since Delphi 1 I guess ?!
ReplyDeleteAs far as I know C++ int is platform dependand, why Integer should not ?
Why should ShortInt and SmallInt be platform-Independent while LongInt is not ? C++ long is 32 bits AFAIK.
I've translated a lot of C++ code to Delphi, and always do it that way:
int -> Integer // was before 64bits and NativeInt
long -> LongInt // was before XE8
Now it have to be
int -> {$IFDEF CPU64}NativeInt{$ELSE}Integer{$ENDIF}
long ->{$IFDEF XE8}FixedInt{$ELSE}LongInt{$ENDIF}
Anyway damage is done.
Paul TOTH Your problem here is that you don't understand the topic. There's no point in you criticising that which you don't understand. That's not meant to be harsh by the way. But you proposed mappings, with the IFDEF CPU64 and IFDEF XE8 demonstrate clearly your misunderstanding.
ReplyDeleteAs I already said, `Integer` maps to `int`. `LongInt` maps to `long int`. That is true for each and every single version of Delphi. Both `Integer` and `LongInt` are platform dependent and always have been. In fact `ShortInt` is platform dependent since it maps to `short int` which is platform dependent. I rather suspect that `SmallInt` is also platform dependent since I presume it maps to `char`.
In yours (end everyone else's defence), Emba have never gone out of their way to make these mappings clear. This has, in my view, led to the confusion that `LongInt` has a fixed size. Consider this SO question: http://stackoverflow.com/questions/24507704/difference-between-longint-and-integer-longword-and-cardinal The accepted answer by well known Delphi interop expert Rudy Velthuis, is critcally factually wrong.
It's high time that Emba made these type mappings explicit. If they would do so then there's a chance that people would start to unlearn these misconceptions. Are you following this Marco Cantù ?