DCC Error : E2003 Undeclared identifier: 'Result' - delphi

I was screwing around with debug setting on my compiler and now I am getting these errors that I can't seem to get rid of.
[DCC Error] HASPCODE.PAS(223): E2003 Undeclared identifier: 'Result'
It didn't complain before, but now no matter what I said the debugging settings to it keeps raising the above error just for the HASPCODE.PAS file only.
For instance, Here is one of the functions where the error is raised.
function THasp.IsHasp:Boolean;
begin
Result := fIsHasp; <<=======
end;

The implicit function Result variable is only available when the extended syntax compiler option is enabled.
The Result variable. In the {$X+} mode, the predefined
variable Result can be used within a function body to hold
the function's return value.

Related

GlobalFree - Incompatible types: 'NativeUInt' and 'PWideChar'

Documentation of WinHttpGetIEProxyConfigForCurrentUser says:
The caller must free the lpszProxy, lpszProxyBypass and
lpszAutoConfigUrl strings in the WINHTTP_CURRENT_USER_IE_PROXY_CONFIG
structure if they are non-NULL. Use GlobalFree to free the strings.
I wrote the following code (Delphi 10.3.2):
var
VConfig: TWinHttpCurrentUserIEProxyConfig;
begin
FillChar(VConfig, SizeOf(VConfig), 0);
if not WinHttpGetIEProxyConfigForCurrentUser(VConfig) then begin
RaiseLastOSError;
end;
...
if VConfig.lpszAutoConfigUrl <> nil then begin
GlobalFree(VConfig.lpszAutoConfigUrl); // <-- Error
end;
and got an error:
[dcc32 Error] E2010 Incompatible types: 'NativeUInt' and 'PWideChar'
Questions:
should I type-cast PWideChar to NativeUInt?
can I use GlobafFreePtr instead of GlobafFree (it accepts PWideChar and works fine in my tests)?
When MSDN tells you to free with a specific function then doing just that is your best bet.
Parts of the Windows API is written in C and (some parts even without STRICT defined?) and other languages with better type checking will require casts in some places.
In the case of HGLOBALs you have the GlobalFlags function that can help you out. In your case the low byte of flags is zero indicating that there are no locks. If the strings had been allocated as movable the documentation would have to tell you to lock before accessing the memory and it does not.
The final nail in the coffin is to debug the function and if you do that you will see that it calls GlobalAlloc with flags set to 0x40 (GPTR) and should therefore be passed to GlobalFree without unlocking. If your compiler complains then you must cast to the appropriate type:
GlobalFree(HGLOBAL(VConfig.lpszAutoConfigUrl));

Using SmartPointer as result data type in function requires invoke call explicitly

I am using the SmartPointer in http://members.adug.org.au/2011/12/05/smart-pointers/
I defined a IStringList:
type
IStringList = ISmartPtr<TStringList>;
I may then use as follow without memory leak prompt:
var S: IStringList;
begin
S := TSmartPtr<TStringList>.Create();
S.Add('abc');
end;
If I use the IStringList as result data type in a function:
function GetList: IStringList;
begin
Result := TSmartPtr<TStringList>.Create();
Result.Add('abc'); // E2010
end;
I get a compiler error:
[dcc32 Error] Unit2.pas(31): E2010 Incompatible types: 'SmartPointer.ISmartPtr<System.Classes.TStringList>' and 'Procedure of object'
A workaround solution would be:
Result.Invoke.Add('abc');
But that defeat the purpose of syntax cleanliness of using SmartPointer. Is there a solution?
It's quite an interesting one. For whatever reason, the compiler treats Result differently from other variables. I see no good reason for that, so this feels like a compiler bug.
I see a few workarounds:
Declare a local variable, use that, and finish the function by assigning that local variable to Result.
Using parens to call the function: Result().Add('abc').
Using a better smart pointer. For instance, a smart pointer that is not based on method invocation would be a good start. A generic record with an implicit conversion operator would presumably work.
Find a version of the compiler without the bug, if indeed it is a compiler bug.
Give up on smart pointers and write traditional style code. Every time I contemplate using smart pointers in Delphi I conclude that I'd rather see the explicit try/finally blocks and understand when my objects are created and destroyed.
FWIW, you can greatly simplify the issue by stripping out the smart pointer code, and removing the generic types. Here is the cleanest SSCCE that I can concoct:
{$APPTYPE CONSOLE}
type
TFunc = reference to function: TObject;
procedure Foo;
var
F: TFunc;
begin
F.ClassName; // compiles
end;
function Bar: TFunc;
begin
Result().ClassName; // compiles
Result.ClassName; // [dcc32 Error] E2003 Undeclared identifier: 'ClassName'
end;
begin
end.
I'm now convinced that this is a compiler bug.
It is presumably related to the rather unusual language feature of Delphi that means the function call parentheses can be omitted for a function that has no parameters. This convenience sometimes brings with it ambiguity. However, in this case there is no ambiguity. The . operator has no meaning when applied to a TFunc<TObject> and so the only way to interpret these statements is that the function is called, and the . operator applied to the returned value.
Bug report: QC123218.
{ I'm not allowed to comment... -.-' Feel free making it one. }
I'm afraid there is no way without defeating the purpose of smart pointers. I tried to solve your problem as part of trying to find a way to assign an anonymous method to an interface variable or parameter (SO question from July 2013). Coming back to it every now and then or asking around didn't help in finding a solution.

Delphi - disable controls not working EMS Advanced Export 4

