Pertanyaan Mengapa saya mendapatkan kesalahan "jenis yang tidak kompatibel" meskipun saya telah membuat definisi rekaman tersedia untuk semua unit?


Saya menulis aplikasi Delphi 2010. Ini memiliki banyak file, dua di antaranya disebut Utils_ABS dan Utils_MAT. Saya telah membuat jenis catatan yang harus dipahami oleh kedua file, jadi saya taruh dalam file sendiri, yang disebut TypeDefs.inc.

Di bagian atas Utils_MAT dan Utils_ABS, saya telah memasukkan INFUDED TypeDefs.inc.

unit Utils_ABS;

interface

{$WARNINGS ON}
{$HINTS ON}
{$WARN UNIT_PLATFORM OFF}
{$WARN SYMBOL_PLATFORM OFF}

uses
Windows, Messages, ... Utils, Analysis, UserFeedback, Utils_MAT;

{$I TypeDefs.inc}     // Include TypeDefs that are used multiple places

procedure ABS_Load;
...

Utils_MAT terlihat sangat mirip, terutama yang terkait {$I TypeDefs.inc}.

Kuncinya adalah bahwa kedua file mereferensikan file ketiga, TypeDefs.inc, sebagai INCLUDE, yang memiliki definisi RECORD:

type
TTableAttrType = Record
tabIOT: Boolean; // Is table an IOT
...
end;

Tidak ada yang lain selain definisi rekaman yang satu ini dalam file ini.

Masalahnya adalah ketika saya mengkompilasi, saya mendapatkan kesalahan berikut:

[DCC Error] Utils_ABS.pas (212): E2010 Jenis yang tidak kompatibel: 'Utils_ABS.TTableAttrType' dan 'Utils_MAT.TTableAttrType'

Saya benar-benar bingung. Bagaimana mereka bisa menjadi tipe yang tidak kompatibel jika mereka berasal dari definisi yang sama? Bukan salinan definisi, tetapi secara harfiah definisi yang sama.

Saya telah memeriksa semua kode sumber saya, dan catatan TTableAttrType ini tidak ditentukan di tempat lain.

Saya telah mencoba untuk mengomentari $ INCLUDE, dan hard-code definisi dari rekaman ke dalam Utils_ABS dan Utils_MAT, tetapi saya masih mendapatkan kesalahan yang sama.

Bagaimana saya mendapatkan kesalahan ini untuk pergi? Bagaimana cara menetapkan struktur catatan di satu tempat, dan memiliki beberapa file mengaksesnya?


5
2017-10-23 00:15


asal


Jawaban:


Dengan memasukkan definisi seperti ini, Anda mendefinisikan tipe di kedua unit. Karena Pascal (dan dengan ekstensi Delphi) menggunakan a sistem tipe nominatif, bukan sistem tipe struktural, kedua jenis tidak sama - mereka memiliki nama yang berbeda, seperti yang ditunjukkan pada pesan kesalahan.

Masukkan definisi TTableAttrType dalam unit terpisah, dan buang unit baru itu ke dalam klausa penggunaan bagian antarmuka di dua unit lainnya. Maka jenisnya hanya akan ditentukan sekali, dan Anda tidak akan lagi memiliki jenis yang tidak kompatibel.


11
2017-10-23 00:24



Meskipun penjelasan Michael benar, ada beberapa hal penting yang harus ditambahkan pada jawaban ini.

Meski terlihat mirip {$INCLUDE ...} direktif dan Uses klausa bekerja sama sekali berbeda. {$INCLUDE} mengimpor sumber (seperti dalam, membaca dari dan kemudian menempel ke) dari unit yang ditentukan ke unit pemanggil sedangkan Uses klausa mengkompilasi unit yang ditentukan dan kemudian menggunakan biner yang dikompilasi (dcu). Jadi, ketika Anda menggunakan {$ INCLUDE}, Anda sebenarnya tidak berbagi hal yang sama tetapi menduplikasinya. Tidak masalah nama dan struktur mereka sama, mereka entitas yang sama sekali berbeda dengan kompilator. Saat menggunakan objek yang dikompilasi di sisi lain, Anda mengacu pada entitas bersama yang sama.


0
2017-10-24 19:40