ข้อสรุปสุดท้าย: เลขคณิตบน 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*
หมายเหตุบรรณาธิการ:คำตอบนี้ได้รับการแก้ไขเพื่อให้สะท้อนถึงข้อสรุปสุดท้าย