Delphi compiler warnings pointing to Delphi's own units - delphi

In Delphi 2007, working on a project which includes a custom component, I'm getting this set of warnings as the first four in Messages when I do a full build (but not when I do a straight compile):
[DCC Warning] Dialogs.pas(1426): W1002 Symbol 'TFileOpenDialog' is specific to a platform
[DCC Warning] Dialogs.pas(1446): W1002 Symbol 'TFileSaveDialog' is specific to a platform
[DCC Warning] ComCtrls.pas(6757): W1036 Variable 'Section' might not have been initialized
[DCC Warning] ComCtrls.pas(19268): W1023 Comparing signed and unsigned types - widened both operands
I generally try to eliminate compiler warnings where I can, but these are "stock" Delphi units. Are these warnings the indirect result of something in my code? If so, how do I figure out what/where? If not, what should I do about them?

I believe it is because you have the stock Delphi source in your build path. If you remove the Delphi source directories, then it should build without these warnings.

The reason they show up only when doing a Build is that the compile command only compiles source which has changed since the previous compile. While the Build command recompiles everything in the project regardless of changes.
The warnings are most likely caused by the Delphi source folder being included in the project search path. Removing it and deleting the dcus in your project's folder will tell you if anything in the project required the Delphi source when you recompile. In my experience you should need the Delphi source if you have found a bug in Delphi's implementation and made a custom copy of a Delphi class to correct the bug. If this is the case when you try to build without the Delphi source you will usually get:
Unit '%s' is compiled with unit '%s'
in '%s' but different version '%s'
found (F2446)
Where %s will be some low level Delphi class.
If you don't get any error's it didn't really need the Delphi source.
This can also happen if the Delphi source is in the environment search path.

