Tuesday 17 June 2014

C++11 Features - Constant Expression

As C++ ISO standard committee promises that the future of C++ will be continuing focusing on its performance as one of its most dominant features. Watch what Bjarne Stroustrup said about the future of C++ on this video. Again here in C++11 constant expression is introduced as a feature/enhancement to improve C++ performance. As C++ is a language that writes once and compiles for all, the idea behind this new feature is to move some of work that used to be done at run time back to compiling time. As the time to evaluate the objects/function is spent ahead, sure for some sense it will enhance the run-time performance.

An extra keyword is introduced as constexpr. It can be used with build-int types, objects, functions, constructors and etc.

1. Motivation
Some of existing problems in C++03 have served well as the motivations of this new feature. Problems like some functions in <limits.h> not regarded const expression (not evaluated at compiling time), surprise of "dynamic initialization" of const expressions that are based on other const expression, and so on. In [2] a very good explanation and deep extension is provided.

2. constexpr and const
constexpr is introduced as a new feature/keyword in C++11, however const has been there for ages and it will continue exist to serve its purpose. Bear in mind that constepxr is not introduced to replace const.

constexpr serves different purpose. It tells the compiler that this piece of code can be evaluated at compile time. If objects or functions with constepxr specifier can be evaluated at compiling time, compiler will do their best to optimize this piece of code, for instance put the const objects into const data section and emit when code needs them.

const servers a different purpose and known as logical constant in C++. Except serving very limited functionality to tell compiler that this is const literal type and can be optimized better (for instance put the data into const data section and emit when code needs them), its main purpose is to be used in API definition. For instance pass const variable/reference/pointer as arguments. Simply it tells people that logically these arguments should stay untouched after calling the API functions. Another good example is to define const functions that tells what exactly functions a const object can invoke. (As I said const in C++ only works as logical constant, because the const-ness can be cast away and then object can be modified. Read Casting in C++.)

Now both of them are existing in C++11. Some of their functionality is overlapped for instance declaring/defining constant variables/objects to be evaluated at compiling time, but other functionality of const will stand as it is, for instance logical const-ness and API definition.

3. constexpr variables/objects
constexpr can be used with definition of vriables/object, and declaration/definition of functions and constructors. But it can't be used as a specifier with class types declaration and arguments. Actually both const and constexpr can't used with declaration of class type and only const specifier can be used with function/constructor arguments.

// Example 1: constexpr variables
//********************************************************************************
constexpr int Increment2(int x); // Ok function declaration
constexpr int Increment3(int x) { return x+3;} //  Ok - function definition
constexpr int x{2}; // Ok - constexpr variable

constexpr struct Foo {}; // Error - can't used with class type declaration
struct Bar {
    int x;
    int y;
    constexpr Bar(int a) : x(Increment3(a)), y(Increment3(a)) {} // Ok  - constructor definition
    constexpr Bar(int a, int b) : x(Increment2(a), y(Increment3(b)) {} // Ok - constructor definiton
}

constexpr Bar myBar1(1); // Ok - const object
constexpr Bar myBar2(1, 2); // Error - Increment2 not defined yet

constexpr int Increment2(int x) { return x+2;} // Ok - function definition
constexpr Bar myBar3(1, 2); // Ok - const object with all definition needed
//********************************************************************************

When constexpr A is used by constexpr B. constexpr A has to be declared and defined before constexpr B is evaluated. As shown in Example 1, myBar2 vs. myBar3.

In this case (variables/objects are declared with constexpr specifier) these variables/objects are declared const. This mean that constexpr specifier guarantees the const-ness and promise better code optimization. For the user-defined class types the {}-list has to be explicitly defined when defining a constexpr class types, as shown in Example 2.

// Example 2:
//********************************************************************************
struct Foo {
    int x;
    int y;
};

constexpr Foo cfoo1 = {1, 2}; // Ok, {}-list is explicit
constexpr Foo cfoo2; // Error
//********************************************************************************

4. constexpr functions
constepxr specifier can be used together with functions and constructors. The functions can be either standalone functions or member functions. constexpr functions and constructors are implicitly inline functions. It means that potentially production code with constexpr specifier can be better optimized and this is another performance enhancement features.

constexpr standalone functions
Because constexpr function can be evaluated at compiling time, therefore only some functions with certain features can be qualified as constexpr functions. For instance definitely functions with feature only at dynamic time are not qualified as constexpr functions. Here is the list of requirements,
    - Non-virtual function
    - Must not return void and must return a value of literal type
    - All its arguments must be literal types as well
Besides the requirements on the function declaration there are requirements on it function body as well. For instance only including null statement, typedef and so on. Please refer to [1] and [5] for more details. They are quite obscure descriptions. In my understanding the function body must not have operator/function invocation that is to change value of existing variables, such arguments or automatic variables declared inside,. For instance pre-increment and post-increment cannot be used in the constexpr function body because they change the value of existing variables. And the value passed as arguments and returned as result must be constexpr too and can be evaluated at compiling time.

One more thing to keep in mind. constexpr is acting like cv-qualifier. Functions with/without constexpr do not change their function signature, as shown in Example 3.

// Example 3
//********************************************************************************
constexpr int Increment2(int x) {reurn x+2; }
int Increment2(intx) {x+=2; return x;} // Error: redefinition
//********************************************************************************

constexpr constructors
Exactly the same as constexpr standalone functions constexpr constructor is to be evaluated at compiler time as well. Therefore any dynamic feature can't be applied and at the same time there are some same sort of requirements applied to its function body as well. Here is the requirements,
    - No virtual function
    - Can have base class that does not have virtual functions and apply recursively
    - All its member variables must be literal types.
    - All its member variables can be evaluated at compiling time and it must have constexpr constructor as well if they are class types
     - No function-try-block
The same requirements on standalone function body apply to constexpr constructor as well. Please refere to [1] and [5].
   
constexpr member functions
constexpr specifier can be used to decorate non-static member functions. And it guarantees the const-ness of this function. And only literal  class type can have constexpr non-static member functions, otherwise the program is ill-formed as shown in Example 4.

// Example 4
//********************************************************************************
struct Foo {
    explicit Foo(int val);
    constexpr std::string GetName() {return "Foo";} // Ok
    constexpr int GetValue() {return m_val;} // Error: m_val is not a constexpr

