Bisakah pointer ke tipe tidak lengkap tidak lengkap?

9

Bisakah int (*)[]tipe yang tidak lengkap?

C 2018 6.2.5 1 mengatakan:

Pada berbagai titik dalam unit terjemahan, suatu jenis objek mungkin tidak lengkap (kurang informasi yang cukup untuk menentukan ukuran objek jenis itu) atau lengkap (memiliki informasi yang cukup).

Jadi tampaknya jika ukuran suatu jenis diketahui, jenisnya lengkap. 6.2.6.1 28 menetapkan bahwa jenis pointer tertentu harus memiliki ukuran yang sama (pointer ke voiddan karakter, pointer ke jenis yang kompatibel, pointer ke struktur, dan pointer ke serikat pekerja), tetapi pointer ke jenis lain dapat bervariasi.

Dalam implementasi C di mana semua pointer, atau semua pointer ke array int, memiliki ukuran yang sama, maka ukuran int (*)[]diketahui, sehingga akan lengkap. Dalam implementasi yang, katakanlah, menggunakan pointer berbeda untuk array besar, ukurannya tidak akan diketahui, sehingga tidak lengkap.

Seperti yang ditunjukkan MM , struktur tidak boleh mengandung anggota dengan tipe tidak lengkap, kecuali anggota array fleksibel akhir, per kendala dalam 6.7.2.1 3. Ini menunjukkan bahwa implementasi dengan satu ukuran pointer harus menerima struct { int (*p)[]; }sementara implementasi yang memiliki perbedaan ukuran untuk array tersebut harus mendiagnosis pelanggaran kendala. (Ini pada gilirannya berarti pernyataan semacam itu bukan bagian dari kepatuhan ketat C.)

Eric Postpischil
sumber
6.2.5 (hal 22) membantu? (Atau apakah itu menambah lebih banyak kebingungan yang memungkinkan jenis yang tidak lengkap untuk diselesaikan oleh deklarasi nanti?)
David C. Rankin
@ DavidC.Rankin Dalam 6.2.5 / 20 bahkan dikatakan bahwa pointer selalu merupakan tipe yang lengkap
Christophe
@LanguageLawyer: Bagaimana itu relevan? Pertanyaannya adalah "Apakah ada X yang bukan Y?", Bukan "Apakah ada X yang merupakan Y?"
Eric Postpischil
@LanguageLawyer: Fakta yang void *lengkap menunjukkan bahwa pointer ke tipe yang tidak lengkap bisa lengkap. Itu tidak menunjukkan apakah pointer ke tipe tidak lengkap bisa tidak lengkap. Jika seseorang bertanya "Bisakah mamalia menjadi gajah?", Menunjukkan bahwa "Singa adalah mamalia" tidak akan menyatakan bahwa mamalia tidak bisa menjadi gajah. Pertanyaan bertanya apakah set X dari pointer ke tipe tidak lengkap dapat mengandung elemen yang tidak lengkap. Menunjukkan bahwa set X pointer ke tipe tidak lengkap berisi elemen yang lengkap tidak relevan.
Eric Postpischil
@EricPostpischil Ups. Saya salah membaca judul sebagai "Bisakah penunjuk ke tipe yang tidak lengkap selesai ?"
Pengacara Bahasa

Jawaban:

3

Array dengan ukuran yang tidak diketahui tidak lengkap:

Tipe array dengan ukuran yang tidak diketahui adalah tipe yang tidak lengkap. Itu selesai, untuk pengidentifikasi jenis itu, dengan menentukan ukuran dalam deklarasi selanjutnya (dengan tautan internal atau eksternal)

int (*)[]Namun tipe ini tidak lengkap: Ini adalah pointer dari array dengan intukuran yang tidak diketahui.
Dan sebuah pointer memiliki ukuran yang terkenal:

printf ("Size %d\n", sizeof(int (*)[]));

6.2.5 / 23: Suatu tipe telah mengetahui ukuran konstan jika tipe tersebut tidak lengkap dan bukan tipe array panjang variabel.

Lebih lanjut Anda bahkan dapat melakukan dereferensi, berkat semantik array:

typedef int (*T)[];
...
int a[10];
for (int i=0; i<10; i++) a[i]=i;
T p=a;
for (int i=0; i<10; i++) printf ("%d ",(*p)[i]);
printf ("\n");

Edit

Selain itu, pointer selalu merupakan tipe yang lengkap. Ditulis hitam putih di 6.2.5 / 20:

Tipe pointer dapat diturunkan dari tipe fungsi atau tipe objek, yang disebut tipe referensi. Tipe pointer menggambarkan objek yang nilainya menyediakan referensi ke entitas dari tipe yang direferensikan. Tipe penunjuk yang berasal dari tipe T yang dirujuk kadang-kadang disebut '' penunjuk ke T ''. Konstruksi tipe pointer dari tipe referensi disebut '' derivasi tipe pointer ''. Tipe pointer adalah tipe objek yang lengkap.

Christophe
sumber
Saya pikir Anda memilikinya rebus dan gcc setuju. struct w / pointer ke array tidak lengkap mirip dengan pertanyaan awal yang mendorong diskusi.
David C. Rankin
Hanya paragraf terakhir yang relevan. Contoh printfhanya menunjukkan bahwa pointer ke array yang tidak lengkap selesai dalam implementasi yang dieksekusi, seperti yang dinyatakan dalam pertanyaan — jika bukan karena 6.2.5 20, dikutip dalam paragraf terakhir, mungkin gagal untuk dikompilasi. 6.2.5 23 juga tidak relevan; itu memberi tahu kita ukuran diketahui dan konstan jika lengkap, dan kita sudah tahu bahwa lengkap berarti ukuran diketahui.
Eric Postpischil
6.2.5 20 menarik. Saya berspekulasi itu tidak dimaksudkan untuk memiliki konsekuensi ini, tetapi itu berarti bahwa semua petunjuk untuk melengkapi tipe yang memiliki tipe yang sama ketika tidak lengkap harus memiliki ukuran yang sama. Sebagai contoh, semua pointer ke array intharus memiliki ukuran yang sama satu sama lain, dan semua pointer ke array structharus memiliki ukuran yang sama satu sama lain, walaupun mungkin tidak semua pointer ke array dari berbagai jenis structharus memiliki ukuran yang sama satu sama lain.
Eric Postpischil
1
@EricPostpischil mungkin teks "Demikian pula, pointer ke versi yang memenuhi syarat atau tidak memenuhi syarat dari jenis yang kompatibel akan memiliki persyaratan representasi dan perataan yang sama." harus ditafsirkan untuk mengatakan bahwa T(*)[]harus memiliki ukuran yang sama dengan T(*)[5], karena mereka adalah tipe yang kompatibel dan kami dapat menambah atau menghapus kualifikasi
MM
Mengizinkan jenis yang kompatibel memiliki ukuran yang berbeda akan menyebabkan sejumlah masalah, mungkin cacat bahwa standar tidak secara eksplisit mengesampingkannya
MM