ตัวชี้ไปยังชนิดที่ไม่สมบูรณ์สามารถไม่สมบูรณ์ได้หรือไม่?


9

สามารถint (*)[]จะเป็นประเภทที่ไม่สมบูรณ์?

C 2018 6.2.5 1 พูดว่า:

ณ จุดต่าง ๆ ภายในหน่วยการแปลประเภทของวัตถุอาจไม่สมบูรณ์ (ขาดข้อมูลเพียงพอที่จะกำหนดขนาดของวัตถุประเภทนั้น) หรือสมบูรณ์ (มีข้อมูลเพียงพอ)

ดังนั้นจึงดูเหมือนว่าถ้าขนาดของประเภทเป็นที่รู้จักประเภทจะเสร็จสมบูรณ์ 6.2.6.1 28 ระบุว่าพอยน์เตอร์บางประเภทต้องมีขนาดเท่ากัน (พอยน์เตอร์voidและตัวอักษร, พอยน์เตอร์ไปยังประเภทที่เข้ากันได้, พอยน์เตอร์ไปยังโครงสร้างและพอยน์เตอร์เป็นสหภาพ) แต่พอยน์เตอร์

ในการนำ C ไปใช้งานที่ตัวชี้ทั้งหมดหรือตัวชี้ทั้งหมดไปยังอาร์เรย์intมีขนาดเท่ากันแล้วขนาดint (*)[]เป็นที่รู้จักดังนั้นจึงจะสมบูรณ์ ในการใช้งานที่กล่าวว่าใช้ตัวชี้ที่แตกต่างกันสำหรับอาร์เรย์ขนาดใหญ่ขนาดจะไม่เป็นที่รู้จักดังนั้นจึงไม่สมบูรณ์

เมื่อMM ชี้ให้เห็นโครงสร้างจะต้องไม่มีสมาชิกที่มีชนิดไม่สมบูรณ์ยกเว้นสมาชิกอาร์เรย์สุดท้ายที่ยืดหยุ่นตามข้อ จำกัด ใน 6.7.2.1 3. สิ่งนี้ชี้ให้เห็นว่าการนำไปปฏิบัติที่มีพอยน์เตอร์ขนาดเดียวต้องยอมรับstruct { int (*p)[]; }ในขณะที่การนำไปใช้ที่แตกต่างกัน ขนาดสำหรับอาร์เรย์ดังกล่าวจะต้องวินิจฉัยการละเมิดข้อ จำกัด (นี่หมายความว่าคำประกาศดังกล่าวไม่ได้เป็นส่วนหนึ่งของการปฏิบัติตามค. อย่างเคร่งครัด)


6.2.5 (p22) ช่วยไหม? (หรือเพิ่มความสับสนมากขึ้นหรือไม่ที่จะทำให้ประเภทที่ไม่สมบูรณ์สมบูรณ์โดยการประกาศในภายหลัง?)
David C. Rankin

@ DavidC.Rankin ใน 6.2.5 / 20 แม้จะมีการบอกว่าตัวชี้เป็นประเภทที่สมบูรณ์เสมอ
Christophe

@LanguageLawyer: นั่นจะมีความเกี่ยวข้องอย่างไร คำถามคือ“ มี X ที่ไม่ใช่ Y หรือไม่” ไม่ใช่“ มี X นั่นคือ Y หรือไม่”
Eric Postpischil

@LanguageLawyer: ความจริงที่void *สมบูรณ์แสดงให้เห็นว่าตัวชี้ไปยังประเภทที่ไม่สมบูรณ์สามารถเสร็จสมบูรณ์ มันไม่ได้แสดงว่าตัวชี้ไปยังประเภทที่ไม่สมบูรณ์นั้นอาจไม่สมบูรณ์หรือไม่ หากมีใครถามว่า "สัตว์เลี้ยงลูกด้วยนมสามารถเป็นช้างได้หรือไม่" แสดงให้เห็นว่า "สิงโตเป็นสัตว์เลี้ยงลูกด้วยนม" จะไม่ช่วยให้สัตว์เลี้ยงลูกด้วยนมไม่สามารถเป็นช้างได้ คำถามถามว่าชุดตัวชี้ X เป็นพอยน์เตอร์ที่ไม่สมบูรณ์อาจมีองค์ประกอบที่ไม่สมบูรณ์หรือไม่ การแสดงว่าชุด X ของพอยน์เตอร์เป็นประเภทที่ไม่สมบูรณ์มีองค์ประกอบที่สมบูรณ์นั้นไม่เกี่ยวข้อง
Eric Postpischil

@EricPostpischil โอ๊ะโอ ผมเคยอ่านผิดชื่อเป็น "ตัวชี้ไปยังประเภทไม่สมบูรณ์สามารถสมบูรณ์ ?"
นักกฎหมายด้านภาษา

คำตอบ:


3

อาร์เรย์ที่มีขนาดที่ไม่รู้จักไม่สมบูรณ์:

ประเภทอาร์เรย์ที่มีขนาดที่ไม่รู้จักเป็นประเภทที่ไม่สมบูรณ์ เสร็จสิ้นสำหรับตัวระบุชนิดนั้นโดยการระบุขนาดในการประกาศในภายหลัง (พร้อมการเชื่อมโยงภายในหรือภายนอก)

int (*)[]อย่างไรก็ตามประเภทนี้ไม่สมบูรณ์: เป็นตัวชี้ของintขนาดที่ไม่รู้จัก
และตัวชี้มีขนาดที่รู้จักกันดี:

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

6.2.5 / 23: ชนิดมีขนาดคงที่ที่รู้จักถ้าชนิดไม่สมบูรณ์และไม่ใช่ประเภทอาร์เรย์ความยาวผันแปร

นอกจากนี้คุณยังสามารถอ่านมันได้ด้วยความหมายของอาเรย์:

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");

แก้ไข

นอกจากนี้ตัวชี้จะเป็นประเภทที่สมบูรณ์เสมอ มันเขียนด้วยสีดำบนพื้นขาวใน 6.2.5 / 20:

ประเภทตัวชี้อาจได้มาจากประเภทฟังก์ชั่นหรือประเภทวัตถุที่เรียกว่าประเภทอ้างอิง ประเภทตัวชี้อธิบายวัตถุที่มีค่าให้การอ้างอิงไปยังเอนทิตีของประเภทอ้างอิง ชนิดตัวชี้ที่ได้มาจากชนิดที่อ้างอิง T บางครั้งเรียกว่า '' ตัวชี้ไปยัง T '' การสร้างประเภทตัวชี้จากประเภทที่อ้างอิงนั้นเรียกว่า '' pointer type pointer '' ประเภทตัวชี้เป็นประเภทวัตถุที่สมบูรณ์


ฉันคิดว่าคุณต้มแล้วและเห็นด้วย struct w / ตัวชี้ไปยังอาร์เรย์ที่ไม่สมบูรณ์นั้นคล้ายกับคำถามต้นฉบับที่พร้อมท์การอภิปราย
David C. Rankin

เฉพาะย่อหน้าสุดท้ายเท่านั้นที่เกี่ยวข้อง ตัวอย่างprintfแสดงให้เห็นว่าตัวชี้ไปยังอาเรย์ที่ไม่สมบูรณ์นั้นเสร็จสมบูรณ์ในการนำไปปฏิบัติที่ได้ดำเนินการตามที่ระบุไว้ในคำถาม - ถ้าไม่ใช่สำหรับ 6.2.5 20 ที่อ้างถึงในย่อหน้าสุดท้ายอาจไม่สามารถคอมไพล์ได้ 6.2.5 23 ก็ไม่เกี่ยวข้องเช่นกัน; มันบอกเราว่าขนาดเป็นที่รู้จักและคงที่ถ้ามันเสร็จสมบูรณ์แล้วและเรารู้อยู่แล้วว่าความสมบูรณ์หมายถึงขนาดที่เป็นที่รู้จัก
Eric Postpischil

6.2.5 20 น่าสนใจ ฉันคาดการณ์ว่าไม่ได้ตั้งใจที่จะให้ผลลัพธ์นี้ แต่หมายความว่าพอยน์เตอร์ทั้งหมดจะมีประเภทที่สมบูรณ์แบบที่มีประเภทเดียวกันเมื่อไม่สมบูรณ์ต้องมีขนาดเท่ากัน ตัวอย่างเช่นพอยน์เตอร์ทั้งหมดไปยังอาร์เรย์intต้องมีขนาดเท่ากันและพอยน์เตอร์ทั้งหมดไปยังอาร์เรย์ของบางขนาดstructต้องมีขนาดเท่ากันแม้ว่าอาจจะไม่ใช่พอยน์เตอร์ทั้งหมดไปยังอาร์เรย์ที่แตกต่างกันstructต้องมีขนาดเท่ากัน เหมือนกัน
Eric Postpischil

1
@EricPostpischil อาจเป็นข้อความ "ในทำนองเดียวกันตัวชี้ไปยังรุ่นที่เข้ากันได้หรือไม่ผ่านการรับรองของประเภทที่เข้ากันได้จะต้องมีข้อกำหนดการเป็นตัวแทนและการจัดตำแหน่งเดียวกัน" ควรตีความเพื่อบอกว่าT(*)[]ต้องมีขนาดเท่าT(*)[5]กันเนื่องจากเป็นประเภทที่ใช้งานร่วมกันได้และเราสามารถเพิ่มหรือลบตัวระบุ
MM

การอนุญาตให้ประเภทที่ใช้งานร่วมกันได้มีขนาดแตกต่างกันจะนำไปสู่ปัญหาที่เกิดขึ้นมากมายมันอาจจะเป็นข้อบกพร่องที่มาตรฐานไม่ได้ออกกฎอย่างชัดเจน
MM
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.