The first two warnings you mention (along with a few others) are to make you aware that the code you're currently using won't compile across different platforms Delphi supports. For Delphi 2007, there isn't much, but it carries the remnants of Kylix (the Linux version that's gone) and Delphi for .NET (which is also gone).
More recent versions of Delphi support cross-platform (Win32/Win64, OS X, iOS, and Android), where these messages are relevant again when developing Firemonkey applications (or VCL apps if there are differences between Win32 and Win64). They indicate the points in your code where you will have to make adjustments in your code for different operating systems. (For instance, the two you cite are for Windows-specific dialogs; you'd need to use a different dialog based on the target platform, and use {$IFDEF} statements around the areas that are platform-specific to keep them from being compiled in for other platforms.
As your current code can't be ported directly (even in a modern Delphi version) to anything other than Windows because it's VCL-based, you can safely turn off those warnings. Use Project->Options->Compiler Messages, and uncheck the following messages (or use the compiler define I've included in your code):
Library Symbol {$WARN SYMBOL_LIBRARY OFF}
Platform Symbol {$WARN SYMBOL_PLATFORM OFF}
Library Unit {$WARN UNIT_LIBRARY OFF}
Platform Unit {$WARN UNIT_PLATFORM OFF}
Unsafe type (.NET remnant) {$WARN UNSAFETYPE OFF}
Unsafe code (.NET remnant) {$WARN UNSAFECODE OFF}
Unsafe typecast (.NET remnant) {$WARN UNSAFECAST OFF}
The last two you've mentioned I can't reproduce with D2007 (IDE version 11.0.2804.9245), so I'd suspect that skamradt's answer is correct - it's because you have the VCL source directories in your search path, and you shouldn't. It should be set to $(BDS)\Lib. If you need to be able to step through the source, use the Project->Options->Compiler page, and check the Use debug DCUs option under Debugging instead.

I spent ages getting these problems (well, your first two anyway) and in my ignorance actually uninstalled Delphi and reinstalled it to no avail. I finally found that it is caused by the lack of project settings. At least atfirst, if you migrate a projects from an earlier Delphi, your existing project settings get converted but for no apparent reason Delphi can start forgetting about this and gives you a 'blank' set of project settings. You can see this by opening Project-Options where you will find Base, Release and Debug. Check out the active one (it is bold in the project manager) and you should see that it has no directory paths as well as all hints and warnings at their defaults. Most of these defaults are fine but 'Platform Symbol' and 'Platform unit' should be disabled (at least for Win32 stuff).
Regards,
Brian

If you want to continue explicitly compiling the VCL source into your project you can make a copy of the units that are raising the compiler hints/warnings and "fix" the hints/warnings in that copy.
Put the updated/"fixed" copies of those VCL units in another folder and make sure you add the path to that folder to your project's Search path BEFORE the path to the Delphi VCL source.
E.g. my project search path looks something like this: "C:\Dev\Source\MyFixedVCLUnits;C:\Program Files\CodeGear\RAD Studio\6.0\source"
To give an example of the simple fixes required to remove these warnings, here is one of the functions in the Dialogs.pas that now lives in my
"C:\Dev\Source\MyFixedVCLUnits" folder:
{$WARNINGS OFF}
function TFileOpenDialogWrapper.CreateFileDialog: TCustomFileDialog;
begin
Result := TFileOpenDialog.Create(nil);
Result.OnExecute := OnExecuteEvent;
end;
{$WARNINGS ON}
In this case, just add the {$WARNINGS OFF} etc as required.

TFileOpenDialog will work only on Windows Vista and up. You should use TOpenDialog instead of TFileOpenDialog, in newer Delphi versions it will detect what OS it is running and display proper dialog.
https://forums.embarcadero.com/thread.jspa?threadID=70498

If you develop only for specific platform open project source and add
{$WARN SYMBOL_PLATFORM OFF}

Compiler warnings can be disabled individually (separate per warning type) in the project options under 'Delphi Compiler | Hints and Warnings'

Related

Why can I compile 64 bit Delphi libraries through runtime package but not through source?

We are just starting on migrating some of our projects to 64-bit in Delphi, we also have a couple of 3rd party Delphi libraries that we are using.
Traditionally, when we use a 3rd party library we do so by using the design time package .bpl OR we just have the compiler compile the source code.
However, in 64-bit it seems we have to do it completely differently. If we are compiling a 64-bit library we need to use DCU.
For example, we have a library that we needed to use in 64-bit. The library supports 64-bit. To get it to work, I had to compile the runtime package as 64-bit then point the compiler to the outputted 64-bit DCU files. When I try to compile the library from source as 64-bit we get all kinds of errors.
So my question basically is: Why/How can we compile the source code through the runtime packages in 64-bit just fine, but when we try to compile as just source code in 64-bit we get errors?
To further illustrate just in case that wasn't clear:
A. Put all source files on search path. Compile program as 64-bit. ERRORS.
B. Open up supplied runtime .dproj from 3rd party library. Compile runtime library as 64-bit. Put outputted 64-bit DCU on search path. Compile program. Works fine.
Thanks
Edit: I'm going to be much more specific because it appears that i have failed in conveying what I'm trying to ask here.
We are using Clever Internet Suite 9.1 for Delphi.
We DO NOT use the design time package when compiling in 32-bit. We link directly to the source code through Delphi's search path. This works fine.
When I change my application to build as 64-bit We get this error:
[dcc64 Error] clSocket.pas(1971): E2089 Invalid typecast
A sample of the offending code (Slightly changed):
procedure cldostuff.WndProc(var Message: TMessage);
begin
if (Message.Msg = cl_const)
and (clSpecialType(Message).LookupHandle = FLookupHandle) then
begin
syncerror:= clSpecialType(Message).syncerror;
SetEvent(FCompleted);
end;
end;
The error is on the casting of the TMessage. I understand why TMessage would cause an error. I am not concerned about the error.
I am curious as to HOW compiling through a "package" works but not in DCU. Apparently I have misused the terminology of "Runtime package". I will post exactly what the clever developers told me on how to use in 64 bit.
The Clever Internet Suite fully supports 64-bit platform. The installer includes binaries for both 32-bit and 64-bit. Also, if you want to re-compile the library, you need to switch the platform option within the clinetsuite_x.dproj file, and recompile it (where _x depends on your Delphi version, e.g., in case of Delphi 10.3 Rio, the project file will be clinetsuite_103.dproj).
So I do Exactly that. I open up that .Dproj file and compile it. Once I do that it creates a Win64/Output folder that has ALL the dcus of the library. I can link to that and work in win64 bit just fine.
My questions is WHY does it work when I compile through the "Supplied .dproj file" but not when I compile through source code.
Hopefully I've done a better job of articulating what I am asking.
That compiler error is typically caused by a typecast between two value types of different size. If the code works in some compilation scenarios but not others then the obvious conclusion is that the record alignment options differ in those scenarios.
Most likely the package dproj file defines aligned records, i.e. {$ALIGN ON}. But your project does not. Perhaps it uses packed alignment, {$ALIGN 1}.
Make sure that all the units in the library are compiled with the same options as specified in the package dproj file. Typically that is done by the library providing an include file that specifies desired options and then the include file is included in all units. That insulates the code from compiler options specified in the host dproj file that are incompatible with those that the code requires.
You can add such a common include file since you have the source. In the longer term you should ask the developers of the library to make their code standalone and not require external specification of critical compiler options.

Error: F1026 File not found: 'System.Actions.dcu' switching back to Delphi XE2 from XE3

I'm moving my code to Delphi XE3 from XE2, but it should compile in both. I notice that some units get 'System.Actions' auto added to the USES clause. This then causes an error when returning to XE2 with:
F1026 File not found: 'System.Actions.dcu' (unit scope "System" indicates Win64, OSX32, Win32 only)
I've never really understood unit scope properly. Is there a correct solution to resolve this rather than wrapping stuff within compiler version {$IFDEF}'s?
Thanks
There is no Actions unit in XE2. It is new in XE3, as part of refactoring work to bring Actions support into FireMonkey. This is documented:
What's New in Delphi and C++Builder XE3:
Actions: FireMonkey now supports actions and action lists, two features that were previously supported only in VCL:
Important: Every FireMonkey or VCL application that uses actions must specify the System.Actions and System.Classes units in the uses section.
Changes in Implementation of VCL Actions
The System.Actions unit is created in the RTL package. Classes from the Vcl.ActnList unit that provide framework-independent action features are moved into this unit. Classes in System.Actions extend the most fundamental behavior of action features introduced in the TBasicAction and TBasicActionLink classes.
Important: As a result of these changes, you need to add the System.Classes and System.Actions units into the uses section.
Implementation of Actions in FireMonkey and VCL
FireMonkey (FMX)
The framework-independent implementation is common to FireMonkey and VCL:
This basic actions functionality is extended in the new System.Actions RTL unit.
VCL
Framework-independent action features that were implemented in the Vcl.ActnList unit in previous RAD Studio releases are now in the new System.Actions unit in the RTL (common to VCL and FireMonkey).
Important: As a result of these changes, you need to add the System.Actions unit to the uses section (or #includes) in your VCL applications that use actions.
You will have to either remove the reference to Actions if you are not actually using actions in your code, or else {$IFDEF} it out.
What Remy said is quite correct, but there may be an easier way to make your code work in both XE2 and XE3. Simply add a unit alias from System.Actions to Vcl.ActnList.
Add this in your project options, on the Delphi Compiler page. You need to add the following:
System.Actions=Vcl.ActnList
Note that if you need to compile in both XE2 and XE3 using the same .dproj file then you are out of luck. That unit alias setting will stop the program compiling under XE3. However, if you have have different .dproj files for XE2 and XE3, then this will allow you to use the same source in both. Or, if you only need to compile for XE2 at the command line, then you could add this unit alias there. I can't tell whether or not this will help you, but I know that the unit alias feature has helped me out of a similar spot on more than one occasion in the past.
If you have ONE project file you still can solve the problem with a "dummy" System.Actions.pas file in your project path directory:
This file will be taken under XE2.
The XE3 compiler will find his System.Actions.dcu in the IDE /lib directory.
Anyway: In normal cases you should use different project files - then the solution with the unit alias is recommended.
The dummy System.Actions.pas could look like:
unit System.Actions;
(*
XE2 compatibility unit: since XE3 unit System.Actions will be inserted into every
interface in units which use actions.
compilerswitch in [uses] is ignored by IDE - so this solution enable successful
compilation in XE2 with same project file than XE3
*)
interface
implementation
end.

How to disable warnings from given unit without modifying that unit?

So I am including in my unit some other units and after building application I receive a huge amount of warnings from those units. The amount is so large that I'am having problems in finding my own warnings on the list. ;-)
Is there some compiler directive which would allow me to turn those warnings off? But please note, that I don't want to modify those units in any way. I would like to achieve something like this:
unit MyUnit;
interface
uses
UnitA, {$WARN EMIT_WARNNIGS OFF} UnitB, {$WARN EMIT_WARNNIGS ON} UnitC, UnitD.
implementation
uses
UnitE, {$WARN EMIT_WARNNIGS OFF} UnitF, UnitG, {$WARN EMIT_WARNNIGS ON} UnitH.
This is an imaginary compiler directive which I would like to have, or maybe it exists and I don't know about it?
Thanks for your time.
There is a compiler directive to turn warnings off, but this can only be set in either project options in which case it applies to all units, or in a unit itself in which case it applies to that unit alone.
So, you're left with a few options.
Unrealistic option that does exactly what you ask:
So the only solution would be to disable warnings in your project and then enable them in all your own units using that directive.
Easiest and most realistic option:
Compile the units once and only use the DCUs by removing the source from your library path. That's easiest if you do not want to edit them anyway.
You can still add them in your browsing path which is different from the library path. In that case, the DCUs are used, but Delphi can still find the sources, so you can still navigate them whilst debugging.
Small advantage is that building your project is faster too, because these units don't need to be recompiled on each build.
Best option:
Stop using those units at all. Units with so many warnings are inferior software and can cause serious problems.
Other solutions:
Set aside your wishes of not modifying the units and add the compiler directives to those units anyway
Solve the warnings
I use Delphi 7 and here's how I do it...
Do not include the unit it the project .dpr or this will not work, add the folder of the unit on the search path of the Project Options.
Then in every unit you use it, use these compiler directives:
uses
{$WARNINGS OFF}{$HINTS OFF}
TheUnitHere;
{$WARNINGS ON}{$HINTS ON}
No, I don't believe there is such a directive.
The only way I have found to achieve this, is to
compile everything
put the dcu of the offending unit somewhere where the compiler will find it
make sure the dcu is found BEFORE the source for that dcu, or make sure the source cannot be found by the compiler
This will ensure that the pas is not compiled so you won't be swamped by the warnings from the offending units.
It is an approach I often take with library units (which we always compile from source) when I do not want the debugger stepping into them. I compile the release configuration (debug = off) then pick up the dcu's of the units that I do not want to step into and make sure that they are found by the compiler before their corresponding pas files.
One caveat: make sure that when you (need to) work on the offending units, the dcu gets removed, or you will be in for a lot of confusion. GExperts' "Clean directories' can help with this.

Shrinking exe by removing RTTI

In this question (link) it was said that the line below (in each unit) would remove as much RTTI as possible:
{$RTTI EXPLICIT METHODS([]) PROPERTIES([]) FIELDS([])}
The posting didn't mention what Delphi version it works with, but I assume D2010. However, when I include the line above, I get this error:
DCC Fatal Error: E2158 System unit out of date or corrupted:
missing TVisibilityClasses.
I'm using a "stock" version of D2010 and have never done anything that I'm aware of that would change the default installation or the libraries.
Any suggestions? TIA
Related question: link.
Make sure you put the "{$RTTI" line below the "unit unit1;" line.
Note that as of XE5 and newer, this directive needs to be in each individual unit for which you want to disable RTTI. Before that (as in comments, which applies only to XE4 and below) it could be in the DPR file and would apply to all units in the project.
The new RTTI is for Delphi 2010 and up.
It can be removed, but then lots of things will have limited functionality (like JSON conversion, part of DataSnap and many of the newer 3rd party libraries that do ORM or other mappings).
Things depending on TValue are gone anyway.
"old style" RTTI (which was introduced in Delphi 1 and is still present in Delphi 2010) cannot be removed.
So: it is recommended to remove RTTI only from your own units, and not from the RTL and VCL.
--jeroen

How can I set the $RTTI directive for the entire project?

I'm working on migrating an old project from Delphi 2007 to Delphi 2010. One thing I've found is that the resulting executable has more than doubled in size, and the original was already quite big. (Over 50 MB.) I suspect that a lot of it has to do with extended RTTI.
Since the project predates Delphi 2010, it doesn't use extended RTTI anywhere, and I'd like to be conservative about including it. Is there any way to use the Project Options dialog to globally set {$RTTI EXPLICIT METHODS([]) PROPERTIES([]) FIELDS([])} as the default? I'd have expected there to be an option for this (and for $WEAKLINKRTTI) somewhere, but I don't see them.
Does anyone know if this can be done from the "Additional options to pass to the compiler" field, or some other way? I'd really prefer not to have to add an include file to every single unit in the project, as there are a few thousand of them...
The behavior of the $RTTI directive has been changed since XE6 because actually it was a bug because it was supposed to be local to the current unit (and it was actually documented as that since Delphi 2010).
Also it could have fatal affects using the directive at all even in one unit because due to the bug it basically switched a global flag affecting the following units (as in the order of compilation).
You can try with the dcc32 –$weaklinkrtti command-line option. (like {$WEAKLINKRTTI ON}).
But that has not the impact of {$RTTI EXPLICIT METHODS([]) PROPERTIES([]) FIELDS([])} in each unit.
Your best bet would be to have it at the top of each unit in an include file.
But then it wouldn't do it for the VCL/RTL which would still be inflated....
Update: Also make sure you compare what's comparable. For instance verify if you don't include debug information in the Linker Options in the new D2010 project where you may not have it in the D2007 one...
In a comment on Mason's own blog, in response to a comment of mine, Mason answered this question.
Try putting these two lines at the top
of your DPR, before the USES clause:
{$WEAKLINKRTTI ON}
{$RTTI EXPLICIT METHODS([]) PROPERTIES([]) FIELDS([])}
This will make sure that no RTTI gets
generated for your own code or any
third-party libraries you use, unless
they’re in a unit where RTTI
generation is explicitly enabled. You
can’t turn it off for the RTL or VCL,
but that shouldn’t add very much to
your size anyway.
Are you certain this is caused by the new RTTI info? While it's a lot of data it shouldn't really double the size of your application.
Check that it's not including debug info in the release build executable.
(Project options -> Delphi Compiler -> Debug information should be False)
As for the question, I use {$WEAKLINKRTTI ON} before the uses clause in the dpr file and it seems to work fine.
I don't know of such an option, but I still would use an include file.
I wont be a problem for any experienced Delphi programmer to write a small program to add an {$i ProjectIncludeFile.inc} to any unit in your folders (immediatly after the unit line).
And that way you can use it for whatever purpose you like.
I myself use if f.i. to set a WriteTempFiles compiler directive (which I use f.i. to save stringlist contents at various places when developing the program), that way I can disable it in one place when the program is ready for deployment.
Since most of my projects involve multiple executables and/or dll's, this is the easiest way to accomplish this globaly for the whole project.

Resources