private type declaration is throwing error? - constants

private type declaration is throwing error?my code is below please help me to fix it
error is=> "missing full declaration of private type t"
spec file
package rec is
type t is private;
give_public_acess:Constant t;
private
type int_array is array(1..5)of integer;
type t_type is record
max:integer:=0;
data:int_array;
end record;
give_public_acess:constant t_type:=(0,(others=>1)); --error is here adacore site says these is good but throwing error?
end rec;

When I compile your code I get 2 error messages:
rec.ads:2:07: missing full declaration for private type "t"
rec.ads:10:03: type does not match declaration at line 3
These are both because you call the type t in the public part and t_type in the private part. The first means exactly what it says; the second is because in the public part you say
give_public_acess:Constant t;
and in the private part
give_public_acess:constant t_type
I suggest you try compiling with -gnatl (full listing): this intersperses error messages with the code, so you get
1. package rec is
2. type t is private;
|
>>> missing full declaration for private type "t"
3. give_public_acess:Constant t;
4. private
5. type int_array is array(1..5)of integer;
6. type t_type is record
7. max:integer:=0;
8. data:int_array;
9. end record;
10. give_public_acess:constant t_type:=(0,(others=>1)); --error is here adacore site says these is good but throwing error?
|
>>> type does not match declaration at line 3
11. end rec;

Related

'GetCalcFields' not found in base class Error

type
TCDSWithRecalc = class(TClientDataset)
public
procedure GetCalcFields(Buffer: PChar); override;
end;
procedure TCDSWithRecalc.GetCalcFields(Buffer :PChar);
begin
inherited GetCalcFields(Buffer);
end;
E2137 Method 'GetCalcFields' not found in base class.
I don't understand what this error is. can you help?
You don't say which Delphi version you are using, but the type declaration of the Buffer parameter was changed from the original (D7 and before) PChar to TRecBuf in the modern (Unicode) versions. So, you you need to change your declaration of TCDSWithRecalc
to
type
TCDSWithRecalc = class(TCustomClientDataset)
public
procedure GetCalcFields(Buffer: TRecBuf); override;
end;
[...]
procedure TCDSWithRecalc.GetCalcFields(Buffer : TRecBuf);
begin
inherited GetCalcFields(Buffer);
end;
In Delphi 10.4.2, the compiler reports an additional error with your version of the declaration
[dcc32 Error] cds1u.pas(41): E2250 There is no overloaded version of 'GetCalcFields' that can be called with these arguments
which is true.

Is it possible to use a class declared in Implementation section from Interface section

If I understand correctly, the interface section is visible to other units, and the implementation section is visible only in the current .pas file.
I have two classes, class TA should be visible to the outside, other class TB should not, but I need a field of type TB in TA.
interface
type
TA = class
//something
B : TB;
end;
//something
implementation
type
TB = class
//something
end;
It doesn't work like that. I also cannot use a forward declaration. Is there a way?
Or, is there a way to declare TB in the interface section but make it kind-of private?
A type cannot be used before it is declared (in terms of line numbers). In particular, this means that you cannot use a type declared in the implementation section in the interface section.
However, consider the following example:
unit VisibilityTest;
interface
type
TFrog = class
strict private type
TFrogMetabolism = class
procedure DoAnabolismStuff;
procedure DoCatabolismStuff;
end;
strict private
FMetabolism: TFrogMetabolism;
public
procedure Croak;
procedure Walk;
procedure Jump;
end;
implementation
{ TFrog.TFrogMetabolism }
procedure TFrog.TFrogMetabolism.DoAnabolismStuff;
begin
end;
procedure TFrog.TFrogMetabolism.DoCatabolismStuff;
begin
end;
{ TFrog }
procedure TFrog.Jump;
begin
end;
procedure TFrog.Croak;
begin
end;
procedure TFrog.Walk;
begin
end;
end.
Here the TFrog class is visible to other units, as well as its Croak, Walk, and Jump methods.
And it does have a (strict private in this example) field of type TFrogMetabolism, a type which can only be used inside TFrog -- and therefore only inside this unit -- because of the preceding strict private specification.
This should give you some ideas. A few variants are possible:
If you remove strict from strict private type, the TFrogMetabolism class can be used everywhere inside this particular unit, and not only in TFrog.
If you replace private with protected, the class can also be used in classes that aren't TFrog but are derived from TFrog.
You can do it but with a price. In class TA, the variable referring to TB must be of type TObject. Let's name that variable B. You can assign an instance of class TB to the variable, for example from the constructor. Then when code in TA needs to use variable B, it must cast is to TB (Hard cast or use "As" operator).
You should also disable RTTI on that TB so that the outside cannot discover what is inside TB.
Here is the code:
unit Unit24;
interface
uses
System.SysUtils;
type
TA = class
B : TObject; // Will contain a TB instance
constructor Create;
destructor Destroy; override;
procedure Demo;
end;
implementation
type
TB = class
procedure SayHello;
end;
{ TA }
constructor TA.Create;
begin
inherited Create;
B := TB.Create;
end;
procedure TA.Demo;
begin
TB(B).SayHello;
end;
destructor TA.Destroy;
begin
FreeAndNil(B);
inherited Destroy;
end;
{ TB }
procedure TB.SayHello;
begin
WriteLn('Hello!');
end;
end.
An example of use:
program Project24;
{$APPTYPE CONSOLE}
{$R *.res}
uses
System.SysUtils,
Unit24 in 'Unit24.pas';
var
A : TA;
begin
A := TA.Create;
try
A.Demo;
finally
A.Free;
end;
end.
One option might be to declare a public interface that TB implements, and then TA can have a field of that interface type.
interface
type
IB = interface
//something
end;
TA = class
public
B : IB;
constructor Create;
end;
//something
implementation
type
TB = class(TInterfacedObject, IB)
//something
end;
constructor TA.Create;
begin
B := TB.Create;
end;
Is it possible to use a class declared in Implementation section from Interface section?
No.
Or is there a way to declare TB in the Interface section but make it kinda private?
Yes,, if you make it a nested class, declare in a private section of the containing type.
A pointer and class can be declared forward, but must be declared in the same type block. The reason that this works is because they are reference types and even just the forward declaration fixates the offset of the fields after them. The type block bit is mainly compiler writer convenience (but as so often, also easier/better error message generation)
Pascal follow-up Modula2 allowed pointers to be more narrowly defined in the implementation, e.g. a pointer to a certain record(so called opaque types). Other units could only use it as a handle type (pass it along etc) and the implementation could access details without typecasts. In that way it is a language assisted way of doing what Fpiette suggests, tobject being the most basic subset of a class.
Another solution would be to make it a generic, and specialize it in the implementation with the generic TB type.

