Recent

Author Topic: FPC v3.0.4 bug in "with" statement  (Read 2187 times)

440bx

  • Hero Member
  • *****
  • Posts: 1131
FPC v3.0.4 bug in "with" statement
« on: February 10, 2019, 02:57:30 pm »
Hello,

There are occasions when FPC 3.0.4 does not generate correct code for a "with" statement.

Attached is a short console program that exhibits the problem. 

Also attached is a screenshot showing the problem.  On the left side is the output of FPC and, just for completeness, on the right side is the output of the same program compiled with Delphi 2.0.

I do not have a trunk install of FPC.  It would be helpful if someone would determine the existence or non-existence of this bug in the trunk version.   Thank you.

using FPC v3.0.4 and Lazarus 1.8.2 on Windows 7 64bit.

Bart

  • Hero Member
  • *****
  • Posts: 3518
    • Bart en Mariska's Webstek
Re: FPC v3.0.4 bug in "with" statement
« Reply #1 on: February 10, 2019, 03:06:56 pm »
In fpc TRect has a property Width, in Delphi 2 it does not.
In With RectA do.. Width points to RectA.Width in fpc, but the local variable Width in Delphi.

Rename your local variables Widht/Heigth to something else and it should work.

(Yet another reason to avoid "with somevar do" constructs.)

Bart

440bx

  • Hero Member
  • *****
  • Posts: 1131
Re: FPC v3.0.4 bug in "with" statement
« Reply #2 on: February 10, 2019, 04:10:52 pm »
In fpc TRect has a property Width, in Delphi 2 it does not.
In With RectA do.. Width points to RectA.Width in fpc, but the local variable Width in Delphi.

Rename your local variables Widht/Heigth to something else and it should work.

(Yet another reason to avoid "with somevar do" constructs.)

Bart
Thank you for explaining the reason for the discrepancy. I appreciate your looking at the code and determining why it did not work as expected.

As a side note, the inclusion of properties named "Width" and "Height" in the definition of TRECT introduced an unnecessary incompatibility between Delphi and FPC.  I can't help questioning the wisdom of such additions.

Recently, I submitted missing definitions for constants and structures for FlashWindowEx.  Since I do not see much, if any, value in using the "Hungarian" notation, I customarily get rid of the "Hungarian" prefixes.  Marco informed me that he had added the definitions using the field names as defined in MSDN (thus including the Hungarian prefixes).   I didn't think any of it but, this problem made it clear that consistency does make a difference.

The presence of "Width" and "Height" can cause problems when porting C code to FPC or Pascal code from Delphi and, it breaks the consistency of definitions.   Additionally, a programmer should be able to take advantage of the features offered by a language - including the "with" statement in Pascal.   IMO, the "with" statement is about as dangerous as a bar of soap when the user decides to eat it instead of using it to cleanse. 

I don't expect the definition of TRECT, or any other for that matter, to change but, those "extras" in standard Window structures make porting C code to FPC riskier than it should be.

Thank you again for pointing out why the code does not work as expected.  I do appreciate your help.



« Last Edit: February 10, 2019, 04:21:15 pm by 440bx »
using FPC v3.0.4 and Lazarus 1.8.2 on Windows 7 64bit.

marcov

  • Global Moderator
  • Hero Member
  • *****
  • Posts: 7455
Re: FPC v3.0.4 bug in "with" statement
« Reply #3 on: February 10, 2019, 05:07:40 pm »
As a side note, the inclusion of properties named "Width" and "Height" in the definition of TRECT introduced an unnecessary incompatibility between Delphi and FPC.

FPC added them because Delphi did in D2006.

Quote
  I can't help questioning the wisdom of such additions.

Fair enough. Be sure to let Embarcadero know!

Quote
Recently, I submitted missing definitions for constants and structures for FlashWindowEx.  Since I do not see much, if any, value in using the "Hungarian" notation, I customarily get rid of the "Hungarian" prefixes.  Marco informed me that he had added the definitions using the field names as defined in MSDN (thus including the Hungarian prefixes).   I didn't think any of it but, this problem made it clear that consistency does make a difference.

