C++11 Move semantics, rvalue reference

In this article we will discuss the move semantics for C++. We will try to figure out what exactly move is.

Problem Statement

Copying is not the optimal solution in all situations. Some situations demand moving as copying may mean duplication of resources and it may be a intensive task.

Another problem arises due to temporaries. These temporaries may blog memory and slow down C++ execution.

Solution

Solution comes inform of the move semantics. We will gradually discover what this is.

rvalue reference

RValues is a new addition to C++11. We will see what its purpose is and why it was implemented.

The original definition of lvalues and rvalues from  is as follows:

As per C style definition an lvalue is an expression that may appear on the left or on the right hand side of an assignment, whereas an rvalue is an expression that can only appear on the right hand side of an assignment.

  int a = 42;
  int b = 43;

  // a and b are both l-values:
  a = b; // ok
  b = a; // ok
  a = a * b; // ok

  // a * b is an rvalue:
  int c = a * b; // ok, rvalue on right hand side of assignment
  a * b = 42; // error, rvalue on left hand side of assignment

C++ with its user-defined types has introduced some subtleties regarding modifiability and assignability that cause this definition to be incorrect. So now what we tell lvalue is an expression that represents a memory location., this lvalue lets us take the address of the location. What is a rvalue? Simple, what ever is not a lvalue.

Now let us formally define these terms and properties a little better.

For first what is an expression?

  • A expression is a sequence of operators and operands. A expression is a statement that specifies a computation. It tells the computer or say C++ what to do.
  • A expression can produce a value like 1+2;// Its value is 3.
  • A expression can have side effects too like a function call.
  • A expression can be simple or complex.
  • Each expression has a type and a value category i.e. if the expression is lvalue, rvalue etc.

 lvalue

An lvalue is an expression that identifies a non-temporary object or a non-member function.

  • Address of a lvalue can be taken.
  • Modifiable i.e. non const lvalue can be used on the left side of the =
  • lvalue can be used to initialize the lvalue reference.
  • Some times when permitted lvalue can have incomplete type.

Examples:

  • The name of a variable or function in scope, regardless of type, such as std::cin or std::endl. Even if the variable’s type is rvalue reference, the expression consisting of its name is an lvalue expression.
  • Function call or overloaded operator expression if the function’s or overloaded operator’s return type is an lvalue reference, such as std::getline(std::cin, str) or std::cout << 1 or str1 = str2 or ++iter
  • Built-in pre-increment and pre-decrement, dereference, assignment and compound assignment, subscript (except on an array xvalue), member access (except for non-static non-reference members of xvalues, member enumerators, and non-static member functions), member access through pointer to data member if the left-hand operand is lvalue, comma operator if the right-hand operand is lvalue, ternary conditional if the second and third operands are lvalues.
  • Cast expression to lvalue reference type.
  • String literal
  • Function call expression if the function’s return type is rvalue reference to function type
  • Cast expression to rvalue reference to function.

prvalue

A pure rvalue (prvalue) is an expression that identifies a temporary object (or a subobject thereof) or is a value not associated with any object.

  •  It can be a rvalue
  • a prvalue cannot be polymorphic: the dynamic type of the object it identifies is always the type of the expression
  • a non-class non-array prvalue cannot be const-qualified.
  • a prvalue cannot have incomplete type (except for type void, see below)
  • The expressions obj.func and ptr->func, where func is a non-static member function, and the expressions obj.*mfp and ptr->*mfp where mfp is a pointer to member function, are classified as prvalue expressions, but they cannot be used to initialize references, as function arguments, or for any purpose at all, except as the left-hand argument of a function call expression, e.g. (pobj->*ptr)(args).
  • Function call expressions returning void, cast expressions to void, and throw-expressions are classified as prvalue expressions, but they cannot be used to initialize references or as function arguments. They can be used in some contexts (e.g. on a line of its own, as the left argument of the comma operator, etc) and in the return statement in a function returning void

