วัตถุประสงค์ของคำหลักคงที่ในพารามิเตอร์อาร์เรย์ของฟังก์ชั่นเช่น "char s [static 10]" คืออะไร?


144

ขณะเรียกดูซอร์สโค้ดฉันพบฟังก์ชั่นเช่นนี้:

void someFunction(char someArray[static 100])
{
    // do something cool here
}

ด้วยการทดลองบางอย่างดูเหมือนว่าผู้มีสิทธิ์อื่นอาจปรากฏที่นั่นด้วย:

void someFunction(char someArray[const])
{
    // do something cool here
}

ดูเหมือนว่าตัวระบุจะได้รับอนุญาตเฉพาะภายใน[ ]เมื่ออาร์เรย์ถูกประกาศเป็นพารามิเตอร์ของฟังก์ชัน สิ่งเหล่านี้ทำอะไร ทำไมมันแตกต่างกันสำหรับพารามิเตอร์ฟังก์ชั่น?

คำตอบ:


127

การประกาศครั้งแรกบอกคอมไพเลอร์ที่someArrayมีความยาวอย่างน้อย 100 องค์ประกอบ สามารถใช้สำหรับการปรับให้เหมาะสม ยกตัวอย่างเช่นมันก็หมายความว่าจะไม่someArrayNULL

โปรดทราบว่ามาตรฐาน C ไม่ต้องการให้คอมไพเลอร์วินิจฉัยเมื่อการเรียกใช้ฟังก์ชันไม่เป็นไปตามข้อกำหนดเหล่านี้ (กล่าวคือเป็นพฤติกรรมที่ไม่ได้กำหนดความเงียบ)

การประกาศครั้งที่สองเป็นการประกาศsomeArray(ไม่ใช่someArrayองค์ประกอบ!) ในฐานะ const เช่นคุณไม่สามารถเขียนsomeArray=someOtherArrayได้ char * const someArrayมันเป็นเช่นเดียวกับถ้าพารามิเตอร์ได้

ไวยากรณ์นี้สามารถใช้งานได้เฉพาะภายในสุด[]ของอาร์เรย์เครื่องมือประกาศในรายการพารามิเตอร์ฟังก์ชัน มันจะไม่สมเหตุสมผลในบริบทอื่น

ข้อความมาตรฐานซึ่งครอบคลุมทั้งสองกรณีข้างต้นอยู่ใน C11 6.7.6.3/7 (คือ 6.7.5.3/7 ใน C99):

การประกาศพารามิเตอร์เป็น '' array of type '' จะถูกปรับเป็น '' ตัวชี้ที่มีคุณสมบัติเป็นประเภท '' โดยที่ qualifier ประเภท (ถ้ามี) เป็นพารามิเตอร์ที่ระบุภายใน[และมา]ของประเภทอาร์เรย์ หากคำหลักแบบสแตติกปรากฏขึ้นภายใน[และที่มา]ของประเภทอาเรย์ดังนั้นสำหรับการเรียกใช้ฟังก์ชั่นแต่ละครั้งค่าของการโต้แย้งที่แท้จริงจะต้องให้การเข้าถึงองค์ประกอบแรกของอาร์เรย์ที่มีองค์ประกอบอย่างน้อยที่สุดตามที่ระบุโดย การแสดงออกขนาด


35
ในหัวข้อนี้: ฉันสงสัยว่าควรพิจารณาให้ใช้int foo(struct bar [static 1]);แทนint foo(struct bar *);ลายเซ็นสำหรับฟังก์ชันที่ไม่ยอมรับพอยน์เตอร์ NULL หรือไม่ (ฉันรู้ว่า gcc มีไวยากรณ์ที่ไม่เป็นทางเลือกอื่นในการติดธงทำหน้าที่ดังกล่าวเพื่อให้ผู้แปลสามารถให้คำเตือน .. )
R .. GitHub STOP ช่วย ICE

2
ฉันเพิ่งตรวจสอบ gcc และเสียงดังกราวด์และไม่คิดว่า someArray จะไม่เป็นโมฆะเสมอเมื่อฉันขอให้พวกเขาเปรียบเทียบกับ 0 นอกจากนี้ฉันพยายามหาประโยคที่แน่นอนใน C99 ซึ่งกำหนดไว้ มีบันทึกใน 6.7.5.3-21 ซึ่งระบุถึงความหมายที่ต้องการและนั่นคือ ฉันสงสัยว่าเราสามารถพึ่งพาสิ่งนี้ได้ นอกจากนี้ทั้งหมดนี้ไม่ได้เป็นส่วนหนึ่งของฟังก์ชั่นลายเซ็นจึงมีไม่มากที่เราบังคับใช้ผ่านมัน
Nordic Mainframe

5
ลิงก์นั้นดูเหมือนจะเน่าเสียไปนี่คือสิ่งที่ชี้ไปหรือเปล่า pic.dhe.ibm.com/infocenter/zos/v1r12/…
Ross Aiken

13
@NordicMainframe: มีบางเวลา แต่รุ่นปัจจุบันclangเตือนอย่างถูกต้องเมื่อคุณพยายามส่งอาร์กิวเมนต์ NULL ที่รู้จักไปยังฟังก์ชันที่มีการ[static 1]ประกาศพารามิเตอร์
dreamlax

1
@CiroSantilli 巴拿馬文件六四事件法轮功if (!someArray) { somecode... }สามารถลบได้
MM
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.