It is about which consistency you choose! I primarily follow MSDN, since it is defined for all functions and is consistent.
 
Quote
The presence of "Width" and "Height" can cause problems when porting C code to FPC or Pascal code from Delphi and, it breaks the consistency of definitions.   Additionally, a programmer should be able to take advantage of the features offered by a language - including the "with" statement in Pascal.   IMO, the "with" statement is about as dangerous as a bar of soap when the user decides to eat it instead of using it to cleanse. 

Besides that this is not a problem that we introduced, do you really think that such a compatibility over multiple languages, multiple SDK versions multiple delphi versions and multiple FPC versions is doable in practice at all?

It is easy to blame every little discrepancy on some policy or error. But not everything is avoidable.

« Last Edit: February 10, 2019, 06:34:01 pm by marcov »

440bx

  • Hero Member
  • *****
  • Posts: 1131
Re: FPC v3.0.4 bug in "with" statement
« Reply #4 on: February 10, 2019, 05:37:29 pm »
As a side note, the inclusion of properties named "Width" and "Height" in the definition of TRECT introduced an unnecessary incompatibility between Delphi and FPC.

FPC added them because Delphi did in D2006.

Quote
  I can't help questioning the wisdom of such additions.

Fair enough. Be sure to let Embarcadero know!
I would if I used their products but, your point is definitely valid.  The FPC team is caught between a rock and a hard place.  The goal of Delphi compatibility does occasionally force some "less than optimal" choices.

Recently, I submitted missing definitions for constants and structures for FlashWindowEx.  Since I do not see much, if any, value in using the "Hungarian" notation, I customarily get rid of the "Hungarian" prefixes.  Marco informed me that he had added the definitions using the field names as defined in MSDN (thus including the Hungarian prefixes).   I didn't think any of it but, this problem made it clear that consistency does make a difference.

It is about which consistency you choose! I primarily follow MSDN, since it is defined for all functions and is consistent.
 
There, the rock and the hard place. Unfortunately,  it is not always possible to be Delphi compatible and consistent with MSDN.

One thing I want to make sure is clear: I greatly appreciate having FPC and all the hard work every member of the team puts forward to make FPC what it is and better every day. 

I know I am "sometimes" dry when in programmer mode.  (btw, that "sometimes" is most of the time, as some may have already noticed. ;))

Besides that this is not a problem that we introduced, do you really think that such a compatibility over multiple languages, multiple SDK versions multiple delphi versions and multiple FPC versions is doable in practice at all?
I didn't know that.  I appreciate your making that clear and, no, I definitely don't think it is possible to be compatible with multiple versions of anything and, given the occasionally conflicting goals the FPC team faces, IMO, you guys are doing a really good job.

It is easy to blame every little discrepancy on some policy or error. But not everything is unavoidable.
It wasn't nor is my intention to blame.  My apologies if it came across that way.  My intention is to point out problems, inconsistencies and, hopefully contribute to eliminate them when possible.

Part of the problem is that I use Delphi 2.0 as the reference compiler.   The last version of Delphi I purchased was Delphi 5 and, I don't even have it installed because SoftICE doesn't understand that version's debug symbols.  The only reason I purchased it (v5) is because it supports 64 bit integers, that's the only feature it had that interested me.   I find later versions of Delphi to border on being totally unusable (particularly those that force Unicode onto the programmer.)

I'm rather grateful for the existence of FPC.  AFAICT, the only 64bit Pascal compiler worth using on the Windows platform (can't say anything about other platforms but, I suspect that is true on most others too.)


« Last Edit: February 10, 2019, 05:40:13 pm by 440bx »
using FPC v3.0.4 and Lazarus 1.8.2 on Windows 7 64bit.

Bart

  • Hero Member
  • *****
  • Posts: 3518
    • Bart en Mariska's Webstek
