All notes
Cpp

Related notes

C/C++ 网络服务器编程 1、常见服务器编程模型 1.1:多进程:简单讲解 UNIX 下创建多进程的方式 1.2:多线程:详细介绍线程池的设计原理及设计细节 1.3:非阻塞:详细介绍 reactor 及 proactor 模型的设计 1.4:协程(新模型):详细介绍网络协议的设计原理及应用场景 2、常见网络通信协议 2.1、HTTP协议:详细介绍 2.2、SMTP协议:简单介绍 2.3、POP协议:简单介绍 2.4、memcached协议:简单介绍 2.5、redis协议:详细介绍 2.6、beanstalk协议:简单介绍 2.7、handler-socket协议:简单介绍 3、使用 acl 框架编程实战 3.1、基础网络通信库的使用 3.2、非阻塞网络通信库的使用 3.3、常见网络协议库的使用 3.3.1、HTTP 协议库的使用:客户端模式、服务端模式 3.3.2、Redis 协议库的使用 3.3.3、beanstalk 协议库的使用 3.3.4、mysql 客户端库的使用 3.3.4、json/xml 库的使用 3.4、网络服务器开发 3.4.1、acl服务器框架介绍 3.4.2、多进程、多线程编程模型实战 3.4.3、高并发非阻塞编程模型实战 3.4.4、高并发协程编程模型实战

TemplateFiles

Header


#pragma once
#ifndef myExample_h
#define myExample_h

class myExample
{
public:
	struct SSomething
	{};
};
#endif

Effective C++

Design Patterns

Singleton

Microsoft MSDN.


// Declaration
class Singleton {
public: 
    static Singleton* Instance();
protected: 
    Singleton();
private:
    static Singleton* _instance;
}

// Implementation 
Singleton* Singleton::_instance = 0;

Singleton* Singleton::Instance() {
    if (_instance == 0) {
        _instance = new Singleton;
    }
    return _instance;
}

extern "c"

What is the aim for extern "c"? Shortly, it tells CPP compiler to compile for C-linkage instead of CPP-linkage, so that the client c codes can link to the compiled binary. http://stackoverflow.com/questions/1041866/in-c-source-what-is-the-effect-of-extern-c.

It usually appears in the header files which are to be included by both CPP compiler and C compiler at the same time. As an example,

#ifdef __cplusplus
extern "c" {
#endif

void iAmAFunc();

#ifdef __cplusplus
}
#endif

Calculate file size

Note that the file, no matter whether it is a text file or not, must be opened in binary mode. Reference on cplusplus.com.

using namespace std;
// Must be opened in binary mode.
ifstream is ("test.txt", ifstream::binary);
if (is) {
	// get length of file:
	is.seekg (0, is.end);
	int length = is.tellg();
}

List directory files in POXIS

GNU.org.

#include <dirent.h>
int main (void)
{
	DIR *dp;
	struct dirent *ep;

	dp = opendir ("./");
	if (dp != NULL) {
		while (ep = readdir (dp))
			cout<< (ep->d_name)<<endl;
		(void) closedir (dp);
	}
	else
		perror ("Couldn't open the directory");

	return 0;
}

Deep copy in assignment operator and copy constructor

LearnCPP: Shallow vs Deep copying. Deep copy means: allocating memory for array rather than simply copying the pointer.


// Copy constructor
MyString::MyString(const MyString& cSource)
{
    // m_pchString is a pointer, so we need to deep copy it if it is non-null
    m_nLength = cSource.m_nLength;
    if (cSource.m_pchString)
    {
        m_pchString = new char[m_nLength];
        strncpy(m_pchString, cSource.m_pchString, m_nLength);
    }
    else
        m_pchString = 0;
}

// Assignment operator
MyString& MyString::operator=(const MyString& cSource)
{
    // 1. check for self-assignment
    if (this == &cSource) return *this;
 
    // 2. first we need to deallocate any value that this string is holding!
    delete[] m_pchString;

    // 3. now we need to deep copy m_pchString 
    m_nLength = cSource.m_nLength;
    if (cSource.m_pchString)
    {
        m_pchString = new char[m_nLength];
        strncpy(m_pchString, cSource.m_pchString, m_nLength);
    }
    else {
        m_pchString = 0;
    }
 
    return *this;
}

Basics

Type cast

C-style cast

Problems:

Static_cast

Type check in compilation phase.

A static_cast is usually safe. There is a valid conversion in the language, or an appropriate constructor that makes it possible.

The only time it's a bit risky is when you cast down to an inherited class; you must make sure that the object is a actually the descendant that you claim it is, by means external to the language (like a flag in the object).

Compared to dynamic_cast

Usually one shouldn't use static_cast for casting down an inheritance hierarchy, but rather dynamic_cast. That will return either the null pointer or a valid pointer.

Sometimes you do know that a pointer points to a given subtype, then use static_cast, cause it is faster than dynamic_cast.

dynamic_cast requires optional compiler support and runtime cost (enabling RTTI), and you might not want to enable it just for a couple of checks you can do yourself. C++'s RTTI is only one possible solution to the problem.

Dynamic_cast

A dynamic_cast() is safe as long as the result is checked (pointer) or a possible exception is taken into account (reference).

Reinterpret_cast, Const_cast

A reinterpret_cast() (or a const_cast()) on the other hand is always dangerous. You tell the compiler: "trust me: I know this doesn't look like a foo (this looks as if it isn't mutable), but it is".

What is the output?


#include <iostream> 
using namespace std; 
int main(void) 
{ 
    const int a = 10; 
    int * p = (int *)(&a); 
    *p = 20; 
    cout<<"a = "<<a<<", *p = "<<*p<<endl; 
    return 0; 
}

a = 10, *p = 20

Explanation: Compiler replaces all "a" with 10 in compilation phase. And in the runtime, "p" changes the value. Thus they are different.

Examples

Derived casts


class CMyClass : public CMyBase {...};
class CMyOtherStuff {...} ;

CMyBase  *pSomething; // filled somewhere

CMyClass *pMyObject;
pMyObject = static_cast<CMyClass*>(pSomething); // Safe; as long as we checked

pMyObject = (CMyClass*)(pSomething); // Same as static_cast<>. Safe, as long as we checked but harder to read.

CMyOtherStuff *pOther;
pOther = static_cast<CMyOtherStuff*>(pSomething); // Compiler error: Can't convert

pOther = (CMyOtherStuff*)(pSomething);            // No compiler error. Same as reinterpret_cast<> and it's wrong!!!

Exceptions

No throw destructors