    int m_val;
};
//********************************************************************************

5. constexpr function evaluation
constexpr specified function can be evaluated at compiling time. If the argument passed through are constexpr expression, then this function will be evaluated at compiling time. Otherwise run time.

Function invocation substitution
Function invocation substitution happens when  a constexpr function is called in another constexpr function. The callee functions will be substituted with its function body or its result after evaluation in the caller function when the caller function is evaluated by compiler, as shown in Example 5. In this sense the callee constexpr functions must be declared and defined before the caller constexpr functions.

// Example 5
//********************************************************************************
constexpr int Foo() {return 0}
constexpr int Bar() {return Foo();} // substituted as exactly as Foo()

namespace name1 {
    constexpr int five = 5;
    constexpr int ReturnFieve() {return five;}
}

constexpr int ReturnFive() {return name1::ReturnFive();} // function body is substituted as "5".
//********************************************************************************

As function invocation substitution happens, the variable/object is initialized via {}-list by the return value of constexpr functions and the functions will be replaced by the deepest constexpr function body or its result, after evaluation by compiler.

constexpr vs. non-constexpr functions
Given a well-formed constexpr function, it can be called as a non-constexpr function or a constexpr function. The situation depends on what the arguments passed into the function to invoke it. If all the arguments are passed as constexpr expression, then this function will be invoked as constexpr function and evaluated at compile time, otherwise it will be called as a normal function. Comparing with non-constexpr function, constexpr functions provide opportunities to evaluate some of invocations at compiling time and better code optimization. However non-constexpr compiler will invoke them all at run time even thought they can be evaluated at compiling time as shown in Example 6.

// Example 6
//********************************************************************************
constexpr int factorial1(int n) {
    return n >= 1? 1 : (n*factorial(n-1));
}

int factorial2(int n) {
    return n >= 1? 1 : (n*factorial(n-1));
}

int myArray[factorial1(5)]; // Ok - array with size of 5! (factorial1(5) evaluated at compiling time)
int myArray[factorial2(5)]; // Error - array have to be declared with const size (known at compiling time)

constexpr int n = 6;
int m = 7;
factorial1(n); // evaluated at compiling time
factorial1(m); // evaluated at run time
factorial2(n); // evaluated at run time
factorial2(m); // evaluated at run time
//********************************************************************************

6. Summary
Definitely it will be good practice to use constexpr specifier to replace const specifier to declare constant literal types variables/object in order to prevent  surprising "dynamic initialization" as stated in Section 1. Use constexpr function for simple/arithmetic functions (easier for inline as well). For constructor and member functions C++11 is still very strict about user-defined types. It has to be literal types (please refer to [1]) that is very strict. So use constexpr constructor and member function only on simple data structure (like POD, refer to Plain Old Data (POD) on C++11). Google C++ Style Guide provides good suggestions.

Bibliography:
[1] C++11 standard
[2] [N2235=07-0095] Gabriel Dos Reis, Bjarne Stroustrup, and Jens Maurer: Generalized Constant Expressions -- Revision 5
[3] http://www.stroustrup.com/C++11FAQ.html
[4] http://en.wikipedia.org/wiki/C%2B%2B11
[5] http://en.cppreference.com/w/cpp/language/constexpr
[6] http://google-styleguide.googlecode.com/svn/trunk/cppguide.xml#Use_of_constexpr

Monday 16 June 2014

C++11 Features - Automatic Type Deduction

Automatic type deduction is introduced in C++11 as a new feature. The standard defines that the type information will be deduced by the compiler based on the information extracted from the initialization value. The keyword is auto (was used as storage class specification and now is deprecated in C++11).

1. Problems in C++03
Before C++11, C++ is a strictly type declaration programming language. Every variable/object has to be declared first with the exactly correct type before it is to be used. Its type is checked at both compiling time and run-time. Any mismatch will be either flagged out by compiler or punished at run time (polymorphism). This strict requirement often causes troubles and inconvenience in C++03.

Too much typing on the return type of STL containers
This is no new to anyone, especially for those functions of STL containers return the iterator type. This sort of trait-type related types have to be declared from its explicit instantiation of containers.

// Example 1: some functions of STL containers
//********************************************************************************
std::vector<std::vector<std::string>>> myDoubleVec;
std::vector<std::vector<std::string>>>::const_iterator vecBegin = myDoubleVec.begin();

class UserID;
class UserInfo
UserID userId;
std::map<UserID, UserInfo> myDB;
// ......
std::map<UserID, UserInfo>::iterator pos = myDB.find(userId);
//********************************************************************************

Unfortunately in C++03 the unnecessary typing is still needed anytime when you are trying to access the element in STL container. It is really not necessary to hit the keyboard to declare a long type, because its type can be easily deduced from instantiation of template. Of course for some of STL container instantiations can be typedef-defined to save the typing.  But this is only true for those that have the file or class scope. It is really not a good idea to have typedef-definition for every instantiation, especially for those only needed for automatic variables declaration.

Used in generic/template programming
The problems are like the difficulty to decide the intermediate variable types and the return types. I will not waste more time on this, as Bjarne Stroustrup provides two really good examples in his C++11 FAQ website. And I think this is the key motivation behind the introduction of this feature in C++11.

2. Tips of using auto
C++11 has introduced a new feature - auto to fix the excessive typing issue. auto can be used with variables, function types, STL containers, std::intializer_list, lambda expression and so on. Together work with newly introduced feature decltype. Their combination fix the return type issues in template programming. Please see more on this issue, suffix return type syntax.
Here I would like to introduce you a few tips when using auto in your daily application.

Reference type
Object type and pointer type work fine. There is a bit special about reference type. Have to use "auto &" to refer to a reference type.

// Example 2: 
//********************************************************************************
auto x = 1; // OK
const auto &y = 2;  //OK - pure rvlaue (will be allocated in const read-only memory section) 
auto &z = 2; // Error - lvalue
auto *a = &x; // OK

int Foo();
int& Bar();
int* Cat();
auto b = Foo(); // OK - auto as int
const auto &c = Foo(); // OK - pure rvalue bind to temporary value
auto &d = Foo(); // Error - lvalue
auto e = Bar(); // OK - auto as int
auto& f = Bar(); // OK - auto as int&
const auto& g = Bar(); // OK - const int&
auto h = Cat(); // OK - auto as int*
auto *i = Cat(); // OK - auto as int*
auto *j = Bar(); // Error - Bar() returns reference not poitner
//********************************************************************************

As well keep in mind that only const reference type, regarded as pure rvalue, can bind to a const value or temporary value but lvalue reference type are forbidden to bind to const value and temporary value, as shown in code with orange color in Example 2.

Object slicing in automatic type deduction
Object slicing happens when the object or the reference-to-object of derived class is passed to create an object of base class. It was discussed briefly in this blog Catching exception. Passing a pointer/reference type as augments in function calling can prevent object slicing. But when a function returns a reference type, if object slicing happens or not depends on the type of variable declared to take the returning from the function.

// Example 3: object slicing
//********************************************************************************
class Base {
public:
    virtual const std::string GetName() const {
        return "Base";
    }
};

class Derived : public Base {
public:
    virtual const std::string GetName() const {
        return "Derived";
    }
};

static Derived gDervied;

Base GetBase() {
    return gDervied;
}

Base& GetBaseRef() {
    return gDervied;
}

void Test() {
    auto b = GetBase(); // object slicing - auto as Base
    auto b2 = GetBaseRef(); // object slicing - auto as Base
    auto &bRef = GetBaseRef(); // polymorphic object: Derived - reference type
}
//********************************************************************************

In Test() of Example 3 there is no surprise that the object slicing happens on "auto b" but does not happen to "auto &bRef". "auto b2" is a sliced object, a bit of surprise. Actually should not, if refer to the last sub-section and Example 2.

The deduced variable types must be the same in multi-variable declaration
If there are multiple variables declared in one statement, the variable types deduced from the initialization of variables must be the same. Otherwise the compiler should flag it out.

// Exmaple 4:
//********************************************************************************
auto a = 1, b = 2; // OK
auto x = 1, y = 2.0; //  Error: in VC12
                               /* error C3538: in a declarator-list 'auto' must always deduce to the same type */
auto m = a, &n = a, *p = &b; // OK
//********************************************************************************

Keep in mind that any auto declaration will be fine if it is legal declaration by replacing auto with the concrete type. In the first code statement in Example 4 auto can be replaced by "int". It is also worth pointing out that automatic type deduction has stricter checking. For instance "int x = 1, y = 2.0;" is not an error but a warning (complaining about the narrowing) . However "auto x = 1, y = 2.0;" is an error.

Initialization
As shown in C++11 - Initializer-list (Part I) and C++11 - Initializer-list (Part II), both {}-list and "()" can be used to initialize objects. auto works fine on both. But keep in mind underneath initialization via {}-list have different type from "()".

// Example 5: initialization
//************************************************
auto x(1);   // Case 1
auto x = 1; // Case 2
auto x{1};  // Case 3
//************************************************

In Example 5:
    - auto as int in Case 1
    - auto as int in Case 2
    - auto as std::initializer_list<int> in Case 3
So bear in mind that initialization via {}-list  brings you different types and invokes initializer-list constructor.

Used in range for loop
The functionality of for loop has been enhanced in C++11. The extended capability is called "range-based for", as shown in Example 6.

// Example 6
//********************************************************************************
std::vector<int> vec{1, 2, 3, 4};
for (auto x : vec) {

}
//********************************************************************************

Range-based for can be used in
    - C style array
    - C++11 std::initializer_list<T>
    - C++ STL containers

Return type of template functions
The combination of auto and decltype can be used to declare the return type of template function. The actual return type will be deduced based on the instantiation of template functions/classes by the compiler at compiling time,

// Example 7: from C++11 standard
//********************************************************************************
struct A {
    char g();
    template<class T> auto f(T t) -> decltype(t + g()) {
        return t + g();
    }
};
template auto A::f(int t) -> decltype(t + g());
//********************************************************************************

In Example 7 if the T is instantiated as int, then the return type will be decltype(int+char) - int. Just be aware of that decltype() is different from decltype(()). The latter returns the reference type.

Used with lambda-expression
Lambda expression/function is another key feature introduced in C++11. Certainly I can recall that every time I need implement a class/struct for a predicate-function/functor no matter how trivial the function is. Especially when this predicate-function/functor is only used locally and really no excuse to implement in a file scope, extra excessive typing and decision on which scope to put it are really hassles. With the power of lambda-expression these issues will be gone.

// Example 8: auto and lambda expression
// ********************************************************************************
void Foo() {
    // ......
    auto increment3 = [](int) {return x + 3;};
    int x{0};
    int y = increment3(x) ; // y = 3
}
//********************************************************************************

As lambda expression is an key feature, I would like to discuss it in more detail and intensively. I will discuss this topic in another blog and add a link up here.

3. Summary
How to judge if an expression with auto is legal . Here is the rule of thumb:
    - Replace auto with the concrete type, for instance "int", if the expression after replacement is legal then this expression with auto is legal too.

Google C++ Style Guide describes the pros and cons of automatic type deduction and provides reasonable suggestions on when/where to use auto. In my opinion I would try to avoid using auto as much as as possible and try explicitly declaration as much as possible in order to tell my fellow colleagues what exactly I try to do. In this explicit way certainly it will make the code easier to read and less ambiguous to communicate. Exceptions in only two scenarios to use auto.
    - Used as the return type of STL containers to save typing
    - Used in generic programming (template) together with decltype

Bibliography:
[1] C++03 standard
[2] C++11 standard
[3] http://www.stroustrup.com/C++11FAQ.html
[4] http://en.wikipedia.org/wiki/C%2B%2B11
[5] [N3257=11-0027 ] Jonathan Wakely and Bjarne Stroustrup: Range-based for statements and ADL
[6] http://google-styleguide.googlecode.com/svn/trunk/cppguide.xml
[7] [N2930=09-0120] Douglas Gregor and Beman Dawes: Range-based for loop wording
[8] [N1478=03-0061] Jaakko Jarvi, Bjarne Stroustrup, Douglas Gregor, and Jeremy Siek: Decltype and auto

Monday 9 June 2014

C++ - Evaluation Order

1. Intruduction
Evaluation order is referring to the evaluation sequence of function arguments or operator arguments. It should not be confused with the left-to-right/right-to-left associativity of operators. And it should not be confused with operator precedence either.

Example 1: concepts
//**********************************************************
double Root(double);
double Square(double);
double Cubic(doubel);

void Foo() {
    double x = Root(2)*Square(4)*Cubic(5); // expression 1
    double y = Root(2)*Square(4)+Cubic(5); // expression 2
    // .......
}
//**********************************************************

Evaluation order: the evaluation sequence of functions in the expression - which function Root(2), Square(4) or Cubic(5) is evaluated first, second and last, as shown in expression 1 and 2 in Example 1.
Associativity of operators: multiply the left two first or the right two first in expression 1 in Example 1.
Operator precedence: do the multiplication first then addition in expression 2 in Example 1.
For more details about these concepts please refer to [1], [2] and [3].

An evaluation include two parts, value evaluation and side effect. [2] provides a very good definition about these two concepts. In a simple word value evaluation is referring to what the function/operator implementation should bring to you, for example returning a value after executing the function/operator. And side effect refers to whether the state of the program/thread is changed between before and after the function/operator is called. For instance, modify the global value, manipulate the IO, modify the pass-in arguments and so on.

2 Summary of rules
For all the rules please read the Chapter 5 in C++ standard [1]. Besides [2] also provides very good summary. Here I would like reiterate what I think is important or bug-prone in my daily job.
    - The evaluation order of function arguments is unspecified. The order of calling the function this time could be different from calling the function the next time.
    - The evaluation order of operator arguments is unspecified too. The same as function arguments.
    - Exception for logic operator "&&" and "||". The evaluation order is specified, in the left-to-right order.
    - Operator "?:", the first expression is evaluated and its side effect takes into force before the second and third.
    - Use initializer-list, {}-list, to initialize the object to guarantee the evaluation order, in the left-to-right order element by element.

3. Examples/Bugs in my previous projects
What is the fuss about evaluation order is the side effect. If the evaluation order is not defined and each evaluation brings side effect, then the overall value evaluation and side-effect could be different after the accumulation of value evaluation and side effect of the whole sequence of evaluations. Most of time the programmers will pay enough attention to side effect on global values and IOs when designing the software structure, because they are more noticeable in the software design process. Normally some guard and sync are put in place among them. However, in my experience, the bugs happen mostly when no enough attention paid to side effect on pass-in arguments.

Undefined evaluation order on function/operator calling
C++03 standard says that the evaluation order of arguments of functions/operators are not specified. It means that the vendor of compiler decides it. And C++11 has no changes on this clause.

// Example 2: evaluation order on argument of functions/operators
//********************************************************************************
int IncrementByTwo(int& x) {
    x += 2;
return x;
}

int IncrementByFour(int& x) {
    x += 4;
return x;
}

int IncrementByEight(int& x) {
x += 8;
return x;
}

int SumXYZ(int x, int y, int z) {
    std :: Couto << "x =" << x << std :: endl;
std::cout << "y = " << y << std::endl;
std::cout << "z = " << z << std::endl;
return x + y + z;
}

void Foo() {
    int eoInitVal = { 0 };
std::cout << IncrementByTwo(eoInitVal) << " "
                 << IncrementByFour(eoInitVal) << " "
                 << IncrementByEight(eoInitVal) << " "
                 << std::endl;
eoInitVal = { 0 };
SumXYZ(IncrementByTwo(eoInitVal),
                    IncrementByFour(eoInitVal),
                    IncrementByEight(eoInitVal));
}

// the output of Foo()
/*
14 12 8
x = 14
y = 12
z = 8
*/
//********************************************************************************

Problem happens when the arguments of function/operator are made up of the return value of other function/operator calls that have side effect on the same variables/objects/IOs. One of examples is the "<<"/">>" operator in std streams. As shown in Example 2 the output of std::cout in Foo() is not what we expect, "2, 6, 14". In VC12 (Microsoft Visual Studio Express 2013), the evaluation order of arguments of functions/operators is in the backwards order, from the last argument to the first.

// Example 3: fix of evaluation order on arguments of functions/operator
//********************************************************************************
void Foo() {
    int eoInitVal = { 0 };
    int two = IncrementByTwo(eoInitVal);
    int six = IncrementByFour(eoInitVal);
    int fourteen = IncrementByEight(eoInitVal);
std :: Couto << two << "" << six << "" << fourteen << "" << std :: endl;
eoInitVal = { 0 };
    two = IncrementByTwo(eoInitVal);
    six = IncrementByFour(eoInitVal);
    fourteen = IncrementByEight(eoInitVal);
SumXYZ(two, six, fourteen);
}
//********************************************************************************

Really there are not too many choices. One of them is to write separated expressions to guarantee the evaluation order to have the side effect that you prefer. (Keep in mind that separated expressions guarantee the evaluation order. The expression is guaranteed to be evaluated first and its side effect takes place before evaluating the expressions after itself. Simply the evaluation order is expression by expression.

Be aware of different code path in logical expression
C++ standard guarantee that the functions/operators in logical expression are evaluated in the left-to-right order and a certain optimization is done. For "&&" if the evaluation of the left side is false, then the compiler skips the evaluation of the right side, because it already has the result of the entire logic expression no matter what the right expression is. For "||" if the evaluation of the left side is true, then the compiler skips the evaluation of the right side.

This kind of optimization causes different code path and potentially buries hidden bugs, if the logical expression is made up of function/operator calls and these calls have side effects on the resources/states-of-program (global/automatic variables/object, IOs and etc.).

//Example 4: different code path in logical expression
//********************************************************************************
bool foo(int& x) {
    // modify x
}
bool bar(int& x) {
    // modify x
}
int Square(int x) {
    return x*x;
}

int x{1};
if (foo(x) && bar(x) {
    // ......
    Square(x);
}

// using "x"

if (foo(x) || bar(x)) {
    // ......
    Square(x);
}
// using "x"
//********************************************************************************

In Example 4 depending on the value evaluation of foo(x), there are the different code paths and potential hidden bugs in "&&" case,
    - If foo(x) true, then bar(x) is not called and the argument passed into Square(x) is only modified by f(x).
    - If foo(x) false and bar(x) is evaluated and returns true, then the argument passed into Square(x) is modified by both functions.
It is not difficult to find out the different code paths for the "||" case. If in the true/false branch of "if(...)" the value of "x" is used, then there might be potential bugs.

Wisely use logic operator to avoid performance penalty
As I introduced above, whether the right side of logical expression is evaluated or not depends on the result of the evaluation on the left side. Weighting on the expensiveness of the evaluation of functions in logical expression, carefully considering the evaluation order (the same as the order of functions/operators appearing in logical expressions in this case) prevents the performance penalty.This could play a big role in big data applications.

// Example 5: performance on logical expression
//********************************************************************************
// Let's consider both foo(int) and bar(int) has no side effect
// work like a functor
bool foo(int x); // Expensiveness 9
bool bar(int& x); // Expensiveness 1

for (......) { // big data
    if (foo(x) && bar(x)) {
        // .....
    }
}
//********************************************************************************

In Example 5 let's assume that
    - foo() has expensiveness of 9 to run
    - bar() has expensiveness of 1.to run
    - big data with 1 million (not big)
    - 50% of data evaluate as true on foo() and 50% false
    - 50% of data evaluate as true on bar() and 50% false
Let's examine how costly it is with different orders,
    - cost of "if (foo(x) && bar(x))": 1 million of evaluation of foo() + half million of evaluation of bar(), so total cost = 1 million * 9 + 0.5 million * 1 = 9.5 million
    - cost of "if (bar(x) && foo(x))": 1 million of evaluation of bar() + half million of evaluation of foo(), so total cost = 1 million * 1 + 0.5 million * 9 = 5.5 million

(The same calculation can be done in "||" case.)
See what the math is telling you. Take into account of how expensive the functions are and also getting to know what your business are (statistical knowledge on the result of evaluation on functions/operator). This sort of scenarios has happened to me in my previous projects. For instance given a large list of variables/equations find out the ASSIGNED variables, algebraic variables, differential variables with varying order and so on. There are often multiple conditions that need to verify. In a few cases correctly ordering which function goes first saves me from huge performance penalty. At the same time consider together if these functions called in logical expression are polymorphic functions. (See the performance penalty on polymorphic function, Design Pattern for Scientific Computing - Curiously recurring template pattern VS. dynamic polymorphism.)

Use initializer-list, {}-list, to initialize objects as often as possible
In C++11 initializer-list is introduced to initialize variables/objects. And this should be considered as good practice in C++ coding style. Please refer to my other two blogs for more details on C++11 - Initializer-list (Part I) and C++11 - Initializer-list (Part II).

Initializer-list guarantees that the evaluation order in {}-list is the same order of each element appearing in the {}-list (elements are separated by ","). And value evaluation and side effect take effect before the evaluations of its following elements. And this property holds recursively if all its sub-elements are initialized via {}-list.

//Example 6:
//********************************************************************************
struct Foo {
    Foo(int, int, int);
};

int eoInitVal{ 0 };
Foo f1{ IncrementByTwo(eoInitVal),
             IncrementByFour(eoInitVal),
             IncrementByEight(eoInitVal) }; // Foo f1{2, 6, 14} in VC12
Foo f2(IncrementByTwo(eoInitVal),
            IncrementByFour(eoInitVal),
            IncrementByEight(eoInitVal)); // Foo f2(14, 12, 8) in VC12
//********************************************************************************

"Foo f1" is initialized via {}-list. All its arguments are evaluated from the left-to-right sequence and the value evaluation and side effect take effect before coming to evaluate the next. And it is initialized as we expected by passing {2, 6, 14}. However "Foo f2" is created by creation constructor. It has the same evaluation order as a function call. So the evaluation order is unspecified. In VC12 (Microsoft Visual Studio Express 2013) "Foo f2" is created with the argument list of (14, 12, 8), because VC12 evaluates the function arguments in the backwards order.

Bibliography:
[1] C++11 Standard
[2] http://en.cppreference.com/w/cpp/language/eval_order
[3] http://en.cppreference.com/w/cpp/language/operator_precedence

Friday 6 June 2014

C++11 - Initializer-list (Part II)

I have discussed the significant improvements of C++11 about initializer-list on C++11 - Initializer-list (Part I). Improvements  like workaround of the most vexing parse problem, initializing standard classes via {}-list, initializing STL containers via {}-list and so on.

From now on in C++11 it will be good practice to initialize variables/objects via {}-list and limit the use of "()" for invoking function and operator. Here I would like to list a few tips for correctly using initializer-list in C++11. Hopefully it will help fellow programmers in their daily job.

1. Overloading among constructors and functions
As I introduced in C++11 - Initializer-list (Part I), std::initialzier_list can be used everywhere for instance argument for function and initializer_list constructor. How does it co-exist with other functions or constructor and which one to invoke when overloading exists? Let's see Example 1.

// Example 1: overloading when std::initializer_list as argument
//********************************************************************************
struct Foo {
    Foo(std::initializer_list<int>};
    Foo(int);
    Foo(int, int);
    Foo(int, int, int);
};

Foo f1(1); // Foo(int)
Foo f2(1, 2); // Foo(int, int)
Foo f3(1, 2, 3); // Foo(int, int, int)
Foo f4{}; // Foo(std::initializer_list<int>};
Foo f5{1}; // Foo(std::initializer_list<int>};
Foo f6{1, 2}; // Foo(std::initializer_list<int>};
Foo f7{1, 2, 3}; // Foo(std::initializer_list<int>};
Foo f8(1, 2, 3, 4}; // Foo(std::initializer_list<int>};

struct MyFoo {
    MyFoo(std::initializer_list<int>);
    MyFoo(std::initializer_list<double);
};

MyFoo mf1{1, 2, 3}; // Ok: MyFoo(std::initializer_list<int>);
MyFoo mf2{1.0, 2.0, 3.0}; // Ok: MyFoo(std::initializer_list<double>);
MyFoo mf3{1, 2.0, 3.0}; // Error:: narrowing
MyFoo mf4{}; // Error: ambiguity
MyFoo mf5{std::initializer_list<double> {1, 2.0, 3.0}}; // Ok: explicit calling
MyFoo mf5{std::initializer_list<int> {1, 2.0, 3.0}}; // Error: narrowing

void Bar(std::initializer_list<int>);
void Bar(std::vector<int>);

Bar{}; // Error: - missing function calling "()"
Bar({}); // Ok - Bar(std::initializer_list<int>);
Bar({1, 2}) ; //Ok - Bar(std::initializer_list<int>);
Bar(std::vector<int>{1, 2}); // void Bar(std::vector<int>);
//********************************************************************************

The rule is that the function with std::initializer_list or initializer_list constructor will be selected/invoked if calling explicitly via {}-list, given that fact that the calling is legal and there is no narrowing existing in the list (Please refer to Section 3). There is a surprise for me at the first place as marked in red color in Example 1. I thought it should work and invoke "MyFoo(std::initializer_list<double>);", but unfortunately VC12 (Microsoft Visual Studio Express 2013) complains about it. Later on I kept reading the standard and found that this is due to the auto instantiation type deducing failure, as shown in Section 6.

2. Initializer-list mixed with auto
There is no forward declaration of std::initializer_list, therefore any explicit and implicit use of std::initializer_list will need to include header <initializer_list>. Using with "auto" is an implicit user case, so please remember to include the header.

Example 2: initializer-list with auto
//********************************************************************************
struct Foo {
    Foo(int, int);
};

void Test() {
auto MyVecFoo = { Foo(1, 2), Foo(2, 3), Foo(4, 5) };
for (auto iter = MyVecFoo.begin(); iter != MyVecFoo.begin(); ++iter) {
            // ....
}
}

void Bar(std::initializer_list<Foo> fooVec) {
    for (auto iter = fooVec.begin(); iter != fooVec.end(); ++iter) {
        // ......
    }
}
//********************************************************************************

auto is a new feature introduced in C+11. It enables the auto type deducing. For sure it will make template programming more pleasant.

3. Narrowing
There two types of narrowing. One is between build-in types and another is between derived-to-base objects. In C++11 neither of them is allowed with some exceptions in build-in types narrowing, when variables/objects are initialized via {}-list.

Example 3: narrowing between build-in types
//********************************************************************************
struct Foo {
    int x;
    double y;
    double z;
};

Foo f1{1, 2, 3.0}; // Ok: (2) int -> double
Foo f2{1.0, 2.0, 3.0}; // Error: narrowing (1.0) double -> int
Foo f3(1.0, 2.0, 3.0); .// Warning but Ok
Foo f4{}; // Ok: default value {0, 0.0, 0.0}

int x1{1}; //Ok
int x2{2.0}; // Error: narrowing
int x3 = 2.0; // Warning but Ok
int x4(2.0); // Warning but Ok

// the rest is from C++11 standard
int x = 999; // x is not a constant expression
const int y = 999;
const int z = 99;
char c1 = x; // OK, though it might narrow (in this case, it does narrow)
char c2{x}; // error: might narrow
char c3{y}; // error: narrows (assuming char is 8 bits)
char c4{z}; // OK: no narrowing needed
unsigned char uc1 = {5}; // OK: no narrowing needed
unsigned char uc2 = {-1}; // error: narrows
unsigned int ui1 = {-1}; // error: narrows
signed int si1 = { (unsigned int)-1 }; // error: narrows
int ii = {2.0}; // error: narrows
float f1 { x }; // error: might narrow
float f2 { 7 }; // OK: 7 can be exactly represented as a float
int f(int);
int a[] = { 2, f(2), f(2.0) }; // OK: the double-to-int conversion is not at the top level
//********************************************************************************

As shown in the red color in Example 3 the {}-list has tighter restriction than initializing via "()". As stated at the beginning of this blog, prefer {}-list to initialize values/objects over "()", because "()" could bury the potential numerical bugs in the code.

Here is the list of narrowing in C++11 between build-in types,
    - floating point type -> integer type
    - long double -> double/float; double -> float (Exception const value/expression converted to narrowed type without accuracy loss)
    - integer type/un-scoped enumeration type -> float point type (Exception const value/expression converted to float point type without accuracy loss and can be re-converted back to integer type/un-scoped enumeration type without accuracy loss)
    - integer type/un-scoped enumeration type -> narrowed integer type, for instance int -> char. (Exception const value/expression converted to narrowed integer type without accuracy loss and can be re-converted back to integer type/un-scoped enumeration type without accuracy loss)

Example 4: narrowing between user-defined types
//********************************************************************************
struct Base {
int x[8];
};

struct Derived : public Base {
int y[8];
};

Base myBaseArr[] = { Base{}, Derived{} }; // Ok
Derived myDerivedArr[] = { Derived{}, Base{} }; // Error: narrowing

struct Foo{
Foo() = default;
Foo(int x, int y) : m_x{ x }, m_y{ y } {}

int m_x{ 1 };
int m_y{ 2 };

virtual int GetValue() const { return m_x + m_y; }
};

struct MyFoo : public Foo {
MyFoo() = default;
MyFoo(int x, int y, int z) : Foo{ x, y }, m_z{ z } {}
int m_z;

virtual int GetValue() const { return Foo::GetValue() + m_z; }
};

Foo fArr[4] = { Foo(), Foo{ 2, 3 }, Foo{ 4, 5 }, MyFoo{ 1, 2, 3 } }; // Ok
MyFoo mfArr[3] = { Foo{ 1, 2 }, MyFoo{ }, MyFoo{ 2, 3, 4 }}; // Error: narrowing
//********************************************************************************

There should be no surprise that base-to-derived does not work (regarded as narrowing) and however derived-to-base works.

4. Initialization of special types: reference and pointer
There is a bit of confusion of reference initialization when using with {}-list. Whether the reference variable/object can be initialized via {}-list depends on if it is a pure rvalue (can only appear in the right-hand side of operator). If they is a pure rvalue (prvalue) type, then it can be initialized via {}-list. Otherwise if it is a lvalue (can appear in the left-hand side of operator), then the answer is no.
Pointer can be initialized just like any other build-in types. It can be initialized with a combination of new expression plus {}-list for default value. And the default value of pointer is nullptr (see more on C++11 features - nullptr).

Example 5: initializer-list with reference and pointer
//********************************************************************************
const int& x = {1}; // Ok: x is a prvalue and bound to a temporary int
int& y = {1}; // Error: y is a lvalue hence it has to bound with a variable
const int (&intArr)[2] = {1, 2}; // Ok: const array and bound to a temporary int array

struct Foo {
    int x {1};
    std::string name{"Foo"};
};

const Foo& cfRef = {1, "My Foo"}; // Ok
Foo& fRef = {1, "My Foo"}; // Error

int* intPtr = new int[4] {1, 2, 3, 4}; // Ok: to allocate the memory and initialize the value
int* intPtr1{}; // Ok: default value - nullptr
iint** intPtr2{}; // Ok: default value - nullptr
//********************************************************************************

5. Internal implementation of std::initializer_list<T>
Internally std::initializer_list<T> can be treated as an implementation of wrapping an array and returning the head, tail and size.

// Example 6: Internal implementation of std::initializer_list (from C++11 standard with my favorite name)
//********************************************************************************
struct Foo {
    Foo(std::initializer_list<double>);
};

Foo f{1.0, 2.0, 3.0};
// equivalent to the following implementation internally
double foo_array[] = {1.0, 2.0, 3.0}
Foo f(std::intializer_list<double>(foo_array, foo_array+3));
//********************************************************************************

The life time of the array "foo_array" is the same as the object of std::initializer_list.

//Example 7: the life time of the internal array (from C++11 standard)
//********************************************************************************
typedef std::complex<double> cmplx;
std::vector<cmplx> v1 = { 1, 2, 3 };
void f() {
    std::vector<cmplx> v2{ 1, 2, 3 };
    std::initializer_list<int> i3 = { 1, 2, 3 };
}
//********************************************************************************

An array object is created for v1 and v2, and the array have the same life span with v1 and v2. But for i3 the array is an automatic object. And how many copies of this array are created depends on the implementation of the vendor of the compiler. The compiler could generate one copy of array of {1, 2, 3} in the read-only memory for v1, v2 and i3. Or it could generate one copy for each. Think about the implementation of literal string.

6. Deducing rules with template
As I introduced in C++11 - Initializer-list (Part I), std::initializer_list is a template class. Its type deducing rules comply with template class deducing rules. With the introduction of auto in C++11, std::initializer_list can be initialized as an auto object. Then the instantiation of the exact type of std::initializer_list has to be deduced at compiling time. If more than multiple types can be deduced and cause narrowing problem as introduced in Section 3, the compiler will complain.

// Example 8: auto deducing the instantiation type of std::initializer_list
//********************************************************************************
auto intIL = {1, 2, 3}; // Ok: all elements are in the same type "int"
auto errorIL = {1, 2.0, 3.0}; // Error: in VC12
/*
cannot deduce type for 'auto' from 'initializer-list'
Element '2': conversion from 'double' to 'int' requires a narrowing conversion
Element '3': conversion from 'double' to 'int' requires a narrowing conversion
*/
auto errorIL2 = { 1.0, 2, 3 }; // Error in VC12
/*
cannot deduce type for 'auto' from 'initializer-list'
Element '1': conversion from 'double' to 'int' requires a narrowing conversion
*/
//********************************************************************************

As well please see how the deducing rules cause the constructor/function calling failure in Example 1. Keep in mind that there should be no narrowing existing between elements, shown in Seciton 3, when initializing a std::initializer_list.

Summary
Use initializer-list to initialize variables/objects anywhere you can and use "()" for invoking function and operator only. And keep in mind the narrowing rules then you would be able to use it safely and smoothly.

Bibliography:
[1] C++11 standard
[2] http://www.stroustrup.com/C++11FAQ.html
[3] http://en.wikipedia.org/wiki/C++11#Initializer_lists
[4] [N2640=08-0150] Jason Merrill and Daveed Vandevoorde: Initializer Lists -- Alternative Mechanism and Rationale (v. 2)

Tuesday 3 June 2014

C++11 - Initializer-list (Part I)

Initializer-list curly brackets "{}" is used to initialize variables/objects and it does not replace creation/copy/move constructors. C++03 inherits the C-style initializer-list features and it works only on build-in types and aggregate. C+11 extends this features to all other standard class and STL containers. And it adds another type of constructor, initializer-list constructor.

1. Limitations on C++03 initializer-list
C++03 inherits the C's initializer-list features and keeps the promise of maintaining the back compatibility toward old C++ standard and C standard. Therefore the very basic requirements in C standard are still kept valid in C++ standard. For initializer-list particular features like static initialization and known memory footprint at compiling time are well maintained in C++03.

Works only on build-in types and aggregate
More details about aggregate and initializer-list please refer to my other blog entry, Aggregate on C++11. And more about plain old data (POD) and initializer-list, please refer to Plain Old Data (POD) on C++11.

Example 1: initializer-list on C++03
//********************************************************************************
int i = {0};

struct Foo{
    int x;
    double y;
};

Foo = {1, 1.0};

Foo arr[3] = {Foo()};
//********************************************************************************

There is is long list of requirements for classes that can be qualified as aggregate or POD. Refer to those requirements on Aggregate on C++11 and Plain Old Data (POD). Most of standard classes are no near to these requirements. Therefore in C++03 initialzier-list has very limited use.

Does not work with STL containers
This could be one of most noticeable drawbacks in C++03 initializer-list, because it makes perfect sense that initializer-list should work on STL container. For instance std::vector internally it could just be an array implementation. However in C++03 initializer-list works on all arrays but does not on std::vector. Really no good excuse to justify this.

Example 2: initialier list and std::vector
//********************************************************************************
// C++03
std::vector<int> myVec = {3, 7, 6, 5,11}; // Error
std::vector<int> myVec{3, 7, 6, 5, 11}; // Error
std::vector<int> myVec(3); // Ok, but not what we want. {0, 0, 0}
std::vector<int> myVec(3, 3); // Ok, but not what we want {3, 3, 3}

// C++03: to initialize to {3, 7, 6, 5, 11}
// Solution 1:
std::vector<int> myVec;
myVec.reserve(5);
myVec.push_back(3);
myVec.push_back(7);
myVec.push_back(6);
myVec.push_back(5);
myVec.push_back(11);

// C++03: better way to initialize to {3, 7, 6, 5, 11}
// Solution 2:
int a[] = {3, 7, 6, 5, 11}
std::vector<int> myVec(a, a+5);
//********************************************************************************

Solution 1 in Example 2 shows how tedious it would be in order to initialize 5 values. And Solution 2 is not a bad one. But when it comes to multi-dimensional vector, std::vector<std::vector<int> >, it would not have a good solution. It would have to repeatedly use the technique, shown in Solution 2 in Exmaple 1, to initialize the one dimension std::vector and repeatedly push back to a 2 dimensional vector, and so on, to get multi-dimensional vector. This is definitely worth of improving.

Most vexing parse problem
This is one specific syntactic ambiguity problem when using "()" to initialize variables/objects. This is because of multiple usage of brackets "()". It can be used for object initialization, function calling and operator.

// Example 3: "()"
//********************************************************************************
struct Foo {
    Foo();
    Foo(int x);
    int operator()(int x);
};
Foo* CreateFoo(int);

int x = 2;
Foo foo(x); // objection creation
CreateFoo(x); // function calling
foo(x); // operator()

struct Bar {
    Bar(Foo);
};

// most of expert C++ programmer would say this is to create an object "my_bar"
// but surprisingly the compiler will say option 2.
Bar my_bar(Foo()); // ambiguity
                               // 1. create a Bar object "my_bar"
                               // 2. function declaration:
                               //     function name - my_bar
                               //     function return type - "Bar" ( a Bar object)
                               //     function argument: a function pointer - return Foo and take no argument

// C++03 workaround
Bar my_bar((Foo()); // Ok - force the compiler to evaluate (Foo()) first
//********************************************************************************

Please read more about this topic on Most vexing parse. This is one of motivations to use curly brackets "{}" to initialize objects rather than using "()".

2. C+11 initializer-list fixes all above 3 problems and provides more
The functionality of initializer-list in C++11 has been hugely expanded. It can work on all classes, work on all STL containers and provide a initializer-list constructor. But still keep the promise of maintaining the back compatibility towards older C++ standard and C standard.

Compatibility maintained on aggregate and POD
C++11 has some improvements on these two features due to expansion of other features but still all the promise on aggregate and POD are still maintained in C++11. Read Aggregate on C++11 and Plain Old Data (POD) for more.

Expand to all classes
Think about the list of limitation that need to be qualified as aggregate in Aggregate on C++11. C++11 has removed all of them, for instance virtual function, base class with non-static member variables and so on.

// Example 4: C++11 initializer list
//********************************************************************************
struct Foo{
    Foo() = default;
Foo(int x, int y) : m_x{ x }, m_y{ y } {}

int m_x{ 1 };
int m_y{ 2 };

virtual int GetValue() const { return m_x + m_y; }
};

struct MyFoo : public Foo {
    MyFoo() = default;
MyFoo(int x, int y, int z) : Foo{ x, y }, m_z{ z } {}
int m_z { 3 };

virtual int GetValue() const { return Foo::GetValue() + m_z; }
};

void Test() {
Foo f{ 2, 3 }; // OK
MyFoo mf{ 4, 5, 6 }; // Ok

Foo fArr[3] = { Foo(1, 2), Foo{ 2, 3 }, Foo{ 4, 5 } }; // Ok
     MyFoo mfArr[3]; // Ok - use default
}
//********************************************************************************

Example 4 shows that C++11 nearly breaks all the crucial requirements needed for C++03 in order to qualify as aggregate then to be initialized by initializer list. Classes with virtual function, user-defined constructors and base class can work fine in all 3 cases in Example 2 shown in Aggregate on C++11. What an improvement!!!

Initializer_list constructor
C++11 provides a template class initializer_list as,
    namespace std {
        template<class E> class initializer_list;
    }
More details please refer to C++11 standard. This is provided in header <initializer_list> under namespace of std. It will create an array of const object E, "const E", with the size of the count of the objects appearing in the list. And provides interface to retrieve the head, tail and the size of the array with constant time complexity.

A constructor of classes with only argument of initializer_list or with the first argument of initializer_list and the rest with default value is called initializer_list constructor. It does not matter with any cv-qualifier.

// Example 5: initializer_list constructor
//********************************************************************************
struct Foo {
    Foo(const std::initializer_list<int>); // initializer_list constructor
    Foo(const std::vector<int>& ); //
};

Foo f({1, 2, 3}); // Ok - use initializer_list constructor
Foo f(std::vector<int>{1, 2, 3}); // Ok - use the 2nd constructor
//********************************************************************************

Quick quiz? How many types of constructors have you encounter so far?
    - default constructor
    - creation constructor
    - conversion constructor
    - copy constructor
    - move constructor
    - initializer_list constructor

Work on STL containers
Now in C++11 all STL containers have a initializer_list constructor. This means that all of them can be initialized directly via {}-list. See Example 6 how the std::vector can be easily initialized.

// Example 6: STL containers initialized via {}-list
//********************************************************************************
std::vector<int> myVec = {3, 7, 6, 5, 11};
std::vector<std::vector<int>> myVec2 = { {1, 3, 5},
                                                                {3, 7, 6, 5, 11},
                                                                {6, 4, 5, 2}};
//********************************************************************************

Let's look back the problem in Example 2 and look at how it is easily resolved in Example 6. Nicely done!!!

"Fix" most vexing parse problem
C++11 can not really wipe out this issue completely. If still written the same code as shown Example 3. The syntactic ambiguity issue will still surface. But C++11 provides an alternative to prevent this issue, which is to enable initializer-list to work on all class initialization. Therefore reduce the usage of "()", then work around this issue. This problem can be circumvented via using "{}"

// Example 7: workaround of most vexing parse problem in C++11
//********************************************************************************
Bar my_bar{Foo()};
//********************************************************************************

C++11 advises that prefer using "{}" to initialize the objects. In Example 7 it is clearly expressing the programmer's intention to create an object, because "{}" cannot be used to invoke a function and only "()" can do.

{}-list works everywhere
{}-list can be used to initialized everything now. In Example 4 default value for member variables, base class in initialization list, member variables in initialization list, objects and arrays. In Example 5 initializer_list's instantiation, initializer_list<int>. In Example 6 std::vector, one dimension and multiple-dimensions. In Example 7 object creation in constructor. More than these,
    - return type
    - work with new expression
    - function argument

// Example 8: {}-list
//********************************************************************************
struct Foo {
    Foo(int, int);
};

Foo CreateConstFooInstance() {
    return {1, 2};
}

int* intPtr = new int[4] {1, 2, 3, 4};

void Test(std::initializer_list<int>) {
    //......
}

Test({}); // Ok - empty list
Test({1, 2, 3, 4}; //Ok - 4 elements
//********************************************************************************

3. Summary
Comparing with C++03, C++11 has hugely expanded the functionality of initializer-list. C++11 has expanded initializer-list to all standard classes and STL containers. But the back-compatibility on aggregate and POD is maintained.  I think since now it becomes good practice that using {}-list to initialize variable and objects. At the same time limit the usage of "()" for variable/object initialization and use it solely for function/operator calling.

Bibliography:
[1] C++03 standard
[2] C++11 standard
[3] http://en.wikipedia.org/wiki/Most_vexing_parse
[4] http://www.stroustrup.com/C++11FAQ.html
[5] http://en.wikipedia.org/wiki/C++11
[6] [N2640=08-0150] Jason Merrill and Daveed Vandevoorde: Initializer Lists -- Alternative Mechanism and Rationale (v. 2)

Monday 2 June 2014

Plain Old Data (POD) on C++11

POD would not sound unfamiliar to you, if you are coming from C background. POD is widely used in Module-C programming, simply to mimic the C++ class feature to use POD to contain the data, implement stand-alone/global functions, and passing a pointer of POD into the function to manipulate. Another usage of POD in C is to act as the data container of data flow passing around modules. For example data to pass between DLLs or sockets.

Moving to C++ the first usage in C is replaced by C++ object oriented programming techniques. But the second usage is still valid. POD is still in use as the container of the data flow across the modules and sockets. Because C++ standard maintains the backwards compatibility towards older version of C++ standard  and C standard, anything has been valid on POD in C standard will still have to be valid in C++ standard too.

Two distinct features on POD required for the compatibility between C standard and C++ standard are,
    - Life time of POD: start when the memory allocated and end when memory released/reused
    - Memory footprint: memset/memcpy can work on it and no memory padding at the top

Example 1: features to maintain the compatibility between C standard and C++ standard
//********************************************************************************
struct Foo {
    int x;
    int y;
};

Foo foo;
memset(&foo, 0, sizeof(Foo));
int arr[2];
memcpy(&arr[0], &foo, sizeof(Foo)); // save foo
// ...... work on foo
memcpy(&foo, &arr[0], sizeof(Foo)); // recover foo
Foo* fooPtr = (Foo*) &arr[0]; // ok
assert(&foo == & foo.x) // ok
//********************************************************************************

1. POD in C++03
Anything works in C standard will still work fine on C++ standard. However C++ have extra requirements on POD, which limits the usage of C++ features on POD. For instance in Example 1 C++ compiler will generate default constructor, default copy constructor, default assignment operator and default destructor. How will these new features in C++ (comparing to C) affect the POD in order to maintain the compatibility? Some limits have to be set on the features of C++ in order to keep the compatibility.

According to C++03 standard, POD has to be aggregate (please read my other blog entry for more details,  Aggregate on C++11). And it can not have user-defined copy constructor and destructor, because its life time has nothing to do with the constructor and destructor, shown in Example 1.

So here is the list of requirements on POD in C++03
    - Must be aggregate
    - Any requirements on aggregate will apply to POD in C++03 (See Aggregate on C++11)
    - No user-defined  copy constructor and no user-defined destructor
    - Free to have user-defined assignment operator
    - Member variables must be build-in types (except reference) or any existing POD
    - Life time: the same as C POD
    - Memory footprint: the same as C POD

2. POD in C++11
There are significant changes on POD definition in C++11 comparing to the tight definition of C++03. But the compatibility is maintained backwards to C standard. In order to achieve the compatibility, the following features are still maintained in C++11,
    - I). Statically initialization at compiling time
    - II). Knowing the exact memory footprint at compiling time
    - III). Life time of POD: start when memory allocated and end when memory released/reused
    - IV). Memory footprint:  the same as C POD

C++11 has literately been moving away from the definition of  POD in C++03. In C++03 POD has to be aggregate and then extra limitation applied on it. C++11 has introduced 2  distinct features, which make more senses in programming, to define POD. (More rationals behind this move please refer to [6].) They are trivial classes and stand-layout classes. If classes (refers to class, struct and union in C++ standard) are both trivial and has a standard-layout, then they are qualified as POD.

Trivial classes
This property is to guarantee that classes can be statically initialized, and can be used directly with memset/memcpy to initialize like in C. Here is the definition of trivial classes in C++11
    - No virtual base class
    - No virtual functions
    - A trivial constructor and destructor  (not user-defined, default)
    - No non-trivial copy/move constructor (not user-defined)
    - No non-trivial copy/move assignment operator (not used-defined)
    - Can have as many as public/protected/private static variables and functions
    - Can have as many as public/protected/private non-static variables and functions
    - Hold all the properties for all its member variables recursively

Standard-layout classes
This property is to guarantee that class have the same memory footprint as C's POD. Requirements in C++11 are,
    - No virtual function
    - No virtual base class
    - All variables have the same accessibility (any of public, protected and private)
    - Can have base classes, but they have to be empty classes. (Otherwise reinterpret_cast and aliasing may not work)
    - Base classes can have static member variables only.
    - Hold all the properties for all its member variables recursively

Combine the requirements from both trivial classes and standard-layout classes.
    - No virtual function
    - No virtual base class
    - Can have base classes that are empty classes with any number of static variables
    - No user-defined creation/copy/move constructor
    - No user-defined copy/move assignment operator
    - No user-defined destructor
    - Can have explicit declaration to use any default constructor assignment operator and destructor ("default" keywords, see C++11 features - Explicitly defaulted/deleted member functions) See the motivating example in [6]
    - All non-static variables must have the same accessibility (public, protected or private) See the motivating example in [6]
    - Non-static variables do not necessarily have to have public accessibility.
    - Can have any public/protected/private static member variables
    - Can have any public/protected/private static/non-static functions
    - No reference type in non-static member variables
    - Hold all the properties in its member variables recursively

Comparing with C++03 there is a bit relaxing in POD, for instance the accessibility of non-static member variables. The main changes is the conceptional changes by introducing two new features, trivial classes and stand-layout classes.

Bibliography:
[1] C++03 Standard
[2] C++11 Standard
[3] http://www.stroustrup.com/C++11FAQ.html
[4] N2640 by Jason Merrill and Daveed Vandevoorde
[5] http://en.wikipedia.org/wiki/C++11
[6] [N2294=07-0154] Beman Dawes: POD's Revisited: Resolving Core Issue 568 (Revision 4)