Re: FPC v3.0.4 bug in "with" statement
« Reply #5 on: February 10, 2019, 06:53:16 pm »
You can give Delphi 7 PE a change perhaps (it's free of charge IIRC).
At least it has AnsiStrings and supports overload (which D3 did not).
Older Delphi's are a bit of a PITA to install on modern Windows (they insist on writng configuration data where they have no write access, so every time you start you open with a blank project...).

Bart

440bx

  • Hero Member
  • *****
  • Posts: 1131
Re: FPC v3.0.4 bug in "with" statement
« Reply #6 on: February 10, 2019, 07:22:02 pm »
You can give Delphi 7 PE a change perhaps (it's free of charge IIRC).
At least it has AnsiStrings and supports overload (which D3 did not).
Thank you Bart :).  I just downloaded it and will give it a whirl in a VM sometime soon.   It's probably a better version to compare with FPC than Delphi 2.

Older Delphi's are a bit of a PITA to install on modern Windows (they insist on writng configuration data where they have no write access, so every time you start you open with a blank project...).

Bart
That's why I only use the command line compiler. Much simpler and, for debugging, either TD32 or SoftIce.  I very, very rarely go into the IDE (usually, it is to compile an example I found somewhere that has trouble compiling with the command line compiler)

Thanks again.
using FPC v3.0.4 and Lazarus 1.8.2 on Windows 7 64bit.

marcov

  • Global Moderator
  • Hero Member
  • *****
  • Posts: 7455
Re: FPC v3.0.4 bug in "with" statement
« Reply #7 on: February 10, 2019, 07:35:08 pm »
It wasn't nor is my intention to blame.  My apologies if it came across that way.  My intention is to point out problems, inconsistencies and, hopefully contribute to eliminate them when possible.

Don't worry, no need to apologize. If I'm a bit short (or harsh) in a detailed way, that is a good thing. That means I consider it worth the trouble to explain and have you quickly learn, just as I had to (and still do if I go into areas of FPC that are new to me).   

Quote
Part of the problem is that I use Delphi 2.0 as the reference compiler.   

FPC has long kept to D7, but 3.0 has firmly gone beyond that.

Quote
The last version of Delphi I purchased was Delphi 5 and, I don't even have it installed because SoftICE doesn't understand that version's debug symbols.  The only reason I purchased it (v5) is because it supports 64 bit integers, that's the only feature it had that interested me.   I find later versions of Delphi to border on being totally unusable (particularly those that force Unicode onto the programmer.)

I'm rather grateful for the existence of FPC.  AFAICT, the only 64bit Pascal compiler worth using on the Windows platform (can't say anything about other platforms but, I suspect that is true on most others too.)

At work I still use Delphi XE 10 (Seattle). The only real problem that I have is that the debugger is less stable. Quite often if you press F7 at the end of a procedure the debugger hangs.

440bx

  • Hero Member
  • *****
  • Posts: 1131
Re: FPC v3.0.4 bug in "with" statement
« Reply #8 on: February 10, 2019, 08:29:52 pm »
At work I still use Delphi XE 10 (Seattle). The only real problem that I have is that the debugger is less stable. Quite often if you press F7 at the end of a procedure the debugger hangs.
I've had a chance to use that version of Delphi.  The problem I ran into very early is that the compiler seems to make pchar a synonym for pwidechar.     If the program "looks" at data that wasn't defined in the program itself, the compiler's dereferencing a pchar as a pwidechar (which that version seems to be rather fond of doing) yields the wrong results. 

I wanted a 64bit Pascal compiler but, the versions of Delphi that use Unicode seem unusable to do any kind of systems programming.  I gave up and decided to have a look at FPC.  I'm rather pleased I did and I'm looking forward to the next stable release.

IMO, for systems programming,  C/C++ and FPC (other than assembler, of course) seem to be two of the few options left.  FPC seems particularly well suited at this time since MS and GNU have been making the removal of dependencies on the C library ever more cumbersome to accomplish.

FPC allows me to create reasonably sized standalone programs with trivial ease (as it should be.)  Creating standalone programs with MS C/C++ is tortuous, creating them with g++ is easy but the exes are rather big.

I find it interesting that most people use FPC for the components it makes available.  I use it because it's easy to strip everything out and just have the code I want.   Basically, the opposite of what brings users to FPC.