Examples:

  • Literal (except string literal), such as 42 or true or nullptr.
  • Function call or overloaded operator expression if the function’s or the overloaded operator’s return type is not a reference, such as str.substr(1, 2) or str1 + str2
  • Built-in post-increment and post-decrement , arithmetic and logical operators, comparison operators, address-of operator, member access for a member enumerator, a non-static member function, or a non-static non-reference data member of an rvalue, member access through pointer to a data member of rvalue or to a non-static member function, comma operator where the right-hand operand is rvalue, ternary conditional where either second or third operands aren’t lvalues.
  • Cast expression to any type other than reference type.
  • Lambda expressions, such as [](int x){return x*x;}

xvalue

An xvalue is an expression that identifies an “eXpiring” object, that is, the object that may be moved from. The object identified by an xvalue expression may be a nameless temporary, it may be a named object in scope, or any other kind of object, but if used as a function argument, xvalue will always bind to the rvalue reference overload if available.

  • It can be either rvalue or
  • it can also be a gvalue
  • Like prvalues, xvalues bind to rvalue references
  • Unlike prvalues, an xvalue may be polymorphic, and a non-class xvalue may be cv-qualified.

Examples:

  • A function call or overloaded operator expression if the function’s or the overloaded operator’s return type is an rvalue reference to object type, such as std::move(val)
  • A cast expression to an rvalue reference to object type, such as static_cast<T&&>(val) or (T&&)val
  • a non-static class member access expression, in which the object expression is an xvalue
  • A pointer-to-member expression in which the first operand is an xvalue and the second operand is a pointer to data member.

gvalue

A glvalue (“generalized” lvalue) is an expression that is either an lvalue or an xvalue.

  • Mostly its properties are as applies to pre-C++11 lvalues
  • A glvalue may be implicitly converted to prvalue with lvalue-to-rvalue, array-to-pointer, or function-to-pointer implicit conversion.
  • A glvalue may be polymorphic: the dynamic type of the object it identifies is not necessarily the static type of the expression.

rvalue

An rvalue is an expression that is either a prvalue or an xvalue.

  • It has properties that apply to both xvalues and prvalues, which means they apply to the pre-C++11 rvalues as well
  • Address of an rvalue may not be taken: &int(), &i++[3], &42, and &std::move(val) are invalid.
  • An rvalue may be used to initialize a const lvalue reference, in which case the lifetime of the object identified by the rvalue is extended until the scope of the reference ends.
  • An rvalue may be used to initialize an rvalue reference, in which case the lifetime of the object identified by the rvalue is extended until the scope of the reference ends.
  • When used as a function argument and when two overloads of the function are available, one taking rvalue reference parameter and the other taking lvalue reference to const parameter, rvalues bind to the rvalue reference overload (thus, if both copy and move constructors are available, rvalue arguments invoke the move constructor, and likewise with copy and move assignment operators).

Moving

Lets say we have a 3D model class. The model class holds textures that are image files, vertex points that can spawn to thousands, color info for each vertex. Say like

class Vertex {
  // Members not imp
public:
  void addVertex ( /*vertex type*/ ) {

  }
  ~Vertex ( ) {
    // Destroy verted
  }
};

class Texture {
  // Members not imp
public:
  void load (/*info*/ ) {
    // Heavy duty image loading
  }
  ~Texture ( ) {
    // Destroy 
  }
};

class Model3D {
private:
  Vertex* _ver;
  Texture* _tex;
public:
  void initialize ( ) {
    _ver = new Vertex;
    _tex = new Texture;
    for ( int i = 0; i<10000; ++i ) {
      // Some more processing
      _ver->addVertex ( );
    }
    for ( int i = 0; i<500; ++i ) {
      _tex->load ( );
    }

  }
  ~Model3D ( ) {
    delete _ver;
    delete _tex;
  }
};

Model3D retGraphics ( ) {
  Model3D g;
  // Do some operation and return
  return g;
}

Model3D g1 = retGraphics ( );

