Why does the compiler say the implementation "differs from the previous declaration" when they look identical?
Asked Answered
P

3

5

i have two units, first one, my interface:

use personas

interface

type
  Tllave = array[0..31] of byte;
  Tdatos = array of byte;

  ImyInterface = interface(IInterface)

    function nombre : string;
    function edad : integer;
    procedure resetear;
    function Proceso(datos : tdatos; cantidad : integer) : integer ;    
    procedure Iniciar(llave : Tllave);
  end;

second unit, my object declaration:

use militares

interface

uses personas;

type

  Tmilitares = Class(TInterfacedObject, ImyInterface )
    public
      function nombre : string;
      function edad : integer;
      procedure resetear;
      function Proceso(datos : Tdatos; cantidad : integer) : integer ;    
      procedure Iniciar(llave : Tllave);
    published
      constructor create;
  end;

implementation

function tmilitares.Proceso(datos : tdatos; cantidad : integer) : integer ; // getting error !!
begin
  // ....
end;


procedure tmilitares.Iniciar(llave : Tllave); // getting error!!
begin
  // ....
end;

I get a error message only in 'proceso' function and 'iniciar' procedure:

declaration of 'Iniciar' differs from previous declaration
declaration of 'Proceso' differs from previous declaration.

I noticed that they've array parameter. The parameter's type are defined in the first unit, if i define these types in the second units i get the same error but it's showed in the declaration of the object. how can i compile?

Protozoal answered 24/5, 2011 at 20:58 Comment(3)
you aren't showing us enough detail. There's something else that is causing these errors.Coed
in the both snippets at line #1 there must be uses, not useFrenchman
no those lines should say unitCoed
C
10

You aren't showing enough code but clearly what is happening is that you are redefining the offending types (Tdatos and Tllave) between the declaration of Tmilitares in the interface section and the implementation of the methods. This redeclaration is either in the form of another unit that you use, or in the implementation section of the militares unit.

Find those other declarations and you'll be able to solve your problem.


Your comment at the end of your question is telling:

If I define these types in the second unit, I get the same error but it's shown in the declaration of the class.

The fact that you tried to re-define the types indicates a problem of understanding. Types need to be declared once and once only. Once you define them twice you now have two distinct incompatible types. What's even worse, they have the same name! Define a type once and import it into other units via a uses statement.

Coed answered 24/5, 2011 at 21:15 Comment(1)
The key here is that if you define it in two places, you end up with two distinct types: unit1.Tdatos and unit2.Tdatos. You could specify the unit too to make it work, but defining once only is the best way.Handiness
B
0

The following works. There are no prior declarations, that don't match. I suspect you are declaring the iMyInterface.SomeProcedure (unit1 in my example) with parameters that are slightly different than what you showed in the class that implements the interface (unit2 in my example) section. Note that anything that implements ImyInterface must implement ALL of it.

Unit1:

unit Unit1;


interface

type   
  Tllave = array[0..31] of byte;  

  Tdatos = array of byte;

  ImyInterface = interface(IInterface)

    function nombre : string;
    function edad : integer;
    procedure resetear;
    function Proceso(datos : tdatos; cantidad : integer) : integer ;
    procedure Iniciar(llave : Tllave);   end;

implementation


  //stuff.

end.

Unit2:

unit Unit2;

interface

{$M+}

uses Unit1;

type

  Tmilitares = Class(TInterfacedObject, ImyInterface )
    public
      function nombre : string;
      function edad : integer;
      procedure resetear;
      function Proceso(datos : Tdatos; cantidad : integer) : integer ;    
      procedure Iniciar(llave : Tllave);
    published
      constructor create;
  end;

implementation


function Tmilitares.nombre: string;
begin

end;

function tmilitares.Proceso(datos : tdatos; cantidad : integer) : integer ; // no more error 
begin
  // ....
end;


constructor Tmilitares.create;
begin

end;

function Tmilitares.edad: integer;
begin

end;

procedure Tmilitares.resetear;
begin

end;

procedure tmilitares.Iniciar(llave : Tllave); // no more error.
begin
  // ....
end;

end.
Bronchial answered 24/5, 2011 at 21:47 Comment(0)
A
0

I'm adding this as an answer here because it is a very similar problem, but I just ran into this in a unit that looks like this :

unit Unit1;

interface
  uses Generics.Collections;

type
  TFoo = class
  end;

  TFooList = class(TObjectList<TFoo>)
    protected
      procedure Notify(const Item: TFoo; Action: TCollectionNotification); override;
  end;

implementation

uses Classes;

procedure TFooList.Notify(const Item: TFoo; Action: TCollectionNotification);
var
 sl : TStringList;
begin
  //
end;

end.

[dcc32 Error] Unit1.pas(20): E2037 Declaration of 'Notify' differs from previous declaration
[dcc32 Error] Unit1.pas(12): E2065 Unsatisfied forward or external declaration: 'TFooList.Notify' [dcc32 Fatal Error] Project1.dpr(6): F2063 Could not compile used unit 'Unit1.pas'

It took me longer than I'd like to admit to figure out that there is a

System.Classes :: TCollectionNotification = (cnAdded, cnExtracting, cnDeleting);

and a :

System.Generics.Collections :: TCollectionNotification = (cnAdded, cnRemoved, cnExtracted);

The lesson is to methodically check your types. Ctrl+CLICK on the type identifier will take you to the definition of the type the compiler is using. To fix it, either reorganize your uses clauses or use a fully qualified type name.

Bad enough when make the novice error of duplicating type names in our own code, doubly bad when Emba does it in their own RTL.

Actinozoan answered 11/3, 2016 at 14:55 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.