I recently ported some C/C++ code I wrote in C to FPC.  The 64bit MS executable is about 435K dependent on some DLL (something140.dll), the g++ standalone is over a meg (to g++'s credit, it's trivial to create a standalone exe - it just puts the banana, the gorilla and the whole rain forest in the exe but, at least it stands alone.)  The FPC exe with more capabilities (I added features while porting) is less than 300K  (and it will get smaller once I take the time to figure out how to eliminate the RTL out of it - my code doesn't need the RTL but the linker complains about not finding "somethingMain" (the entry point).  Taking care of that is on my todo list.

« Last Edit: February 10, 2019, 08:37:56 pm by 440bx »
using FPC v3.0.4 and Lazarus 1.8.2 on Windows 7 64bit.

marcov

  • Global Moderator
  • Hero Member
  • *****
  • Posts: 7455
Re: FPC v3.0.4 bug in "with" statement
« Reply #9 on: February 10, 2019, 10:03:42 pm »
At work I still use Delphi XE 10 (Seattle). The only real problem that I have is that the debugger is less stable. Quite often if you press F7 at the end of a procedure the debugger hangs.
I've had a chance to use that version of Delphi.  The problem I ran into very early is that the compiler seems to make pchar a synonym for pwidechar.     If the program "looks" at data that wasn't defined in the program itself, the compiler's dereferencing a pchar as a pwidechar (which that version seems to be rather fond of doing) yields the wrong results. 

Yes of course. I had that too, with e.g. D2009. But simply sorting units by type

  • operates on common strings -> leave as is
  • operate on strings that must remain 1-byte -> replacing pchar with pansichar
  • operates on non strings -> replace by pbyte


is basically most of the work. I think I did it in three days for the quite sizable work codebases. For operating on buffers I introduced an own type that was pbyte on D2009+ and pchar on older delphis. (because older delphi's miss pointer math on non pchar pointer types)

I don't really see a relation of this to systems programming. The core windows system is widechar based, and pchars are not really special for system.

engkin

  • Hero Member
  • *****
  • Posts: 2513
Re: FPC v3.0.4 bug in "with" statement
« Reply #10 on: February 10, 2019, 10:07:21 pm »
the linker complains about not finding "somethingMain" (the entry point).
I assume you mean Windows default symbol name for console apps: _mainCRTStartup.

You can pass -s to the compiler and change it manually in the produced script (link.sys) and batch (ppas.bat) files.

Also, FPC has -XM to do the same, but does not seem to work, and using: -k--entry=SomeOtherName does not work either, as it comes before the original name:
Quote
ld.exe .... --entry=SomeOtherName .....  --entry=_mainCRTStartup ...

440bx

  • Hero Member
  • *****
  • Posts: 1131
Re: FPC v3.0.4 bug in "with" statement
« Reply #11 on: February 10, 2019, 10:56:49 pm »
@Marco:
I don't really see a relation of this to systems programming. The core windows system is widechar based, and pchars are not really special for system.
Here is an example.  if you want to trap API calls made by some dll in your process, you need to walk the IAT and/or the HintNameTable looking for the name of the function you want to trap, determine its location in the exe and then patch the entry.  That name is not in Unicode and treating it as such will not work.  You may want to do this with your own program to install one or more loggers for various API calls of interest (particularly when debugging) or to see what some other program is doing.

I mentioned systems programming because once the code is looking outside what is produced by the Delphi compiler, treating pchar as pwidechar causes quite a number of gratuitous headaches.   When I tell FPC that something is a pchar, it treats it as a pchar.  Good compiler!.   With the exception of resource names, most everything that is not user data in a PE file, is plain char.

It's amazing what a big difference little things can make.  Treating datatypes as what they really are, sure makes life easier.

@Engkin:
the linker complains about not finding "somethingMain" (the entry point).
I assume you mean Windows default symbol name for console apps: _mainCRTStartup.

You can pass -s to the compiler and change it manually in the produced script (link.sys) and batch (ppas.bat) files.

Also, FPC has -XM to do the same, but does not seem to work, and using: -k--entry=SomeOtherName does not work either, as it comes before the original name:
Quote
ld.exe .... --entry=SomeOtherName .....  --entry=_mainCRTStartup ...

Thank you very much.  I'll be trying that soon (hopefully, very soon.)
using FPC v3.0.4 and Lazarus 1.8.2 on Windows 7 64bit.

PascalDragon

  • Hero Member
  • *****
  • Posts: 636
  • Compiler Developer
Re: FPC v3.0.4 bug in "with" statement
« Reply #12 on: February 11, 2019, 04:42:40 pm »
I mentioned systems programming because once the code is looking outside what is produced by the Delphi compiler, treating pchar as pwidechar causes quite a number of gratuitous headaches.   When I tell FPC that something is a pchar, it treats it as a pchar.  Good compiler!.   With the exception of resource names, most everything that is not user data in a PE file, is plain char.
Please note that PChar depends on the mode switches. In mode DelphiUnicode or if modeswitch UnicodeStrings is set the type PChar will be an alias to PWideChar just like in Delphi. Otherwise it's an alias to PAnsiChar (and that is also what you'd use in Delphi to deal with non-Unicode zero terminated characters).
I personally consider it as defensive programming to use either PWideChar or PAnsiChar if my code depends on that instead of PChar as the default might change in the future.

440bx

  • Hero Member
  • *****
  • Posts: 1131
Re: FPC v3.0.4 bug in "with" statement
« Reply #13 on: February 11, 2019, 06:40:31 pm »
Please note that PChar depends on the mode switches. In mode DelphiUnicode or if modeswitch UnicodeStrings is set the type PChar will be an alias to PWideChar just like in Delphi. Otherwise it's an alias to PAnsiChar (and that is also what you'd use in Delphi to deal with non-Unicode zero terminated characters).
I personally consider it as defensive programming to use either PWideChar or PAnsiChar if my code depends on that instead of PChar as the default might change in the future.
I appreciate that information.  Either I use no mode at all, which means I use the default mode - i.e, FPC, or specifically OBJFPC, either with explicit enabling/disabling of other features.   There are some "features" I want to ensure I do _not_ enable and some that cannot be turned off I will never use, except possibly in throw-away code.

