You’re trying to access it as an array index, but it needs to be a function call:
MyChar.clas := classes(i); { note () instead of [] }
You should probably add some range checking, too. What happens if someone puts 20
in the text file? Your array only has items at indexes 1
through 7
, so you’ll get a runtime error when you call classes(20)
with the out of range value.
(You could probably use a constant array for allclasses
to lessen your code as well, but your instructor probably haven’t gotten that far yet.)
Given your comment about not having an instructor, here’s a suggestion about a better way to handle the function:
function classes(o:integer): String;
const
allclasses: array[1..7] of string = ('class1',
'class2',
'class3',
'class4',
'class5',
'class6',
'class7');
begin
{
Low() returns the lowest index of the array, and
High() returns the highest. The if statement makes sure
that o is between them. It is the range check I mentioned.
}
if (o >= Low(allclasses)) and (o <= High(allclasses)) then
classes := allclasses[o]
else
classes := '';
end;
Topic: Illegal Qualifier (Read 4199 times)
My compile terminates with 8 errors «Error: Illegal qualifier».
I’ve googled etc and so I have an idea of the kind of things I might be looking for. But the compiler doesn’t give me any location, not even a unit.
Is there anything I can do to get the compiler give me a location?
Logged
It means some name conflict in a path, i.e. some unit in your uses contain identifiers with the same name.
-
unit Unit1;
-
{$mode objfpc}{$H+}
-
interface
-
uses
-
Classes, SysUtils, Forms, Controls, Graphics, Dialogs;
-
type
-
{ TForm1 }
-
TForm1 = class(TForm)
-
procedure FormCreate(Sender: TObject);
-
private
-
public
-
end;
-
var
-
Form1: TForm1;
-
Tag: TPoint;
-
implementation
-
{$R *.lfm}
-
{ TForm1 }
-
procedure TForm1.FormCreate(Sender: TObject);
-
begin
-
Tag.X:=4;
-
end;
-
end.
This code gives «Illegal Qualifier» error because Tag is also property of TForm. It is sibling error to «Duplicate identifier».
Logged
It’d be amazing for the cmopiler to give me a name or a location. I mean, I have some 150k lines of code to look through…
Logged
So it turns out that this is caused by a property declaration like this:
-
property system : String read X write X;
Logged
system is reserved — for the hidden system unit — so can’t be used as a global property.
Logged
I actually get compliments for being rude… (well, Dutch, but that is the same)
So it turns out that this is caused by a property declaration like this:
property system : String read X write X;
You didn’t get a line number along with the error message ?… if that is the case, it’s probably worth reporting as a bug.
Logged
FPC v3.0.4 and Lazarus 1.8.2 on Windows 7 SP1 64bit.
Trying to verify my idea that the line number is not displayed because your compiler settings might not create debug information I tried this project:
-
program Project1;
-
uses
-
Classes;
-
type
-
TSystemClass = class
-
private
-
x: string;
-
public
-
property System: String read x write x;
-
end;
-
var
-
sc: TSystemClass;
-
begin
-
sc := TSystemClass.Create;
-
try
-
sc.System := ‘abc’;
-
WriteLn(sc.System);
-
finally
-
sc.Free;
-
end;
-
ReadLn;
-
end.
And it compiles and runs flawlessly… So, what exactly are you doing? Please present compilable code, no snippets.
Logged
Yes, I know, but what won’t work is a global property declaration. And FPC supports global properties.
Logged
I actually get compliments for being rude… (well, Dutch, but that is the same)
Well, this doesn’t compile:
-
unit Unit1;
-
interface
-
type
-
TSystemClass = class
-
private
-
function getX: string; virtual; abstract;
-
procedure setX(value: string); virtual; abstract;
-
public
-
property system: String read getX write setX;
-
end;
-
implementation
-
end.
and
-
program project1;
-
uses
-
Classes, Unit1;
-
begin
-
end.
It seems be both the property name and the virtual abstract accessors
Logged
Well, this doesn’t compile:
Don’t use System as the property name.
Logged
> Don’t use System as the property name.
Well, that might be — painful, especially since it’s supported in delphi. But what was really painful was the lack of information about what the problem was
Logged
> Don’t use System as the property name.
Well, that might be — painful, especially since it’s supported in delphi. But what was really painful was the lack of information about what the problem was
Have you tried prepending the name with a % or & , I forgot which one it is ?
That allows you to use reserved words.
Logged
The only true wisdom is knowing you know nothing
Well, this doesn’t compile:
unit Unit1;
interface
type
TSystemClass = class
private
function getX: string; virtual; abstract;
procedure setX(value: string); virtual; abstract;
public
property system: String read getX write setX;
end;
implementation
end.
and
program project1;
uses
Classes, Unit1;
begin
end.
It seems be both the property name and the virtual abstract accessors
Please report this as a bug. In this example the identifer
System
is part of the
TSystemClass
type, so it’s namespaced, thus this should work. And at least the compiler should properly show the error location.
Logged
-
program Project1;
-
//{$mode Delphi}
-
{$mode objfpc}
-
uses
-
Classes;
-
type
-
TSystemClass = class
-
private
-
x: string;
-
function GetX: String; virtual; abstract;
-
procedure SetX(value: String); virtual; abstract;
-
public
-
property System: String read GetX write SetX;
-
end;
-
begin
-
end.
The main question was: Why are there no messages about error locations? The above minimal code behaves exactly as reported in the first post, no matter whether mode Delphi or ObjFPC is selected: The error message is useless:
Compile Project, Target: D:\Prog_Lazarus\lazarus_test_projects\project1.exe: Exit code 1, Errors: 2
Error: Illegal qualifier
Error: Illegal qualifier
So, I agree with PascalDragon and recommend reporting this as a bug to Mantis.
Logged
Misses «uses Classes».
Please post attachments within the forum as much as possible (paste from the clipboard and enclose in [
quote
] … [
/quote
] tags, or upload compilable, zipped projects under «Attachment and other options» below the edit box). Otherwise they will be removed sooner or later from external sites, and your post will become meaningless to others finding it at some time in the future.
Logged
function classes(o:integer): String;
var allclasses : array[1..7] of String;
begin
allclasses[1]:= 'class1';
allclasses[2]:= 'class2';
allclasses[3]:= 'class3';
allclasses[4]:= 'class4';
allclasses[5]:= 'class5';
allclasses[6]:= 'class6';
allclasses[7]:= 'class7';
classes := allclasses[o];
end;
Above you can see a function, which should receive an integer and give a result of string that was stored in array.
procedure loadthis(chosen : string);
var f: text;
i : integer;
begin
Assign(f, 'files\'+chosen+'.txt');
Reset(f);
ReadLn(f, i);
MyChar.clas := classes[i];
end;
When this procedure is called, it calls a «classes» function. Pleae note that Mychar ir a global variable.
begin
loadthis(FileName);
ReadLn;
Readln
end.
Ant this is the main program, which calls «loadthis» procedure.
I Have no idea whats wrong, but I am getting these errors:
- Wrong amount of parameters specified
- Illegal qualifier
Both errors come from this line:
MyChar.clas := classes[i];
. I have really no idea what is wrong, maybe I can not call a function from a procedure ? Please help.
type metk=(a,b); st=record mark:string; fio:string; nomr:string; otm:metk; end; mas=array [1..10] of st; fail=file of st; procedure zap(var tabl:mas;var n:integer;var f:fail); var i:integer; c:char; begin repeat write('Количество записей не более 10 n='); readln(n); until n in [1..10]; writeln('Введите данные:'); for i:=1 to n do begin writeln('Запись ',i); write('marka=');readln(tabl[i].mark); write('fio=');readln(tabl [i].fio); write('nomer=');readln(tabl [i].nomr); write('otmetka(y/n)=');readln(c); case c of 'y':tabl[i].otm:=a; 'n':tabl[i].otm:=b; end; write(f,tabl[i]); end; end; var n,i:integer; tabl:mas; f:fail; begin assign(f,'C:\text.txt'); rewrite(f); Zap(tabl,n,f); close(f); reset(f); write('end'); end.
-
arrays
-
function
-
procedure
-
pascal
|
Question
function classes(o:integer): String;
var allclasses : array[1..7] of String;
begin
allclasses[1]:= 'class1';
allclasses[2]:= 'class2';
allclasses[3]:= 'class3';
allclasses[4]:= 'class4';
allclasses[5]:= 'class5';
allclasses[6]:= 'class6';
allclasses[7]:= 'class7';
classes := allclasses[o];
end;
Above you can see a function, which should receive an integer and give a result of string that was stored in array.
procedure loadthis(chosen : string);
var f: text;
i : integer;
begin
Assign(f, 'files\'+chosen+'.txt');
Reset(f);
ReadLn(f, i);
MyChar.clas := classes[i];
end;
When this procedure is called, it calls a «classes» function. Pleae note that Mychar ir a global variable.
begin
loadthis(FileName);
ReadLn;
Readln
end.
Ant this is the main program, which calls «loadthis» procedure.
I Have no idea whats wrong, but I am getting these errors:
- Wrong amount of parameters specified
- Illegal qualifier
Both errors come from this line:
MyChar.clas := classes[i];
. I have really no idea what is wrong, maybe I can not call a function from a procedure ? Please help.
Solution
You’re trying to access it as an array index, but it needs to be a function call:
MyChar.clas := classes(i); { note () instead of [] }
You should probably add some range checking, too. What happens if someone puts 20
in the text file? Your array only has items at indexes 1
through 7
, so you’ll get a runtime error when you call classes(20)
with the out of range value.
(You could probably use a constant array for allclasses
to lessen your code as well, but your instructor probably haven’t gotten that far yet.)
Given your comment about not having an instructor, here’s a suggestion about a better way to handle the function:
function classes(o:integer): String;
const
allclasses: array[1..7] of string = ('class1',
'class2',
'class3',
'class4',
'class5',
'class6',
'class7');
begin
{
Low() returns the lowest index of the array, and
High() returns the highest. The if statement makes sure
that o is between them. It is the range check I mentioned.
}
if (o >= Low(allclasses)) and (o <= High(allclasses)) then
classes := allclasses[o]
else
classes := '';
end;