I tried to disable ABSQuery1 controls before exporting data :
procedure TForm1.QExport4Dialog1BeforeExportRow(Sender: TQExport4;
Row: TQExportRow; var Accept: Boolean);
begin
ABSQuery1.DisableControls;
end;
But I get :
> [dcc32 Error] Unit1.pas(75): E2003 Undeclared identifier: 'TQExport4'
> [dcc32 Error] Unit1.pas(76): E2003 Undeclared identifier:
> 'TQExportRow' [dcc32 Error] Unit1.pas(204): E2005 'TQExport4' is not a
> type identifier [dcc32 Error] Unit1.pas(205): E2005 'TQExportRow' is
> not a type identifier [dcc32 Fatal Error] Project1.dpr(15): F2063
> Could not compile used unit 'Unit1.pas'
What am I doing wrong ?
Your error messages all indicate that you have not used the units in which the named symbols are declared. Add those units, those that declare TQExport4 and TQExportRow, to the uses clause of your Unit1.
It's usually worth consulting the documentation when you encounter a compiler error that you do not understand. Search for the error code, for example E2003. The documentation says:
The compiler could not find the given identifier - most likely it has been misspelled either at the point of declaration or the point of use. It might be from another unit that has not mentioned a uses clause.
The final sentence covers your scenario, although the author got in a tangle when writing that text and the words don't make a lot of sense. Sigh.
Incidentally, the example at the bottom of that documentation page made me sad. The author indicates a preference, when correcting mis-named variables, for the option requiring the fewest key strokes. Never mind getting the name right, just make it compile with the fewest key strokes and who cares about the next person to read the code. Pah!

delphi E2003 undeclared identifier 'self'

I need a bit of help; I'm helping a friend port a Delphi app built years back to newer versions of Windows, as it currently only runs on Windows 95.
The code utilises 3rd party libraries from Woll2Woll for DB operations.
One of these libraries generates the error E2003 Undeclared identifier: 'self'.
I've been through a number of sites via Google and with my limited knowledge of Delphi (stemming from my Pascal training about 12 years ago and extrapolating my slightly rusted PHP, BASH, ColdFusion and ASP coding skills), I've run into a brick wall - I'm strapped for time and can't make sense of the info I'm coming across on the web.
The problematic code segment is from the wwwQuery.pas file and looks like this:
{$ifdef wwDelphi3Up}
procedure TwwQuery.OpenCursor(InfoQuery: Boolean);
{$else}
procedure TwwQuery.OpenCursor;
{$endif}
begin
{$ifdef wwDelphi3Up}
inherited OpenCursor(InfoQuery);
{$else}
inherited OpenCursor;
{$endif}
//Modded by Arie
//wwSaveAnswerTable(self, Handle, FAnswerTable);
wwSaveAnswerTable(self, Handle, 'FAnswerTable');
end;
The precise error messages are:
[DCC Error] wwQuery.pas(243): E2003 Undeclared identifier: 'self'
[DCC Error] wwQuery.pas(244): E2029 '.' expected but ';' found
[DCC Fatal Error] wwcommon.pas(285): F2063 Could not compile used unit 'wwQuery.pas'
Line 243 is the 2nd last line, just above the end;
The wwSaveAnswerTable function looks like this:
Function wwSaveAnswerTable(ADataSet: TDBDataSet; AHandle: HDbiCur; tableName: string): boolean;
What must I change the Self parameter to, to stop the compile error?
Thanks a stack.
The problem is related to compiler define wwDelphi3Up or any related up in code.
As you see next error message: [DCC Error] wwQuery.pas(244): E2029 '.' expected but ';' found
Compiler expects end of program, and line wwSaveAnswerTable(self, Handle, 'FAnswerTable'); are not compiled inside OpenCursor method. That's why Self is not defined.
You don't need to change parameter, because for sure will affect functionality.
Try to compile it without defines, if you are not use an ancient version of Delphi:
procedure TwwQuery.OpenCursor(InfoQuery: Boolean);
begin
inherited OpenCursor(InfoQuery);
wwSaveAnswerTable(self, Handle, 'FAnswerTable'); // Here prob FAnswerTable without quotes
end;

Dynamical assignment of values in Delphi

I am creating a control similar to object inspector , So i want to assign any changes to the property to the relevant object.
var
v:TValue ;
ctx : TRttiContext;
begin
// k.IsOrdinal := true ;
v := v.FromVariant(2) ;
ctx.GetType(tButton).GetProperty('Style').SetValue(Button1, v.AsOrdinal);
end;
above is my code , but i am getting invalid type cast error.
Is it possible to handle any variable and enums .(No need of objects and records as it is very complicated )
The call to SetValue needs to read like this:
SetValue(Button1, TValue.From(TButton.TButtonStyle(2)))
In your code, the use of AsOrdinal is incorrect. That is a function that returns a TRttiOrdinalType. But TRttiOrdinalType is described thus:
TRttiOrdinalType is the class used to describe all the Delphi ordinal value types, such as Integer, Byte, Word, and so on.
But you need to provide a TValue that represents a TButtonStyle, which is what the code above achieves.
As an aside, I initially tried to use the generic TValue.From<T>() function like this:
SetValue(Button1, TValue.From<TButton.TButtonStyle>(TButton.TButtonStyle(2)));
But that just resulted in the following internal compiler error:
[DCC Fatal Error] Unit58.pas(38): F2084 Internal Error: URW1147
QC#103129
Every time I attempt to use generics I end up being defeated by these internal errors!
Thanks to Serg for pointing out the alternative form of calling the parameterised method using type inference does not fall foul of the internal error.

Resources