I find having to explicitly use pansichar instead of pchar a disgrace.  A compiler "designer" laid the idea of making pchar the same as pwidechar and, now to avoid that atrocity, programmers have to play it "safe" and use pansichar.   A programmer shouldn't have to do that kind of defensive programming.  The compiler should do what the programmer specified, not something else.

I have very strong feelings about the way Borland/Codegear/Embarcadero have contaminated the Pascal language with decisions that are nothing short of atrocities.  Treating pchar as pwidechar is one of them.

At the very least, there should have been an option, compiler switch, to enable/disable that "feature" and the default should be how it worked in the past not some new way that breaks just about every piece of code written before it.

My way of being defensive is, the last time Borland/Codegear/Embarcadero saw a dime from me is when I purchased Delphi 5 and, considering Delphi's market share trend, it seems I am not the only one with that method.  I don't see them getting any money from me in the future either, I haven't even bothered to get their free/community version, their product has become something I don't want, even for free.

If they had not made pchar a synonym for pwidechar, or if they had given a way to turn that disgrace off, most likely I would have purchased the first version of 64bit Delphi (I don't remember which one it was.) and, I would be a customer today.  For 64bit apps, I had to use C/C++ instead. I really dislike C but, I have to give credit to MS for their VS debugger.  I still use C/C++ because of it.  I wanted to say something positive in this post for a change.  Now that I am in positive mode ...

I can also say that I am really pleased with FPC. It does have its rough edges here and there but, it gets the job done and so far, when I tell it something is a pchar, it's always treated it as a pchar.  Good compiler!.

I know you are part of the team that works on FPC, therefore have my heartfelt thank you for making FPC possible and what it is.


using FPC v3.0.4 and Lazarus 1.8.2 on Windows 7 64bit.