Here as you can see the ThreeD model class does some heavy duty vertex and texture loading. Now take a look at the statement Model3D g1 = retGraphics ( );. This statement can be converted to following pseudo code

Model3D tempG;
Model3D retGraphics ( ) {
  Model3D g;
  // Do some operation and return
  // g will die with the scope, so copy it to a temp object
  tempG = g; // Clone the resources call Model3D::operator =( Model3D& ) on tempG 
  g->~Model3D( );
}
Model3D g1 = tempG; // Clone tempG. Call Model3D::operator =( Model3D& ) on g1
tempG->~Model3D ( );

As you see there is a temporary involved. That means the vertex and texture destruction and loading happens  2ce. This is a time consuming and unnecessary process. So now the intelligent programmer is left with writing some code that can actually do the swapping of resource, rather than let the resource get destroyed. This is again time consuming and boring work, but all have to do it increasing the source size. Won’t it be good if the language did it, hence reducing the burden from the programmer? Well C++ does exactly that with the move functionality.So it does something like

Model3D& Model3D::operator = ( <move type> rhs ) {
  //swap _ver
  //swap _tex
}

This is the reason C++ creates a overload with the move type, which is special type to tell the compiler to move the resources rather than do the delete and construct operation. With the move type in play the compiler deals with the following choice:

  • Move type must be a reference
  • when there is a choice between two overloads where one is an ordinary reference and the other is the mystery type, then rvalues must prefer the mystery type
  • lvalues must prefer the ordinary reference

So what exactly is this move type? This is the rvalue reference i.e. Model3D&&.

Model3D& is called the lvalue refernce.  So what are the properties of the rvalue reference now?

  • During function overload resolution lvalue prefer lvalue reference and rvalue prefer rvalue reference.
void f ( Model3D& m); // Lvalue reference overload.
void f ( Model3D&& m); // rvalue refernce overload.

f ( g1 ); // Here g1 is lvalue, so call void f ( Model3D& m );
f ( retGraphics ( ) ); // Here rvalue is needed. so void f ( Model3D&& m ); is called.
  • We can overload any function with rvalue. But mostly in practive the copy constructor and assignment operator.

In the next article we will look at it in more details.

Bibliography

C++ Rvalue References Explained by Thomas Becker.

Lvalues and Rvalues by Mikael Kilpeläinen

C++11 Constructors and Copy assignment – Part 2

Topics Covered

In this section we will have a look at more C++ constructors. The following will be covered:

  1. Copy Constructor
  2. Copy Assignment Operators
  3. Move Constructor

 Copy Constructor

Definition

General Definition

A non-template constructor for class X is a copy constructor if its first parameter is of type X&, const X&, volatile X& or const volatile X&, and either there are no other parameters or else all other parameters have default arguments .

Example:

class X {
public:
  X ( const X& );  // Copy Constructor
  X ( const X&, int = 1 );  // Copy Constructor
};

Here the copy constructor is public. This class is call Copy Constructible.

Saying this what happens in the following case?

class X {
public:
  X ( X& x, int i );
  X ( ) { };
};

X::X ( X& x, int i = 0) {

}

We will discuss more of these cases when we dive deeper in another article.

Like normal constructors these can also be deleted, or default.

X ( const X& ) = default; // Forcing a copy constructor to be generated by the compiler
X ( const X& ) = delete; // Avoiding implicit default constructor

Now the question is; do we always need to pass a reference in copy constructor?

Well lets see the case below:

class X {
public:
  X ( const X v);
};

// Somewhere else in code
X a;
X b = a;

Now what will happen? Here X b = a;  the code will look like b( X v = a). Now this is again a copy constructor call. This will happen like this recursively until we are out of stack space and the program will crash. So this is not allowed. This will throw up error telling this is illegal copy constructor.

A class can have multiple copy constructors, e.g.

class X {
public:
  X ( const X& );
  X ( X& );
};

