ข้อสรุปสุดท้าย: เลขคณิตบน a void*
นั้นผิดกฎหมายทั้งใน C และ C ++
GCC อนุญาตให้เป็นส่วนขยายให้ดูที่การคำนวณทางคณิตศาสตร์void
และตัวชี้ฟังก์ชั่น (โปรดทราบว่าส่วนนี้เป็นส่วนหนึ่งของบท "C Extensions" ของคู่มือ) เสียงดังกราวและ ICC น่าจะอนุญาตให้ใช้void*
เลขคณิตสำหรับจุดประสงค์ในการเข้ากันได้กับ GCC คอมไพเลอร์อื่น ๆ (เช่น MSVC) ไม่อนุญาตให้ใช้การคำนวณทางคณิตศาสตร์void*
และ GCC ไม่อนุญาตหากระบุ-pedantic-errors
แฟล็กหรือหากระบุ-Werror-pointer-arith
แฟล็ก (แฟล็กนี้มีประโยชน์หากรหัสฐานของคุณต้องคอมไพล์ด้วย MSVC)
มาตรฐาน C พูด
คำพูดนำมาจากร่าง n1256
คำอธิบายมาตรฐานของสถานะการดำเนินการเพิ่มเติม:
6.5.6-2: สำหรับการเพิ่มเติมตัวถูกดำเนินการทั้งสองจะต้องมีประเภทคณิตศาสตร์หรือตัวถูกดำเนินการหนึ่งจะเป็นตัวชี้ไปยังประเภทวัตถุและอื่น ๆ จะต้องมีประเภทจำนวนเต็ม
ดังนั้นคำถามที่นี่คือว่าvoid*
เป็นตัวชี้ไปที่ "ประเภทวัตถุ" หรือเทียบเท่าว่าvoid
เป็น "ประเภทวัตถุ" คำจำกัดความของ "ประเภทวัตถุ" คือ:
6.2.5.1: ประเภทถูกแบ่งพาร์ติชันออกเป็นประเภทออบเจกต์ (ชนิดที่อธิบายถึงวัตถุทั้งหมด), ประเภทฟังก์ชั่น (ประเภทที่อธิบายฟังก์ชั่น) และประเภทที่ไม่สมบูรณ์ (ประเภทที่อธิบายถึงวัตถุ แต่ไม่มีข้อมูลที่จำเป็นในการกำหนดขนาด)
และมาตรฐานกำหนดvoid
เป็น:
6.2.5-19: void
ประเภทประกอบด้วยชุดค่าที่ว่างเปล่า; เป็นประเภทที่ไม่สมบูรณ์ที่ไม่สามารถดำเนินการให้เสร็จสิ้นได้
เนื่องจากvoid
เป็นชนิดที่ไม่สมบูรณ์จึงไม่ใช่ชนิดวัตถุ ดังนั้นจึงไม่ใช่ตัวถูกดำเนินการที่ถูกต้องสำหรับการดำเนินการเพิ่มเติม
ดังนั้นคุณไม่สามารถทำการคำนวณทางคณิตศาสตร์ของvoid
ตัวชี้ได้
หมายเหตุ
เดิมทีคิดว่าvoid*
อนุญาตให้ใช้เลขคณิตเนื่องจากส่วนเหล่านี้ของมาตรฐาน C:
6.2.5-27: ตัวชี้เป็นโมฆะจะต้องมีข้อกำหนดการเป็นตัวแทนและการจัดตำแหน่งเดียวกัน
กับตัวชี้ไปยังชนิดอักขระ
อย่างไรก็ตาม
ข้อกำหนดการเป็นตัวแทนและการจัดตำแหน่งเดียวกัน
นั้นหมายถึงการบ่งบอกถึงความสามารถในการแลกเปลี่ยนระหว่างกันกับฟังก์ชั่นการคืนค่าจากฟังก์ชั่นและสมาชิกของสหภาพ
ดังนั้นวิธีการที่printf("%s", x)
มีความหมายเหมือนกันไม่ว่าx
มีประเภทchar*
หรือแต่มันไม่ได้หมายความว่าคุณสามารถทำเลขคณิตบนvoid*
void*
หมายเหตุบรรณาธิการ:คำตอบนี้ได้รับการแก้ไขเพื่อให้สะท้อนถึงข้อสรุปสุดท้าย