some reasons not to allow your destructors to throw:

Callback

Rich Hickey introduced the bound pointer in 1994. I think boost::bind() has the same effect.

CodeGuru provides a method. Another suggested a functor - a function object:


class CMyTimer
{
public:
	void MethodTick( int Id, Callback & timerNotify){ timerNotify(Id); }
	void SetTimer(int iInterval);
};

class Callback
{
public: 
    int operator() (int Id) { ...;} 
};

int main ()
{
  Callback timerNotify;
  CMyTimer theTimer;

  theTimer.SetTimer(1234);
  theTimer.MethodTick(Id, timerNotify);
}

Type safety

Stackoverflow.

I was reading about c++ vectors and it was mentioned that memcpy and printf functions from C are not type safe.

Type safety means that the compiler can check whether you're using the right types. For example, if you're using printf, you could accidentally crash your program by writing this:
	printf("The meaning of life is %s", 42);
because 42 is an integer, not a string.

Enum


enum class Color { RED, GREEN=20, BLUE};
Color r = Color::BLUE;
switch(r) {
    case Color::RED : std::cout << "red\n"; break;
    case Color::GREEN : std::cout << "green\n"; break;
    case Color::BLUE : std::cout << "blue\n"; break;
}
// int n = r; // error: no scoped enum to int conversion
int n = static_cast<int>(r); // OK, n = 21

Bits

Use bits as options/flags

Ref. C Bitwise Operators


// Toggling a bit, e.g. set 1-bit to 0, and 0-bit to 1.
x ^= mask;

// Turn off, e.g. setting a bit to zero
x &= (~mask);

// Turn on.
x |= mask;
Common flags used as options/flags
Binary		Hexadecimal	Decimal
0000 0000	0x00	0
0000 0001	0x01	1
0000 0010	0x02	2
0000 0100	0x04	4
0000 1000	0x08	8
0001 0000	0x10	16
0010 0000	0x20	32
0100 0000	0x40	64
1000 0000	0x80	128

An example:


// the flag definitions
#define CAR_LOCKED    0x01  // 0000 0001
#define CAR_PARKED    0x02  // 0000 0010
#define CAR_RESET     0x00  // 0000 0000

// macros to manipulate the flags
#define RESET_CAR(x)     (x = CAR_RESET)

#define SET_LOCKED(x)    (x |= CAR_LOCKED)
#define SET_PARKED(x)    (x |= CAR_PARKED)

#define UNSET_LOCKED(x)  (x &= (~CAR_LOCKED))
#define UNSET_PARKED(x)  (x &= (~CAR_PARKED))

#define TOGGLE_LOCKED(x)  (x ^= CAR_LOCKED)
#define TOGGLE_PARKED(x)  (x ^= CAR_PARKED)

// these evaluate to non-zero if the flag is set
#define IS_LOCKED(x)      (x & CAR_LOCKED)
#define IS_PARKED(x)      (x & CAR_PARKED)

Function pointer

Ref. A function pointer is a variable that stores the address of a function. It can be used as function argument or Callback functions.


// Definition
void (*pfoo)(int, int);

// Initializing
void foo(int,int){};
pfoo = foo;
// or
pfoo = &foo;

// Invoking
int arg1, arg2;
pfoo( arg1, arg2 );
// or
(*pfoo)( arg1, arg2 );

// Wild examples.
// compar specifies how to sort.
void qsort(void *base, size_t nmemb, size_t size, int(*compar)(const void *, const void *));
// Callback.
void create_button(int x, int y, const char *text, function callback_func);

// Function pointer to a class static function.
void (T::*func)(void);

Using Virtual Functions Instead of Function Pointers (C++)


#include <stdlib.h>

int int_sorter( const void *first_arg, const void *second_arg )
{
	int first = *(int*)first_arg;
	int second = *(int*)second_arg;
	if ( first < second )
		return -1;
	else if ( first == second )
		return 0;
	else
		return 1;
}