A member function template is never instantiated to produce a copy constructor signature.  Like

class X {
public:
 template<typename T>
 X ( T );
 X ( );
};

X a;
void foo ( ) {
 X b ( a ); // does not instantiate the member template to produce X::X<X>(X);
}

In this case the implicitly declared copy constructor is used.

The reason being follows:

  1. The template can be instantiated to mimic a copy constructor but as per the standard statement it is not a copy constructor (If you haven’t seen the definition see again, it explicitly tells as non-templated). So this means the class doesn’t define one.
  2. The compiler now generates a copy-constructor in the right circumstance. So say the compiler also instantiates this templated code. Then when the time to choose comes, the over loading resolution chooses the non templated function rather than the templated one as it does for other functions.

Implicitly-declared copy constructor

If no user-defined copy constructors are provided for a class type the compiler will always declare a copy constructor with the following type

class X {
public:
  inline X ( const X& );  // It is public and inline
};

The const modifier is applied only if the following conditions are met:

  • All direct and virtual bases of “X” have copy constructors with references to const or to const volatile as their first parameters.
  • All non-static members of “X” have copy constructors with references to const or to const volatile as their first parameters
Some facts
  • The implicitly-defined copy constructor for a non-union class X performs a member-wise copy of its bases and members.
  • The order of initialization is the same as the order of initialization of bases and members in a user-defined constructor.
  • The implicitly-defined copy constructor for a union X copies the object representation of X.

Deleted implicitly-declared copy constructor

The implicitly-declared or defaulted copy constructor for class X is defined as deleted or in simpler pre C++11 terms undefined (the compiler cannot define them) if the following conditions are met:

  • X has non-static data members that cannot be copied (have deleted, inaccessible, or ambiguous copy constructors)
  • X has direct or virtual base class that cannot be copied (has deleted, inaccessible, or ambiguous copy constructors)
  • X has direct or virtual base class with a deleted or inaccessible destructor.

Trivial copy constructor

A trivial copy constructor is a constructor that creates a byte-wise copy of the object representation of the argument and performs no other action. Objects with trivial copy constructors can be copied by copying their object representations manually e.g. with std::memmove.  All data types compatible with the C language (POD types) are trivially copyable.

The copy constructor for class X is trivial if all of the following is true:

  • It is not user-provided (that is, it is implicitly-defined or defaulted), and if it is defaulted, its signature is the same as implicitly-defined
  • X has no virtual member functions
  • X has no virtual base classes
  • The copy constructor selected for every direct base of X is trivial
  • The copy constructor selected for every non-static class type (or array of class type) member of X is trivial

Implicitly-defined copy constructor

If the implicitly-declared copy constructor is neither deleted nor trivial, it is defined (that is, a function body is generated and compiled) by the compiler.

  • For union types, the implicitly-defined copy constructor copies the object representation (as by std::memmove).
  • For non-union class types (class and struct), the constructor performs full member-wise copy of the object’s bases and non-static members in their initialization order using direct initialization.

Usage

class X {
public:
  X ( const X& );  // Copy Constructor
};

X a;
// General initialization
X b = a; 
X b ( a );
// Function argument passing
void f ( const X v ); // Function definition
f ( a );
// Return 
void f ( ) {
  X a;
  return a;
}

If a class X only has a copy constructor with a parameter of type X&, an initializer of type const X or volatile X cannot initialize an object of type (possibly cv-qualified) X

class X {
public:
  X ( ) ; // default constructor
  X ( X& ) ; // copy constructor with a non-const parameter
};
const X a;
X b = a;  // error: X::X(X&) cannot copy a into b

 

Copy Assignment Operator

Definition

A user-declared copy assignment operator X::operator= is a non-static non-template member function of class X with exactly one parameter of type X, X&, const X&, volatile X& or const volatile X&. As with any function and constructor they can be default or deleted.

class X {
public:
  X& operator=( X );
  X& operator=( const X& );
  X& operator=( const X& ) = default;
  X& operator=( const X& ) = delete;
};

 