Ada Access to parameterless procedure "wrong convention"

I have the following binding:
function atexit(proc : access Procedure) return Integer with
Import, Convention => C;
As well as the procedure:
procedure Exiting is
begin
Put_Line("Exiting");
end Exiting;
When I try to call it like:
I : Integer := atexit(Exiting'Access);
it fails with subprogram "Exited" has wrong convention
however providing my own (incompatable) atexit which accepts a parameter, and modifying Exiting to use that same parameter, allows passing the procedure just fine.
So it seems like the issue is passing a parameterless procedure as an access type.
I've tried giving a named access type like
type Procedure_Access is access Procedure;
But the result is exactly the same.
How can I pass a parameterless procedure then?
You might have forgotten the Convention aspects in the declarations of Exiting and Procedure_Access. The following works in GNAT CE 2018:
foo.c
int _atexit(void (*f)(void))
{
(*f)();
return 0;
}
main.adb
with Ada.Text_IO; use Ada.Text_IO;
with Interfaces.C; use Interfaces.C;
procedure Main is
type proc_ptr is access procedure
with Convention => C;
function atexit(proc : proc_ptr) return int
with Import, Convention => C, Link_Name => "_atexit";
procedure Exiting
with Convention => C;
procedure Exiting is
begin
Put_Line("Exiting");
end Exiting;
I : Integer := Integer (atexit (Exiting'Access));
begin
Put_Line("atexit returned " & I'Image);
end Main;
default.gpr
project Default is
for Source_Dirs use ("src");
for Object_Dir use "obj";
for Main use ("main.adb");
for Languages use ("Ada", "C");
end Default;
output
Exiting
atexit returned 0

Unknown error on VDM++ toolbox lite

I'm doing VDM++ on VDM++ toolbox lite and below is my example code:
class Course
types
public study :: numsubj : nat1
sem : nat1;
public subjpersem = nat1;
operations
public getsubj:nat1 * nat1 ==>study
getsubj(numsubj,sem) == (
subjpersem := numsubj/sem;
);
end Course
I tried to run the code. Succeeded creating the object but when I run print getsubj(10,2), it returns error Run-Time Error 120: Unknown state component
Can somebody help me thank you in advance
In Overture/VDMJ, this spec gives two type checking errors. Do these not appear in VDMTools?
Error 3247: Symbol 'subjpersem' is not an updatable variable in 'Course' (test.vpp) at line 9:5
Error 3027: Operation returns unexpected type in 'Course' (test.vpp) at line 7:8
Actual: ()
Expected: study
Type checked 1 class in 0.119 secs. Found 2 type errors

How to rename an Ada constant defined in the private part

I want to rename a constant in the public part of a package (the original name is deprecated) that is defined in the private part. I tried this but GNAT says:
full constant declaration appears too late
package Sample is
type The_Type is private;
My_Constant : constant The_Type;
My_Renamed_Constant : The_Type;
private
type The_Type is ...;
My_Constant : constant The_Type := ...;
My_Renamed_Constant : The_Type renames My_Constant;
end Sample;
Is there a reason you want a rename instead of (say)
function My_Renamed_Constant return The_Type;
which simply returns My_Constant in the package body?
Functionally identical... and should inline if you're worried about speed.
Later in the deprecation process, make My_Renamed_Constant the constant and My_Constant the function instead. Then, when you think you're ready to retire it, have function My_Constant raise Program_Error or a custom exception indicating "using deprecated constant" to catch any usage you missed.
You probably don’t need to use a renaming; would this do? (this may depend on exactly what the full declaration of The_Type is in your case)
package Sample is
type The_Type is private;
My_Constant : constant The_Type;
My_Renamed_Constant : constant The_Type;
private
type The_Type is new Integer;
My_Constant : constant The_Type := 42;
My_Renamed_Constant : constant The_Type := My_Constant;
end Sample;