int main()
{
	int array[10];
	int i;
	/* fill array */
	for ( i = 0; i < 10; ++i )
		array[ i ] = 10 - i;
	qsort( array, 10 , sizeof( int ), int_sorter );
	for ( i = 0; i < 10; ++i )
		printf ( "%d
" ,array[ i ] );
}

// Virtual function.
class Sorter
{
public:
	virtual int compare (const void *first, const void *second);
};

// cpp_qsort, a qsort using C++ features like virtual functions
void cpp_qsort(void *base, size_t nmemb, size_t size, Sorter *compar);

By the way, in C++11, lambda function is also a replacement for function pointers.

Typedef function pointers

http://stackoverflow.com/questions/11038430/how-to-create-a-typedef-for-function-pointers.


int foo(int i){ return i + 1;}

// Typedef a function pointer.
typedef int (*g)(int);

// Define function-pointer variable, and initialise.
g func = &foo;

// Call function through pointer
int hvar = func(3);

// Reference.
// The signal() function from the C standard:
extern void (*signal(int, void(*)(int)))(int);
// It is the same as:
typedef void (*SignalHandler)(int signum);
extern SignalHandler signal(int signum, SignalHandler handler);

Macro

Unique

__COUNTER__

Ref.

stringizing #, Concatenation / token pasting ##

Ref.


struct command
{
  char *name;
  void (*function) (void);
};

struct command commands[] =
{
  { "quit", quit_command },
  { "help", help_command },
  ...
};

// Use token pasting macro.
#define COMMAND(NAME)  { #NAME, NAME ## _command }
struct command commands[] =
{
  COMMAND (quit),
  COMMAND (help),
  ...
};

#define type i##nt
type a; // same as int a; since i##nt pastes together to "int"

Object Oriented Programming (OOP)

Principles

See UML notes for inheritance/generalization, association, aggregation, composition, etc.

Polymorphism

Virtual function

Virtual function
when called, is resolved to the most derived version of the function available with the same signature.
Polymorphism
is named after the capability of virtual functions in C++.

See LearnCPP for reference.

The downside for virtual function is, it usually runs slowlier than normal functions.

Dynamic linkage

TutorialsPoint: cpp polymorphism. Without the advent of virtual functions, the functions to be called are determined at compilation, known as static linkage or early binding. Virtual functions bring us dynamic linkage and late binding.


#include <iostream>
class Base
{
  public:
    [virtual] const char* getName() { return "Base"; }
};

class Derived: public Base
{
  public:
    [virtual] const char* getName() { return "Derived"; }
};

int main(int argc, char **argv)
{
  Derived derived;
  Base &rBase = derived;
  std::cout<<"rBase is a "<<rBase.getName()<<std::endl;
  return 0;
}

// Cases without virtual.
// Output:
//   rBase is a Base.
// Reason: rBase refers to a class of Base.

// After adding "virtual" to both the getName().
// Output:
//   rBase is a Derived.
// Reason: virtual function is resolved to the most derived version of the function available.

Old-school: function pointers

LearnCPP: early binding and late binding.


#include <iostream>
using namespace std;
 
int Add(int nX, int nY)
{
    return nX + nY;
}
 
int Subtract(int nX, int nY)
{
    return nX - nY;
}
 
int Multiply(int nX, int nY)
{
    return nX * nY;
}
 
int main()
{
    int nX;
    cout << "Enter a number: ";
    cin >> nX;
 
    int nY;
    cout << "Enter another number: ";
    cin >> nY;
 
    int nOperation;
    do
    {
        cout << "Enter an operation (0=add, 1=subtract, 2=multiply): ";
        cin >> nOperation;
    } while (nOperation < 0 || nOperation > 2);
 
    // Create a function pointer named pFcn (yes, the syntax is ugly)
    int (*pFcn)(int, int);
 
    // Set pFcn to point to the function the user chose
    switch (nOperation)
    {
        case 0: pFcn = Add; break;
        case 1: pFcn = Subtract; break;
        case 2: pFcn = Multiply; break;
    }
 
    // Call the function that pFcn is pointing to with nX and nY as parameters
    cout << "The answer is: " << pFcn(nX, nY) << endl;
 
    return 0;
}

The virtual table, vtable

For detail in vtable and vfptr, see programming.note.

"Virtual" keyword on derived functions

Virtual functions must have same signature


class Base
{
public:
  virtual int getVal() { return 1; }
};

class Derived: public Base
{
public:
  virtual float getVal() { return 0.01; }
};

// Polymorphism will not work!
// Clang even raises an error when compiling.

Derived class as return type/argument is allowed in polymorphism


class Base
{
public:
  virtual Base* getThis() { return this; }
}

class Derived
{
public:
  virtual Derived* getThis() { return this; }
}

// Polymorphism works!

Pure virtual functions, abstract base class, interface

LearnCPP: pure virtual function, abstract base classes and interface classes.


class Base
{
public:
  virtual int getVal()=0;
};
Abstract base class
A base class with more than one pure virtual member function is abstract base class.
It can't be instantiated. Therefore, we don't need to make its constructor protected any longer.
Thus, pure virtual function is also called abstract function.
Interface class
A class has only pure virtual functions is Interface class. E.g. no member variables.
Because it has no data and no function bodies, traditional problems are avoided in multiple inheritance.
Interface class belongs to Abstract base class.

Virtual destructors

Virtual destructors are useful in that you can delete an instance of a derived class through a pointer to base class.


class Base 
{
    virtual ~Base(){}
};

class Derived : public Base
{
    ~Derived() {}
}

Base *b = new Derived();
delete b; // ~Derived() is called!

#include <iostream>
class Base
{
public:
  ~Base() { std::cout<<"~Base()"<<std::endl; }
};

class Derived: public Base
{
private:
  int * m_pnArray;
public:
  Derived(int n)
  {
    m_pnArray = new int[n];
  }
  ~Derived()
  {
    std::cout<<"~Derived()"<<std::endl;
    delete[] m_pnArray;
  }
};

int main()
{
  Derived *pD = new Derived(10);
  Base *pB = pD;
  delete pB;  // Here memory leak happens.
  return 0;
}
// Output:
// ~Base()

// After declaring "virtual ~Base()"
// Output:
// ~Derived()
// ~Base()
"If you want to prevent the deletion of an instance through a base class pointer, you can make the base class destuctor protected and nonvirtual; by doing so, the compiler won't let you call delete on a base class pointer."

When not using virtual destructor

StackExchange.

Having a virtual destructor if your class is meant to be used as a base class.

Why a pure virtual destructor needs an implementation?

StackOverflow.


class Base
{
public:
    Base(){}
    virtual ~Base() = 0;
};

class Derived : public Base
{
};

The compiler tries to build the virtual table given a virtual (pure or not) destructor, and it complains because it can't find the implementation.

virtual destructors differ from other virtual functions because they are called when the object is destroyed, regardless of whether it was implemented or not. This requires the compiler to add it to the vf table, even if it's not called explicitly, because the derived class destructor needs it.

Pedantically, the standard requires a pure virtual destructor to be implemented.

Why no virtual constructor

StackOverflow.

From Bjarne Stroustrup's C++ Style and Technique FAQ Why don't we have virtual constructors?

A virtual call is a mechanism to get work done given partial information. In particular, "virtual" allows us to call a function knowing only any interfaces and not the exact type of the object. To create an object you need complete information. In particular, you need to know the exact type of what you want to create. Consequently, a "call to a constructor" cannot be virtual.

Inheritance

Multiple inheritance

LearnCPP: multiple inheritance.

Problems incurred:

Should we avoid multiple inheritance?

Example: ambiguous function calling


#include <iostream>
class A1
{
public:
  const char* talk() { return "A1"; }
};

class A2
{
public:
  const char* talk() { return "A2"; }
};

class B: public A1, public A2
{
};

int main()
{
  B b;
  // This incurs compilation error - member 'talk' found in multiple base classes of different types:
  // std::cout<<b.talk()<<std::endl;

  // Output: A1
  std::cout<<b.A1::talk()<<std::endl;
  // Output: A2
  std::cout<<b.A2::talk()<<std::endl;
  return 0;
}

Virtual base classes

LearnCPP: virtual base classes.

Example: Diamond problem and solution


#include <iostream>
class PoweredDevice
{
public:
  PoweredDevice(int nPower) { std::cout<<"Powered Device: "<<nPower<<std::endl; }
};

class Scanner: public PoweredDevice
{
public:
  Scanner(int nScanner, int nPower)
    : PoweredDevice(nPower)
  { std::cout<<"Scanner: "<<nScanner<<std::endl; }
};

class Printer: public PoweredDevice
{
public:
  Printer(int nPrinter, int nPower)
    : PoweredDevice(nPower)
  { std::cout<<"Printer: "<<nPrinter<<std::endl; }
};

class Copier: public Printer, public Scanner
{
public:
  Copier(int nScanner, int nPrinter, int nPower)
    : Scanner(nScanner, nPower), Printer(nPrinter, nPower)
  {}
};

int main()
{
  Copier cpier(3, 2, 1);
  return 0;
}

// Output:
// Powered Device: 1
// Printer: 2
// Powered Device: 1
// Scanner: 3
// Conclusion: Copier has two copies of PoweredDevice base.

// Because the inheritance diagram is:
// PoweredDevice       PoweredDevice
//   ^                     ^
//   |                     |
// Scanner             Printer
//   ^                     ^
//   |                     |
//   +-------- Copier -----+

The solution is add "virtual" as follows:


// NOTE 1: add "virtual" here.
class Scanner: virtual public PoweredDevice
{
};
class Printer: virtual public PoweredDevice
{
};

class Copier: public Scanner, public Printer
{
public:
  Copier(int nScanner, int nPrinter, int nPower)
    // NOTE 2: Copier must take charge and explicitly initialize the base class "PoweredDevice".
    : Scanner(nScanner, nPower), Printer(nPrinter, nPower), PoweredDevice(nPower)
  {}
};

// Output:
// Powered Device: 1
// Printer: 2
// Scanner: 3
// Conclusion: PoweredDevice is initialized once and in the very beginning.

// Because the inheritance diagram is now:
//   +--> PoweredDevice <--+
//   |                     |
//   |                     |
// Scanner             Printer
//   ^                     ^
//   |                     |
//   +-------- Copier -----+

Constructors and Destructors

Explicit constructor

Constructors with only one parameter could be used implicitly to convert a parameter type to matched type. Example:


class OFString
{
public:
	OFString(const char* s);
}

int main(int argc, char **argv)
{
	DcmSCU scu;
	// set AE titles
	// setAETitle(const OFString& str);
	// Here an implicit conversion happens.
	scu.setAETitle("mySCU");
}

If we want to prevent this from happening, add explicit before the constructor.


class OFString
{
public:
	explicit OFString(const char* s);
}

int main(int argc, char **argv)
{
	DcmSCU scu;
	// set AE titles
	// setAETitle(const OFString& str);
	// Here we have to explicitly convert.
	scu.setAETitle(OFString("mySCU"));
}

Multi-arg ctors with default params can also act as single arg ctor. Reference.

Default constructors

StackOverflow.

A default constructor is one that can be invoked without any arguments.

If there is no user-declared constructor for a class, and if the class doesn't contain const or reference data members, C++ implicitly declares a default constructor for it.

GradeStack.

Default constructors vs copy constructors

GeeksForGeeks: does compiler always create a copy constructor.

Compiler created default constructor has empty body.
Unlike default constructor, body of compiler created copy constructor is not empty, it copies all data members of passed object to the object which is being created.

Compiler doesn’t create a default constructor if we write any constructor even if it is copy constructor.
Reverse is not true. Compiler creates a copy constructor if we don’t write our own, even if we have written other constructors in class.

So we need to write copy constructor only when we have pointers or run time allocation of resource like file handle, a network connection.

Execution orders

Single inheritance:

Class II: public I
I()
II()

Multiple inheritance:

Class III: public I, II
I()
II()
III()

Class III: public I, virtual II
II()
I()
III()

MultiLevel inheritance:
class II: public I {};
class III: public II {};
I()
II()
III()

Other rules:

Constructors and Destructors are inherited?

StackOverflow.

No, they are not inherited since the base/derived have different names for their con/des-tructors.

But the inheritance gaurantee the execution order: base constructors first, and derived destructors first, in an FILO manner.

Common functions

Operator precedence

Precedence table.

C style (type) cast has lower precedence than type() cast. The latter has the same precedence as postfix operator, while the previous has same precedence as prefix operator.


// Compile error.
(ofstream*)(itr->second)->close(); // ostream has no close. 
// Correct.
((ofstream*)(itr->second))->close(); // ostream has no close. 

C++

unique_ptr

Shared_ptr


template< class T, class... Args >
shared_ptr<T> make_shared( Args&&... args );

#include <iostream>
#include <memory>
 
void foo(const std::shared_ptr<int>& i)
{
    (*i)++;
}
 
int main()
{
    auto sp = std::make_shared<int>(12);
    foo(sp);
    std::cout << *sp << std::endl;
}

Shared, weak, unique pointers

Stackoverflow.

A weak_ptr is technically a means to hang on to the reference counter of a set of shared_ptrs that manage some shared object. When the last shared_ptr is destroyed the object is destroyed, but its reference counter lives on as long as there are weak_ptrs to it. Thus via any still exising weak_ptr you can check whether the object still exists, or has been destroyed.

If it still exists then from the weak_ptr you can obtain a shared_ptr that lets you reference the object.

The main usage of this is to break cycles.

In particular, an object can contain a weak_ptr holding on to its own reference counter, which allows you to obtain a shared_ptr to the object from the object itself. That is, a shared_ptr that uses the same reference counter as other shared_ptrs to this object. Which is how enable_shared_from_this works.

unique_ptr doesn't have any reference counter, so it doesn't make sense to hang on to that non-existent reference counter.

sort

c++ sort keeping track of indices

Stackoverflow.


template <typename T>
std::vector<size_t> ordered(std::vector<T> const& values) {
    std::vector<size_t> indices(values.size());
    std::iota(begin(indices), end(indices), static_cast<size_t>(0));

    std::sort(
        begin(indices), end(indices),
        [&](size_t a, size_t b) { return values[a] < values[b]; }
    );
    return indices;
}

atoi

Cplusplus.

This function is not defined in ANSI-C and is not part of C++, but is supported by some compilers. Use sprintf() instead.


#include <stdio.h>
#include <stdlib.h>

int main ()
{
	int i;
	char buffer [33];
	printf ("Enter a number: ");
	scanf ("%d",&i);
	itoa (i,buffer,10);
	printf ("decimal: %s\n",buffer);
	itoa (i,buffer,16);
	printf ("hexadecimal: %s\n",buffer);
	itoa (i,buffer,2);
	printf ("binary: %s\n",buffer);
	return 0;
}

// Output:
// Enter a number: 1750
// decimal: 1750
// hexadecimal: 6d6
// binary: 11011010110

Map

fstream

append and ate

StackOverflow.
app comes from 'append'- all output will be added (appended) to the end of the file. In other words you cannot write anywhere else in the file but at the end.
ate come form 'at end' - it sets the stream position at the end of the file when you open it but you are free to move it around (seek) and write wherever it pleases you.

tellg

cplusplus.


// read a file into memory
#include <iostream>     // std::cout
#include <fstream>      // std::ifstream

int main () {
  std::ifstream is ("test.txt", std::ifstream::binary);
  if (is) {
    // get length of file:
    is.seekg (0, is.end);
    int length = is.tellg();
    is.seekg (0, is.beg);

    // allocate memory:
    char * buffer = new char [length];

    // read data as a block:
    is.read (buffer,length);

    is.close();

    // print content:
    std::cout.write (buffer,length);

    delete[] buffer;
  }

  return 0;
}

Good practice

Gehrcke.


int main()
{
	ifstream f (argv[1]);
		perror("error state after ifstream constructor");
	if (!f.is_open())
		perror("is_open() returned false. error state");
	else
		cout << "is_open() returned true." << endl;
	cout << "* checking error bits once before first getline" << endl;
	check_error_bits(&f);
	while(1) {
		cout << "* perform getline() # " << getlinecount << endl;
		getline(f, line);
		cout << "* checking error bits after getline" << endl;
		if (check_error_bits(&f)) {
			cout << "* skip operation on data, break loop" << endl;
			break;
			}
		// This is the actual operation on the data obtained and we want to
		// protect it from errors during the last IO operation on the stream
		cout << "data line " << getlinecount << ": " << line << endl;
		getlinecount++;
	}		   
	f.close();
	return 0;
}

Advanced Features

Move Semantics

References

lvalue and rvalue

In C++ every expression yields either an lvalue or an rvalue, and is thus called either an lvalue or an rvalue expression.

Every expression that is not an lvalue is an rvalue.

An intuitive approach would be to think of expressions as functions and then an lvalue can be thought as the result of a function returning a reference. For example:


// "A[0]" is an lvalue because:
T& operator[](T*, ptrdiff_t); // The operator returns a lvalue reference

// "*p" is an lvalue because:
T& operator*(T*);

// "-x" is an rvalue because the negate operator returns non-reference:
T operator-(T);

l/r-valueness is independent of type

The lvalueness or rvalueness of an expression is independent of its type. For example, there are both lvalues and rvalues of type int.

Therefore, it's possible to have lvalues whose type is rvalue reference, and it's also possible to have rvalues of the type rvalue reference. For example, named rvalue references are lvalues:


void foo(A&& a){
}

// Within foo, a is an lvalue (of type A), but it will only bind to rvalues.

Since named rvalue references are lvalues, to assign it to another rvalue reference it is necessary to convert it to an rvalue.


Widget makeWidget();
Widget&& var1 = makeWidget()   // var1 is an lvalue, but its type is rvalue reference (to Widget)

// To call the move assignment, var1 needs to be converted by rvalues:
Widget var2 = static_cast<Widget&&>(var1); // the cast expression yields an rvalue, but its type is rvalue reference
// Or
Widget var2 = std::move(var1);    // equivalent to above

String literals are lvalues, so "hello" is an lvalue of type array of 6 const chars (including the null terminator). This is distinct from other literals, which are prvalues.

Rvalues correspond to temporary objects, such as those returned from functions or created through implicit type conversions. Most literal values (e.g., 10 and 5.3) are also rvalues.

Conversion between lvalue and rvalue

An rvalue cannot be converted to an lvalue, so an rvalue cannot be used to initialise non-const reference.

As discussed in the first StackOverflow link, the lvalue can't be implicitly converted to an rvalue, or an rvalue reference can't bind directly to an lvalue.

To explicitly bind an lvalue to an rvalue reference, there are ways:


// They tells the compiler/readers that you're promising to be done with modifiable_lvalue.
std::string&& i = std::move( modifiable_lvalue );
std::string&& i = static_cast<std::string&&>( modifiable_lvalue );

Nomenclature

The original meaning comes from the assignment: an lvalue being the left side of the assignment and rvalue the right side.

Rvalue is modifiable

non-class rvalues are non-modifiable.

This is not the case with user types. A class rvalue can be used to modify an object through its member functions. Albeit in practice, it can be said that objects are modified only through modifiable lvalues.

Rvalue references can also have cv-qualified types (const/volatile).


int x;
int& getRef () 
{
        return x;
}
getRef() = 4; // This is lvalue.

int getVal ()
{
    return x;
}
getVal(); // This is rvalue.

// You can read, but cannot modify rvalue.
const int& val = getVal(); // ok
int& val = getVal(); // NOT ok

// With rvalue reference, you can modify.
const int&& val = getVal(); // ok
int&& val = getVal(); // also ok - praise be!

rvalue reference

The move constructor is actually simpler than the copy constructor!


// move constructor
ArrayWrapper (ArrayWrapper&& other)
: _p_vals( other._p_vals  )
, _size( other._size )
{
	other._p_vals = NULL; // This is important, or the destructor will free the memory!!!
	other._size = 0;
}

// copy constructor
ArrayWrapper (const ArrayWrapper& other)
: _p_vals( new int[ other._size	 ] )
, _size( other._size )
{
	for ( int i = 0; i < _size; ++i ) {
		_p_vals[ i ] = other._p_vals[ i ];
	}
}

~ArrayWrapper ()
{
	delete [] _p_vals;
}

#include <utility> // for std::move
// move constructor
ArrayWrapper (ArrayWrapper&& other)
: _p_vals( other._p_vals  )
, _metadata( std::move( other._metadata ) )
{
	other._p_vals = NULL;
}

MetaData (MetaData&& other)
: _name( std::move( other._name ) ) // Uses std::move on the string it holds.
: _size( other._size )
{}

Universal Reference

Universal references in c11 by Scott Meyers.

T&& doesn’t always mean "Rvalue Reference". It may be universal reference.

How to find it: Rule of thumb

If a variable or parameter is declared to have type T&& for some deduced type T, that variable or parameter is a universal reference. The cases include:


Widget&& var1 = someWidget;      // here, "&&" means rvalue reference

auto&& var2 = var1;              // here, "&&" does not mean rvalue reference, but universal reference.

template<typename T>
void f(T&& param);               // here, "&&" does not mean rvalue reference, but universal reference.

// The following examples are intriguing, and cautions must be taken.

template<typename T>
void f(std::vector<T>&& param);  // here, "&&" means rvalue reference. Because the form is not "T&&", it's "std::vector<t>&&".

template<typename T>
void f(const T&& param);         // "&&" means rvalue reference, because of "const".
Examples from std::vector

More intruguing examples from std::vector. push_back(T&& x) has rvalue reference:


// Consider this push_back function in std::vector

template <class T, class Allocator = allocator<T> >
class vector {
public:
    void push_back(T&& x);       // fully specified parameter type ⇒ no type deduction, && ≡ rvalue reference.
};

// Explanations
// Consider the function's declaration outside the class:
template <class T>
void vector<T>::push_back(T&& x);
// push_back can't exist without the class std::vector<T> that contains it.  But if we have a class std::vector<T>, we already know what T is, so there's no need to deduce it.

Widget makeWidget();         // factory function for Widget
std::vector<Widget> vw;
vw.push_back(makeWidget());
// The use of push_back will cause the compiler to instantiate that function for the class std::vector<Widget>. The declaration for that push_back looks like this:
void std::vector<Widget>::push_back(Widget&& x); // So there is no type deduction.

std::vector's emplace_back:


template <class T, class Allocator = allocator<T> >
class vector {
public:
    template <class... Args>
    void emplace_back(Args&&... args); // deduced parameter types ⇒ type deduction; && ≡ universal references. Because the function template parameter Args is independent of the class template parameter T.
};

How the representation is determined

Like all references, universal references must be initialized, and it is a universal reference’s initializer that determines whether it represents an lvalue reference or an rvalue reference: If the expression used for initialization is an lvalue, then lvalue reference; otherwise rvalue reference.


Widget&& var1 = someWidget;
auto&& var2 = var1; // WCF caution: here var2 is lvalue reference in the end, because var1 is lvalue - yes it is rvalue reference, but "rvalue reference itself is lvalue"!
// It’s as if var2 were declared like this:
Widget& var2 = var1;

template<typename T>
void f(T&& param);  // "&&" might mean rvalue reference

f(10);              // 10 is an rvalue. So param has an rvalue reference of type "int&&".

int x = 10;
f(x);      // x is an lvalue. param is an lvalue reference "int&".

Nitty Gritty Details: Reference collapsing

The true core of the issue is that some constructs in C++11 give rise to references to references, and references to references are not permitted in C++.


Widget w1;
Widget& & w2 = w1; // error! "reference to reference" not permitted.

template<typename T>
void f(T&& param);
 
// Cases where reference to reference may occur:
int x;
f(10); // invoke f on rvalue. T is deduced to be "int".
f(x);  // invoke f on lvalue. T is deduced to be "int&". Initial instantiation of f becomes "void f(int& && param);". Instantiation of f with lvalue after reference collapsing: "void f(int& param);". See below.

There are four possible reference-reference combinations:"& &", "&& &&", "& &&", "&& &".

There are only two reference-collapsing rules:

The truth is that a universal reference is really just an rvalue reference in a reference-collapsing context.

Intriguing examples:


int&& r1 = 10;                   // r1’s type is int&&
int& r2 = x;                     // r2’s type is int&
f(r1); // invoke f on lvalue.
f(r2); // invoke f on lvalue.
// The deduced type for both r1 and r2 is int&. Why? First the reference parts of r1’s and r2’s types are stripped off (yielding int in both cases), then, because each is an lvalue, each is treated as int& during type deduction.

// In essence, lvalues of type T are deduced to have type T&, and rvalues of type T are deduced to have type T.

// Example: auto
Widget&& var1 = someWidget; // var1 is of type Widget&& (no use of auto here)
auto&& var2 = var1;         // "Widget& &&" collapse to "Widget&", so var2 is of type "Widget&".

// Example: typedef
template<typename T>
class Widget {
    typedef T& LvalueRefType;
    ...
};
Widget<int&> w; // "typedef int& & LvalueRefType;" collapse to "typedef int& LvalueRefType;".
void f(Widget<int&>::LvalueRefType&& param); // "void f(int& && param);" collpase to "void f(int& param);".

// Example: decltype
Widget w1, w2;
auto&& v1 = w1;          // v1 is an lvalue reference referring to w1.

decltype(w1)&& v2 = w2;  // v2 is a decltype-based universal reference, and decltype(w1) is Widget, so v2 becomes an rvalue reference. w2 is an lvalue, and it’s not legal to initialize an rvalue reference with an lvalue, so this code does not compile!!!

More: glvalues, xvalues, prvalues

glvalues
A glvalue is a "Generalized lvalue". It is used to refer to something that could be either an lvalue or an xvalue. wcfNote: it is NOT universal reference!
xvalues
An xvalue is an "eXpiring" value: an unnamed objects that is soon to be destroyed. xvalues may be either treated as glvalues or as rvalues depending on context.

xvalues usually only arise through explicit casts and function calls, examples including:


A v1;
static_cast<A&&>(v1); // Yields an xvalue of type A.
std::move(v1); // Yields an xvalue of type A.
B().a; // Yields an xvalue of type A, since the temporary object B() is a prvalue.
prvalues
A prvalue is a "Pure rvalue"; an rvalue that is not an xvalue.

Literals other than string literals (which are lvalues) are prvalues. So 42 is a prvalue of type int, and 3.141f is a prvalue of type float.

Any temporaries created as a result of implicit conversions are thus also prvalues.


int consume_string(std::string&& s);
int i=consume_string("hello"); // "hello" will implicitly convert to a temporary of type std:string, which is a prvalue.

Overload the unary minus operator of an rvalue reference

StackOverflow: Overload the unary minus operator of an rvalue reference.


#include <iostream>
#include <string>
#include <vector>

class X
{
   public:
      int n;
      X(const X&) = default;
      X() : n(0) {}
      X(int n) : n(n) {}

      X operator- () const &  // lvalue ref-qualifier
      {
         std::cout << "&\n";
         X x(-n);
         return x;
      }

      X operator- () const && // rvalue ref-qualifier
      {
         std::cout << "&&\n";
         X x(-n);
         return x;
      }    

      friend X operator+(const X& lhs, const X& rhs) {
          return X(lhs.n + rhs.n);
      }
};

int main()
{
    X a;
    X b = -a;      // unary operator- of a TYPE& aka lvalue ref
    X c = -(a+b);
}

// outputs:
// &
// &&

Forward semantics

Problem


template<typename T1>
class Gadget {
    template <typename T2>
    Gadget(T2&& rhs); // rhs is a universal reference, but rhs itself is an lvalue.
};

For the rhs:

This ambiguity regarding the lvalueness and rvalueness of what a universal reference is bound to is the motivation for std::forward: to take a universal reference lvalue and convert it into an rvalue only if the expression it's bound to is an rvalue.

Concepts

RTTI

Run-Time Type Information (RTTI)
The ability of the system to report on the dynamic type of an object and to provide information about that type at runtime (as opposed to at compile time).

dynamic_cast


class Interface
{
public:
        virtual void GenericOp() = 0;// pure virtual function
};

class SpecificClass : public Interface
{
public:
        virtual void GenericOp();
        virtual void SpecificOp();
};

Interface* ptr_interface;

SpecificClass* ptr_specific = dynamic_cast<SpecificClass*>(ptr_interface);
if( ptr_specific ){
    ptr_specific->SpecificOp();
}else{
    // our suspicions were incorrect -- it is definitely not a SpecificClass.
    // The ptr_interface points to an instance of some other child class of the base InterfaceClass.
    ptr_interface->GenericOp();
};

If the pointer that you are trying to cast is not of the correct type, then dynamic_cast will return a null pointer.

If the real type of the object being cast is not correct then dynamic_cast will not return null (there's no such thing as a null reference). Instead, it will throw a std::bad_cast exception.

typeid

Determine the class of an object at runtime.

It returns a reference to a std::type_info object, which exists until the end of the program, that describes the "object".

If the "object" is a dereferenced null pointer, then the operation will throw a std::bad_typeid exception.

The C++98 standard requires that header file typeinfo be included before operator typeid is used within a compilation unit.

typeid is faster and often preferred over dynamic_cast. typeid, applied on a type or non de-referenced value is a constant-time procedure, whereas dynamic_cast must traverse the class derivation lattice of its argument at runtime.

You should never rely on the exact content returned by std::type_info::name(), as this is implementation specific with respect to the compile.

typeid is actually an operator rather than a function, as it can also act on types:


const std::type_info& info = typeid(type);

#include <iostream>
#include <typeinfo>  //for 'typeid' to work

class Person {
public:
   virtual ~Person() {}
};

class Employee : public Person {
};

int main () {
   Person person;
   Employee employee;
   Person *ptr = &employee;
   // The string returned by typeid::name is implementation-defined
   std::cout << typeid(person).name() << std::endl;   // Person (statically known at compile-time)
   std::cout << typeid(employee).name() << std::endl; // Employee (statically known at compile-time)
   std::cout << typeid(ptr).name() << std::endl;      // Person * (statically known at compile-time)
   std::cout << typeid(*ptr).name() << std::endl;     // Employee (looked up dynamically at run-time because it is the dereference of a pointer to a polymorphic class)
}

Limitations

RTTI can only be used with polymorphic types, which should satisfy:
1. Used on the dereference of a pointer or reference (i.e. typeid(*ptr) or typeid(ref))
2. to an object of polymorphic class type (a class with at least one virtual member function).

运行时类型检查需要运行时类型信息,而这个信息存储在类的虚函数表,只有定义了虚函数的类才有虚函数表。

The type of any other expression is statically known at compile time.

Use of dynamic_cast and typeid in other types is called CTTI: compile-time type identification.

Misuses of RTTI

RTTI should be used sparingly in C++ programs.

Other language mechanisms such as polymorphism and templates are almost always superior to RTTI.

As with everything, there are exceptions, but the usual rule concerning RTTI is more or less the same as with goto statements. Do not use it as a shortcut around proper, more robust design. Only use RTTI if you have a very good reason to do so and only use it if you know what you are doing.

Acceleration

Pointer aliasing

In C/C++, you can have multiple pointers pointing to the same memory block (they may point to different location, but the memory block is overlapped), which is called pointer aliasing. When you access a pointer multiple times, the compiler is not sure whethter the data pointed is changed or not between these acceses, and it will produce codes trying to load it every time.

In C99, restrict (or in C++, __restrict__) keyword is used to tell the compiler that the pointer is not aliased, so the compiler could optimise more on this.


void example2b(const float * __restrict__ a, const float * __restrict__ b, float * __restrict__ c)
{
	for (int i=0; i<512; i++) {
		c[i]=a[i]+b[i];
	}
}

In CUDA, for Compute Capability 3.5+ GPU, when using this keyword together with const, the compiler will use readonly cache in addition, which boosts further.


__global__ void example3b(const float* __restrict__ a, float* __restrict__ b, const int*  __restrict__ c) {
  int index = blockIdx.x * blockDim.x + threadIdx.x;
  b[index] = a[c[index]];
}

A good reference: here.

Ofstream seekp after EOF

This discussion gave a good example that it is workable to seekp after EOF. I have also done the same successfully on iOS.

In another try, I followed the codes given by this link. However, even I had spared about 2G disk space on the iPad, the function fcntl kept complainning: not enough space.


#include <cerrno>
#include <fcntl.h>
void preAllocate()
{
	fstore_t fst;
	fst.fst_flags = F_ALLOCATECONTIG; // could add F_ALLOCATEALL
	fst.fst_posmode = F_PEOFPOSMODE; // allocate from EOF (0)
	fst.fst_offset = 0; // offset relative to the EOF
	fst.fst_bytesalloc = 0; // why not but is not needed

    const int vnb = sagpnb*supp.w;
    fst.fst_length = vnb;
    int fd = open(sagFile.c_str(), O_WRONLY|O_CREAT);
    errno=0;
    auto ret = fcntl(fd, F_PREALLOCATE, &fst);
    if(ret == -1) { // read fcntl docs - must test against -1
        perror("Error. Fail to allocate space for sag image");
        return -2;
    }
    ret = ftruncate(fd, vnb);
    if (ret !=0) {
        perror("Error. Fail to truncate for sag image");
        return -2;
    }
    close(fd);
}

Then in this Apple page, searching for "F_PREALLOCATE", I found the structure fstoreoperated on by this command. The fst_flags could have two choices: F_ALLOCATECONTIG and F_ALLOCATEALL. In the previous example code, it uses F_ALLOCATECONTIG, which specifies to allocate contiguous space. So I wonder it may work if I switch to F_ALLOCATEALL. The fst-posmode has two options: F_PEOFPOSMODE (physical end of file), and F_VOLPOSMODE (volume offset).

errno in fopen

errno is a thread-local global integer variable. Remember to reset it to zero before calling testing function. Example:


#include <cstdio>
#include <errno.h>
#include <cstring>

int main(void)
{
	errno=0; // Reset to zero.
	FILE *f = fopen("path", "rb");
	// strerror is a function from <cstring> to convert the error code to c string.
	if (!f) fprintf(stderr, "Open file error: %s.\n", strerror(errno));
	// Or directly print it to stderr using perror().
	if (!f) perror("Open file error");
	return 0;
}

Reference.

Must include the header cmath. Near-by rounding: round(x) := copysign( int(0.5+fabs(x)), x). So round(2.2)=2, round(2.6)=3, round(2.5)=3, round(-2.5)=-3.

About FD

Each running process has a file descriptor table which contains pointers to all open i/o streams. When a process starts, three entries are created in the first three cells of the table. Entry 0 points to standard input, entry 1 points to standard output, and entry 2 points to standard error. Whenever a file or other i/o stream is opened, a new entry is created in this table, usually in the first available empty slot. The socket system call returns an entry into this table; i.e. a small integer. This value is used for other calls which use this socket. The accept system call returns another entry into this table. The value returned by accept is used for reading and writing to that connection.

pthread

A thread's stack size is fixed at the time of thread creation. Only the main thread can dynamically grow its stack.

int pthread_attr_setstacksize(pthread_attr_t *attr, size_t stacksize);
int pthread_attr_getstacksize(const pthread_attr_t *attr, size_t *stacksize);

Mutex


pthread_mutex_init (mutex,attr)
pthread_mutex_destroy (mutex)

pthread_mutexattr_init (attr)
pthread_mutexattr_destroy (attr)

pthread_mutex_lock(pthread_mutex_t *mutex);
pthread_mutex_trylock(pthread_mutex_t *mutex);
pthread_mutex_unlock(pthread_mutex_t *mutex);

pthread_create

Reference.


#include <pthread.h>

int pthread_create(pthread_t *thread, const pthread_attr_t *attr,
                   void *(*start_routine) (void *), void *arg);

The main thread has tid 0?

Not really. Please see this discussion. Use pthread_equal() to compare thread pthread_t objects.

Compile

Environment variables

GDB

The usual way to produce debugging information for gdb is to pass -g to the gcc or g++ compiler (and also at linking time).

Cyclic dependency

Assuming foo and bar are dependent on each other, we have to: (Reference)


g++ -o myApp -lfoo -lbar -lfoo

# Another way
# -Wl: pass option to the linker.
# -Wl,-Map,output.map passes -Map output.map to the linker.
g++ -o myApp -Wl,--start-group -lfoo -lbar -Wl,--end-group

In CMakeLists.txt, I just write the libs twice to solve this problem:


set (DCMTK_LIB_DIR "/home/image/proGreen/dcmtk/lib")
file (GLOB DCMTK_LIBRARIES "${DCMTK_LIB_DIR}/lib*.a")
# Write DCMTK_LIBRARIES twice here to solve cyclic dependency.
target_link_libraries (imgServ pthread mysqlcppconn ssl ${DCMTK_LIBRARIES} ${DCMTK_LIBRARIES})

CPP FAQ

Is const reference necesarry for implicit types when passed as arguments?

对于内部数据类型的输入参数,不要将“值传递”的方式改为“const 引用传递”。否则既达不到提高效率的目的,又降低了函数的可理解性。例如void Func(int x) 不应该改为void Func(const int &x)。But Why?

How is static variable stored in memory

cs-fundamentals.com.

A compiler driver (preprocessor, compiler, assembler, and linker) can generate three types of object files:

The program memory contains:

The stack and heap are traditionally located at opposite ends of the process's virtual address space.

Check Size of Code, Data, and .BSS Segments


gcc check-endianness.c -o check-endianness
size check-endianness
# text    data     bss     dec     hex filename
# 1235     492      16    1743     6cf check-endianness

int main ()
{
  unsigned int x = 0x76543210;
  char *c = (char*) &x;
 
  if (*c == 0x10) {
    printf ("Underlying architecture is little endian. 
");
  }
  else {
     printf ("Underlying architecture is big endian. 
");
  }

  return 0;
}

Global function vs static function

StackOverflow: c static local function vs global function.

Static functions are invisible to the linker, allowing other compilation units to define functions with the same signature.


static int Square(int i)
{
  return i * i;
}

In new C++, namespaces are used instead.

Signals

References:

Platform Macros

If you want to know what macros are defined in your CC compiler, try this (http://stackoverflow.com/questions/2565979/macros-for-gcc-g-to-differentiate-linux-and-mac-osx):


touch dummy.hxx
cpp -dM ./dummy.hxx

MacOS: __APPLE__ Linux: __linux__ mach/mach.h: __MACH__

Headers location

C headers

In CentOS, in /usr/include, there are sys and c++ directories.

In MacOS, /Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX10.9.sdk/usr/include

Runtime

Reference. LD_LIBRARY_PATH.

Stringstream trap

stringstream is a good choice for extracting information from std::string. However, there is often a trap as in the codes written below:


#include <sstream>
#include <string>
#include <iostream>
using namespace std;
int main(int argc, char** argv)
{
	string s1="11111111";
	string s2="22222222";
	string output;
	stringstream ss(s1);
	ss>>output;
	cout<<output<<endl;
	ss.str(s2);
	ss>>output;
	cout<<output<<endl;
	return 0;
}

You might be disappointed and then eager to know why that the output is:


11111111
11111111

instead of


11111111
22222222

Here comes the explanation:


stringstream ss(s1);
ss>>output; // Read and reach the end of the buffer, set the EOF flag.
cout<<output<<endl;
ss.str(s2); // Set the string buff but the EOF flag is still on.
ss>>output;	// Since EOF is on, this operation fails and output is kept unchanged.
cout<<output<<endl;

The solution is to call ss.clear() everytime it is given a new string buffer. The calling must be before the extraction, e.g.


stringstream ss(s1);
ss>>output;
cout<<output<<endl;
ss.str(s2);
ss.clear();
ss>>output;
cout<<output<<endl;

See my read reference.

Fixed width intergers

LearnCPP. C99 defined a set of fixed-width integers (in the stdint.h header), which are adopted by C++11 (in the cstdint header). They are: int8_t, uint8_t, int16_6, uint16_t, int32_t, uint32_t, int64_t, uint64_t.

Valgrind

Valgrinde.


# If you normally run your program like this:
myprog arg1 arg2
# Use this command line:
valgrind --leak-check=yes myprog arg1 arg2

Get file size

Method 1

Stackoverflow.


#include <fstream>

std::ifstream::pos_type filesize(const char* filename)
{
    std::ifstream in(filename, std::ifstream::ate | std::ifstream::binary);
    return in.tellg();
	// If you want to read file from begining, remember to do this:
	// in.seekg(0, std::ios::beg);
}

GLIBC not found

Stackoverflow. When coming across: /usr/lib/libstdc++.so.6: version `GLIBCXX_3.4.15' not found, you could try to locate the cause:


strings /usr/lib64/libstdc++.so.6 | grep GLIBCXX
The newest GLIBC is missing from the output list. Usually you need to append the newest lib path such as "/usr/local/gcc-4.8.0/lib64" in ldconfig path.