#include <stdlib.h>
void *operator new[](size_t size, int n){
if( size != 0 && n != 0 )
return calloc(n, size);
return calloc(1, 1);
}
int main(){
int * p1;
const int i = 0;
// p1 = new (20) int[i] ; // Case 1 (OK)
p1 = new (20) (int[i]); // Case 2 (Warning)
if( p1 == 0 )
return 1;
return 0;
}
โค้ดนี้ (https://godbolt.org/g/hjo7Xn) คอมไพล์ได้สำเร็จด้วย Clang 6.0.0 อย่างไรก็ตาม GCC 7.3 ออกคำเตือนว่าอาร์เรย์ที่มีความยาวเป็นศูนย์เป็นสิ่งต้องห้ามใน C ++ หากถอดวงเล็บออก (กรณีที่ 1) คำเตือนจะหายไป
ไม่เหมือนกับอาร์เรย์ที่มีความยาวเป็นศูนย์ที่จัดสรรแบบคงที่ (C++03:8.3.4/1) อนุญาตให้ใช้อาร์เรย์ที่มีความยาวเป็นศูนย์ที่จัดสรรแบบไดนามิกได้ (C++03:5.3.4/6) อย่างไรก็ตาม ในมาตรฐาน C++ รูปแบบหลังจะได้รับอนุญาตอย่างชัดเจนก็ต่อเมื่อทำตามหนึ่งในสองเส้นทางไวยากรณ์ที่เป็นไปได้ของ นิพจน์ใหม่ นั่นคือเส้นทางที่มี new-type-id em> และไม่มีวงเล็บ (กรณีที่ 1)
มาตรฐาน C++ อนุญาตให้ใช้ นิพจน์ใหม่ กับอาร์เรย์ที่มีความยาวเป็นศูนย์ตามเส้นทางไวยากรณ์ที่สอง นั่นคือ ด้วย type-id และ วงเล็บ (กรณีที่ 2)?
คำพูดที่เกี่ยวข้องเพียงอย่างเดียวคือ C++03:5.3.4/5:
เมื่อวัตถุที่จัดสรรเป็นอาร์เรย์ (นั่นคือ มีการใช้ไวยากรณ์ direct-new-declarator หรือ new-type-id หรือ type-id em> หมายถึงประเภทอาร์เรย์) นิพจน์ใหม่ ให้ตัวชี้ไปยังองค์ประกอบเริ่มต้น (ถ้ามี) ของอาร์เรย์
ข้อความ (if any)
จะอนุญาตให้ใช้อาร์เรย์ที่ไม่มีองค์ประกอบ อย่างไรก็ตาม ดูเหมือนจะไม่ชัดเจนว่าจะอ้างถึงทั้งสองกรณีหรือเฉพาะอาร์เรย์ที่มี new-type-id และไม่มีวงเล็บ (กรณีที่ 1)
ขอบคุณล่วงหน้า.
หมายเหตุ:
- ISO/IEC 14882:2003 ส่วนที่ 8.3.4 ย่อหน้าที่ 1:
#P9#
- ISO/IEC 14882:2003 ส่วนที่ 5.3.4 ย่อหน้าที่ 6:
#P10#
- ISO/IEC 14882:2003 ส่วนที่ 5.3.4 ย่อหน้าที่ 7:
#P11#
- ISO/IEC 14882:2003 ส่วนที่ 5.3.4 ย่อหน้าที่ 1:
#P12# #P13# #P14#
- แม้ว่าคำพูดข้างต้นมาจากมาตรฐาน C++03 เท่าที่ฉันทราบ ปัญหานี้ยังคงไม่ชัดเจนใน C++ Standard เวอร์ชันใหม่กว่า (C++11, C++14 และ C++17)
- โพสต์ที่น่าสนใจของ Herb Sutter เกี่ยวกับศูนย์ อาร์เรย์ความยาว
- โค้ดในตัวอย่างเป็นการทดสอบที่มีการปรับเปลี่ยนเล็กน้อยจากชุด SuperTest ของ SolidSands'
operator new[]
? มันเกี่ยวอะไรด้วยวะ? - person Cheers and hth. - Alf   schedule 30.04.2018