Chitra – A game engine from scratch using C++ and SDL – Introduction

A game engine is a software framework designed for the creation and development of video games. Video game developers use them to create games for video game consoles, mobile devices and personal computers. The core functionality typically provided by a game engine includes a rendering engine, a physics engine or collision detection, sound, scripting, animation, artificial intelligence, networking etc. This is an abstraction that brings the world we see into life.

In these tutorial series we will go through creating a game engine from some basic components. We will explore the concepts, data-structures and theory behind them. We will try to create 2D engine first and then venture into 3D.

To do so we will use the following software.

  1. Geometry

Forking out of Urho3D -> Konark

I have forked out of a excellent game engine Urho3D. I have named it as Konark (Named after a beautiful temple at Odisha – India). I wish to add some twists of my own. I will keep on updating it with some changes.

What is “Urho3D”?

Urho3D is greatly inspired by OGRE and Horde3D. There has been some additional research that has gone into it. It has the following features:

Features

Direct3D9 or OpenGL rendering (Shader Model 2, OpenGL 2.0 or OpenGL ES 2.0 required as minimum)
HLSL or GLSL shaders + caching of HLSL bytecode
Configurable rendering pipeline. Default implementations for forward, light pre-pass and deferred rendering
Component based scene model
Skeletal (with hardware skinning), vertex morph and node animation
Automatic instancing on SM3 capable hardware
Point, spot and directional lights
Shadow mapping for all light types; cascaded shadow maps for directional lights
Particle rendering
Geomipmapped terrain
Static and skinned decals
Auxiliary view rendering (reflections etc.)
Geometry, material & animation LOD
Software rasterized occlusion culling
Post-processing
HDR renderingv1.31
2D sprites and particles that integrate into the 3D scenev1.31
Task-based multithreading
Hierarchical performance profiler
Scene and object load/save in binary and XML format
Keyframe animation of object attributesnew
Background loading of resourcesnew
Keyboard, mouse, joystick and touch input (if available)
Cross-platform support using SDL 2.0 (currently runs on Windows, Linux, Mac OS X, Android, iOS, and Raspberry Piv1.3)
Physics using Bullet
2D physics using Box2Dnew
Scripting using AngelScript
Alternative script interface using Luav1.3 or LuaJITv1.31 (on Windows, Linux, Mac OS X, Android, and Raspberry Pi)
Networking using kNet + possibility to make HTTP requestsv1.3
Pathfinding using Recast/Detourv1.23
Image loading using stb_image + DDS / KTX / PVR compressed texture support
2D and “3D” audio playback, Ogg Vorbis support using stb_vorbis + WAV format support
TrueType font rendering using FreeType, AngelCode bitmap fonts are also supported
Unicode string support
Inbuilt UI system
Scene editor and UI-layout editor implemented in script with undo & redo capabilities
Model/scene/animation/material import from formats supported by Open Asset Import Library
Alternative model/animation import from OGRE mesh.xml and skeleton.xml files
Supported build tools and IDEs: Visual Studio, Xcode, Eclipse, CodeBlocks, GCC, LLVM/Clang, MinGW-W64
Supports both 32-bit and 64-bitv1.3 build
Build as single external library v1.3 (can be linked against statically or dynamically)

 

I wish to add boost geometry support and all the matrix and vector calculations will be using GLM(OpenGL Mathematics).

 

C++11 Constructors

What is a Constructor

Construction is an important part of the object creation. Unlike the ‘malloc’  function in C which just gets the system memory and returns the handle to it, the ‘new’ operator does more things. Constructors are also invoked when the object is declared. This means constructors are used with both stack-based and heap-based allocation. It is this construction phase which brings life to just allocated chunk of memory. In this article we will discuss briefly the different constructs for construction available in C++11.

As per the C++ reference Constructor is a special member function. Constructors do not have names.  A declaration of a constructor uses a function declarator of the for:

ptr-declarator ( parameter-declaration-clause ) exception-specification-opt attribute-specifier-seqopt

It means syntactically, a constructor is specified by a method name that is the same as the class name.

A constructor is used to initialize objects of its class type. Because constructors do not have names, they are never found during name look-up. A constructor can be invoked for a const, volatile or const volatile object. const and volatile semantics are not applied on an object under construction. They come into effect when the constructor for the most derived object ends. Following is the ‘order of construction’:

  1. It calls base class and member constructors in the order of declaration.
  2. If the class is derived from virtual base classes, it initializes the object’s virtual base pointers.
  3. If the class has or inherits virtual functions, it initializes the object’s virtual function pointers. Virtual function pointers point to the class’s virtual function table to enable correct binding of virtual function calls to code.
  4. It executes any code in its function body.

A constructor never has a return type and may or may not have parameters.  A constructor with no parameters is called the default constructor.

As of C++11 the default constructors have the following syntax:


ClassName ( ) ;  //  Declaration of a default constructor
ClassName :: ClassName ( ) {/*body*/} // Definition of the constructor outside the class body
ClassName() = delete ; //  Inhibiting the automatic generation of a default constructor (since C++11)
ClassName() = default ; // Explicitly forcing the automatic generation of a default constructor  (since C++11)


 

Default Constructor

Default constructor for a class X is a constructor of class X that can be called without an argument.  What this means is that the default constructor can have no arguments or all arguments should have a default value. There are many contexts in which you may have to provide a default constructor for a class or else the compiler will throw errors. But why is a default constructor needed?

Lets take the example of the class X

class X{int _i; X(int i){}};

now lets say we need 10 stack objects i.e. an array:

X x[10];

Here the C++ implementation wont know what to specify the default values. The compiler will throw error.

So what is happening here? Why is the error coming.

If no user-defined constructor exists for a class X and one is needed, the compiler implicitly declares a default parameter-less constructor for X i.e. ‘X::X()’.

Default constructor is also needed when you want to initialize your object with ‘STL’.

Even try to compile the following code :

class X{

const int _i;

}; // This will not compile as const is not given a value.

class Y{

int &_iref;

}; // The Ref holds no value so this will also not compile.


 

Additions in C++11

  • C++11 Explicitly Defaulted Constructors

In pre C++11 versions if your class required a number of explicit constructors accepting arguments but also a default constructor that does nothing, you had to explicitly write your empty default constructor as follows:

class X{

int _i;

public:

X(){/*Nothing inside*/} // You have to explcitly write it with a null body.

X(int i);

}

In this case if ‘X(int i)’ is defined then compiler will not generate any default constructor. To avoid having to write empty default constructors manually, C++11 introduces the concept of ‘explicitly defaulted constructors’. This allows you to write the class definition as follows without the need to implement it in the implementation file.

class X{

int _i;

public:

X() = default;

X(int i);

}
  • C++11 Explicitly Deleted Constructors

We can define a class for which we do not want to write any constructors and we also do not want the compiler to generate the default constructor. In that case we need to explicitly ‘delete‘ the default constructor. Deleted constructors also give us simple language to prevent problematic type promotions from occurring in arguments to functions.

class X{

int _i;

public:

X() = delete;

}

 

We will take a more closer look at the C++ initializers and copy constructor in the next blog.

Inside C++ – Class, Struct and Objects

In this chapter we will deal with class, structures and objects.

So class or struct is the keywords we use to create a class in C++. The class can hold static, non static member variables. Class can contain static, non static and virtual member functions. To have a detailed look at all the possible representations of the class members please refer Inside the C++ object model. We will not go through them all. We will only discuss what the current trends are (The trend in Clang).

Lets take an example:


class Point{
private:
float _x;
float _y;
//static int _pointCount;
public:
Point(){_x = 0; _y = 0;}
Point(const float x, const float y):_x(x), _y(y){/*++_pointCount;*/}
float x() const{ return _x;}
float y() const{ return _y;}
float x() { return _x;}
float y() { return _y;}
//virtual float pointOps(){float ret = _x+_y; return ret;}
//static int pointCount(){return _pointCount;}
};

