2012年10月17日 星期三

[C++] flexible array

最近看到squid某個patch, 看到比較少用的flexible array, 在clang下面支援不足 (non-POD type), 所取得的備案.
What is Flexible arrays: Flexible array通常是使用在struct 最後一個member, 來讓struct可以使用不定長度的array. Ex:
     struct line {
       int length;
       char contents[0];
     };
     
     struct line *thisline = (struct line *)
       malloc (sizeof (struct line) + this_length);
     thisline->length = this_length;

Reference:
http://gcc.gnu.org/onlinedocs/gcc-4.1.2/gcc/Zero-Length.html

Notes:
Flexible was introduced in C99 standard but not in C++. Clang didn't support non-POD type flexible array.

Discuss thread

remove flexible array for clang support 
http://www.squid-cache.org/mail-archive/squid-dev/201208/0008.html

find bug about previous patch
http://www.squid-cache.org/mail-archive/squid-dev/201210/0156.html

other solution
http://www.squid-cache.org/mail-archive/squid-dev/201210/0186.html

It introduce a wrapper which help to preserve shared memory usage by using placement-new operator. The caller must allocate enough memory when constructing FlexibleArray which capacity must match the memory.

+template 
+class FlexibleArray
+{
+public:
+    explicit FlexibleArray(const int capacity) {
+        if (capacity > 1) // the first item is initialized automatically
+            new (items+1) Item[capacity-1];
+    }
+
+    Item &operator [](const int idx) { return items[idx]; }
+    const Item &operator [](const int idx) const { return items[idx]; }
+
+    //const Item *operator ()() const { return items; }
+    //Item *operator ()() { return items; }
+
+    Item *raw() { return items; }
+
+private:
+    Item items[1]; // ensures proper alignment of array elements
+};