2012年10月25日 星期四

[GCC] C++ compiler option for static analysis

GCC compiler option for some C++ checking.

==========================================


-Weffc++ (C++ and Objective-C++ only)                                                                                                                                                   
   Warn about violations of the following style guidelines from Scott Meyers' Effective C++ book:
   
   ·   Item 11:  Define a copy constructor and an assignment operator for classes with dynamically allocated memory.
   
   ·   Item 12:  Prefer initialization to assignment in constructors.
   
   ·   Item 14:  Make destructors virtual in base classes.
   
   ·   Item 15:  Have "operator=" return a reference to *this.
   
   ·   Item 23:  Don't try to return a reference when you must return an object.
   
   Also warn about violations of the following style guidelines from Scott Meyers' More Effective C++ book:
   
   ·   Item 6:  Distinguish between prefix and postfix forms of increment and decrement operators.
   
   ·   Item 7:  Never overload "&&", "||", or ",".
   
   When selecting this option, be aware that the standard library headers do not obey all of these guidelines; use grep -v to filter out those warnings.


-Woverloaded-virtual (C++ and Objective-C++ only)
    Warn when a function declaration hides virtual functions from a
    base class.

-Wsign-promo (C++ and Objective-C++ only)
    Warn when overload resolution chooses a promotion from unsigned or
    enumerated type to a signed type, over a conversion to an unsigned
    type of the same size.  Previous versions of G++ would try to
    preserve unsignedness, but the standard mandates the current
    behavior.

-Wextra
    This enables some extra warning flags that are not enabled by
    -Wall.

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
+};