//int Point::_pointCount = 0;

int main(){
Point p;
return 1;
}

The assembly generate is as below. Based on your clang setting you can get more or less code in your ll file. I have removed all the code that do not pertain to our discussion at hand or that do not add any value to our discussion. For example  we will ignore “#0″. This is basically attribute. A group of attributes is referenced with a “#<Number>”.


%class.Point = type { float, float }

define i32 @main() {
entry:
%p = alloca %class.Point, align 4
call x86_thiscallcc void @_ZN5PointC2Ev(%class.Point* %p)
ret i32 1
}

; Function Attrs: nounwind
define linkonce_odr x86_thiscallcc void @_ZN5PointC2Ev(%class.Point* %this) unnamed_addr #1 align 2 {
entry:
%this.addr = alloca %class.Point*, align 4
store %class.Point* %this, %class.Point** %this.addr, align 4
%this1 = load %class.Point** %this.addr
%_x = getelementptr inbounds %class.Point* %this1, i32 0, i32 0
store float 0.000000e+00, float* %_x, align 4
%_y = getelementptr inbounds %class.Point* %this1, i32 0, i32 1
store float 0.000000e+00, float* %_y, align 4
ret void
}

Let us dissect the above assembly one by one.

Line 1 is the way LLVM assembly represents data collection. The structure type is used to represent a collection of data members together in memory. The elements of a structure may be any type that has a size.

Example:

%T1 = type { <type list> }

Similarly in our example the  class A; is %class.Point = type { float, float }

Now going to the “main” function. As you can guess the “align” specifier is used to specify alignment. Below is the main code commented. In llvm the comments are starting with a “;”.


define i32 @main() #0 {
entry:
%p = alloca %class.Point, align 4 ; Allocate memory for our class Point instance

call x86_thiscallcc void @_ZN5PointC2Ev(%class.Point* %p) ; Constructor call. The name is mangled.

ret i32 1
}

Here in the code we see the constructor as a different function. So how does it know about the object members?

Well this is the job of the this pointer which is passed to the constructor as given below

@_ZN5PointC2Ev(%class.Point* %this) //The this pointer passed to the class

Now why is the constructor call a must? Lets see inside the constructor:

  1. We allocate memory to store a pointer by %this.addr = alloca %class.Point*, align 4.
  2. The “store” instruction has the format “store type value, type* destination address”. So store %class.Point* %this, %class.Point** %this.addr, align 4.
  3. The argument to the “load" instruction specifies the memory address from which to load. So %this1 = load %class.Point** %this.addr. Loads the content pointed to by %this.addr on this1. This is basically the this pointer.
  4. The ‘getelementptr‘ instruction is used to get the address of a subelement of an aggregate data structure. It performs address calculation only and does not access memory. So %_x = getelementptr inbounds %class.Point* %this1, i32 0, i32 0 fetches the address of the “_x”.
  5. Now store float 0.000000e+00, float* %_x, align 4 will store the 0 float value in this element.

 

Empty class / struct

Empty class or structures are structures without any members or member functions. So what happens when we have these kind of constructs? Is there any memory allocated for them? If yes then why? Lets explore this concept.
Consider generating the AST for the below 2 constructs

// test.cpp - input
struct emptyS{};
class emptyC{};
// AST generated by the command
// "clang.exe -S -emit-llvm  -fcolor-diagnostics -Xclang -ast-dump test.cpp"
TranslationUnitDecl
|-TypedefDecl implicit __builtin_va_list 'char *'
|-CXXRecordDecl <test.cpp:1:1, col:15> col:8 struct emptyS definition
| `-CXXRecordDecl <col:1, col:8> col:8 implicit struct emptyS
`-CXXRecordDecl <line:2:1, col:14> col:7 class emptyC definition
`-CXXRecordDecl <col:1, col:7> col:7 implicit class emptyC

From the above code we observe that the test.cpp is the translation unit.
We have a definition of the class as “CXXRecordDecl <line:2:1, col:14> col:7 class emptyC definition”
the 2nd CXXRecordDecl is a implicit class name inserted into the C++ class namespace as described by C++ standard.
Now lets generate the IR for this.


// Input test.cpp

struct emptyS{};
class emptyC{};

int main(){
emptyS s;
emptyC c;
return 1;
}

// Output test.ll

%struct.emptyS = type { i8 }  // Non zero size
%class.emptyC = type { i8 }   // Non zero size

; Function Attrs: nounwind
define i32 @main() {
entry:
%retval = alloca i32, align 4
%s = alloca %struct.emptyS, align 1 // 1 Byte aligned
%c = alloca %class.emptyC, align 1 // 1 byte aligned
store i32 0, i32* %retval
ret i32 1
}

Now though the class and struct have no data members still their size is non zero.

Reason: It is nonzero to ensure that the two different objects will have different addresses. When we allocate memory for them then

%s = alloca 0 and %c = alloca 0 will point to the same memory location.

 

Union

A union is a class defined with the class-key union; it holds only one data member at a time. class-key here means the key words class/struct/union.

Now lets see how the memory layout of a a union looks like. Comments are inline. Based on your machine you can get different sizeof values. Here we see that the double is having largest size. So the union contains double only.

// ===Input===
typedef void (*FunPtrType)(void);
union U{
int _i;
float _f;
char _c;
double _d;
void* _p;
FunPtrType _fp;
};

int main(){
int sizeInt = sizeof(int);
int sizefloat = sizeof(float);
int sizeChar = sizeof(char);
int sizeDouble = sizeof(double);
int sizeV = sizeof(void*);
int sizeFP = sizeof(FunPtrType);

U u;
return 1;
}
// ===Output===
// Command "c:\program files\LLVM\bin\clang.exe" -S test.cpp -emit-llvm  -fcolor-diagnostics
%union.U = type { double } // From below we can see that the size of double is 8, which is the largest

; Function Attrs: nounwind
define i32 @main() #0 {
entry:
%retval = alloca i32, align 4

// Allocate size for sizeof variables
%sizeInt = alloca i32, align 4
%sizefloat = alloca i32, align 4
%sizeChar = alloca i32, align 4
%sizeDouble = alloca i32, align 4
%sizeV = alloca i32, align 4
%sizeFP = alloca i32, align 4

// Allocate size for union
%u = alloca %union.U, align 8
store i32 0, i32* %retval

// store <type> <value>, <dest address>
store i32 4, i32* %sizeInt, align 4 // size only 4
store i32 4, i32* %sizefloat, align 4 // size only 4
store i32 1, i32* %sizeChar, align 4 // size only 1
store i32 8, i32* %sizeDouble, align 4 // Largest size 8 ========
store i32 4, i32* %sizeV, align 4 // size only 4
store i32 4, i32* %sizeFP, align 4 // size only 4
ret i32 1
}

Bibliography:

  1. Name mangling in Itanium.

Index

<Previous

Tutorial on Statistics, probability and data analysis using R – Introduction

R is an extremely useful statistics programming language and environment that is Open Source and available for all mainstream operating systems. The strength of R lies in its inbuilt statistics processing and user contributed libraries. It has a strong community and support. Another strong point of R is its plotting capability.

It is also even used in big organizations for data analysis. In these series of articles we will explore R and we will try to do some data analysis.

To get a better introduction at R see the Wikipedia article. The article from R group. We will use online R platform primarily to do go through the tutorials. Another good R tutorial is Code School. I will not be going through the basics of R as Code School is a nice one. I will start with basic statistics and probability. Later we will use data analysis. I will use R Fiddle to test and share results. So lets start. Try it on R Fiddle and check. It will be better to complete it and then we come here for more.