Skip to content

Generalised attributes

GCC has recently implemented generalised attributes. In this post I will discuss what they are and how they can be useful.

Generalised attributes are an extendible means to specify compiler specific attributes for particular language constructs. Previously these have had compiler specific syntax, and as such, wouldn’t even compile with the wrong compiler. The GNU compiler uses __attribute__, and the Microsoft compiler uses the __declspec keyword.

Attributes are declared by placing an attribute specifier in a declaration. An attribute specifier is said to appertain to a particular entity in the declaration. In other words, the specifier applies to some part of the declaration. The specifier is either an alignas specification, or a list of attributes inside double square brackets ([[]]).

Read more…

Alignment support

GCC has recently implemented alignment support. In this post I will discuss what this is and how you can use it.

There are four additions that are related to alignment support, these are the alignas alignment-specifier, the alignof expression, alignment arithmetic library support and std::align for aligning pointers. I will explain these all individually below.

Alignment is the requirement that the memory address of the first byte of certain types of objects be modulo zero with respect to some integer. For example, int32_t has an alignment of 4, it can only be placed in memory locations divisible by 4.

Alignments are ordered from weaker to stronger or stricter. An alignment that is stricter than another has a larger value. It is said to be stricter because there are less memory locations at which it can be placed, therefore the compiler is stricter in where that object can be placed.

Read more…

TransLucid 0.2 released

TransLucid version 0.2 has been released. With this release comes the ability to replace and delete declarations, intensions as first-class values, and lazy parsing and processing of declarations. It can be downloaded from Sourceforge at http://sourceforge.net/projects/translucid.

You can read all about the latest features at cartesianprogramming.com.

shared pointers

Shared pointers allow you to hold on to several copies of the same pointer, without having to keep explicit track of membership. Rather than one object owning the pointer, a shared pointer counts the number of references there are to the actual pointer, and deletes the object when that counter reaches zero.

The declaration of the shared pointer class is:

template <class T>
class shared_ptr;

The shared pointer class is a shared pointer to something—it has a strong type just like any other pointer.

The most basic way to use the shared pointer is to create one, and then pass it around. The simplest constructor is:

template <class Y> explicit shared_ptr(Y* p);

You use this by simply writing something like:

shared_ptr<int> x(new int(5));

Note that the constructor is explicit because you don’t want to accidentally create a shared pointer by passing it to a function without realising. If it wasn’t explicit, you could pass a pointer to a function that expects as argument a shared pointer, and that would convert it to the shared pointer and suddenly your pointer that you don’t want to be managed might get deleted when you don’t want it to be.

It is preferable to use std::make_shared, which creates a shared pointer and allocates both the memory for the object and the pointer’s data block with only one call to new. The example above would be better written as:

auto x = std::make_shared<int>(5);

Read more…

TransLucid 0.1 released

The first release of the programming language that I am developing, TransLucid 0.1, has been made. TransLucid is a declarative language in which a variable is an infinite array of arbitrary dimensionality, which captures all of the variance of that variable.

It can be downloaded from Sourceforge at http://sourceforge.net/projects/translucid.

Binding references

Suppose that you want to bind a reference to a variable to a function, then you can’t just pass the variable to the function bind, because that will copy the variable instead of taking a reference. Since a reference is not a first-class value, there is no way to pass the reference around. So instead you can use the function ref, which creates a reference wrapper around the variable. A reference wrapper is just an object which holds onto a reference, that way when the wrapper is copied, the reference is copied by the wrapper instead of the actual object.

For example, suppose you had a vector of int that you wanted to add up, one way to do that would be:

void
increment(int& i, int current)
{
  i += current;
}

int sumVector(const std::vector<int>& v)
{
  using std::placeholders::_1;
  int result = 0;
  for_each(v.begin(), v.end(), 
    std::bind(&increment, std::ref(result), _1));

  return result;
}

Deprecated binders and adaptors

Along with variadic templates have come much more flexible function binders and adaptors; as a result, several existing binders and adaptors are now deprecated. You should no longer use the functions ptr_fun, mem_fun, bind1st and bind2nd. Their functionality has been completely subsumed by the class std::function and the functions bind and mem_fn. Note that the deprecated function is mem_fun, and the new function is mem_fn, the only difference being the letter u.

Member functions

The function mem_fn takes a pointer to a member function of any class, and returns a functor whose first argument is an object of the required class, and whose remaining arguments are the arguments that the function expects. When called it will call the member function with the given object and the given arguments.

For example, suppose that you have the class A:

class Person
{
  public:

  Person(const std::string& name)
  : m_name(name) {}
  
  void
  hello() const
  {
    std::cout << "hello " << m_name;
  }

  std::string m_name;
}

You could create two objects of type Person, and create the one member function object to the same function on both objects:

Person bob("Bob");
Person jim("Jim");
auto hello = std::mem_fn(&Person::hello);
hello(bob);
hello(jim);

These lines will print to standard output:

hello Bob
hello Jim

The functions bind1st and bind2nd have been deprecated by bind. Furthermore, bind makes use of placeholders _M, where M is an integer whose value is implementation defined. Using bind with placeholders allows any argument to be bound to any position, for example, the function swap_args defined below creates a function that calls the given function with its two arguments swapped.

namespace ph = std::placeholders;

template <typename F>
auto
swap_args(F&& f)
  -> decltype(std::bind(f, ph::_2, ph::_1))
{
  using namespace std::placeholders;
  return std::bind(f, _2, _1);
}

Then you could write:

int main()
{
  std::cout << swap_args(std::divides<double>())(4, 2) 
            << std::endl;

  return 0;
}

Note that the result is 0.5, which is 2 divided by 4, the result of calling std::divides with the arguments 4 and 2 swapped. Note also that with bind, you are free to bind whichever arguments you wish to a function, you can also bind constant values, for example, you could bind the value 2 to the first argument, and the 4th passed argument to the second argument in the called function, completely ignoring the 1st, 2nd and 3rd arguments:

auto bound = std::bind(f, 2, _4);

Finally, the class function allows you to create a functor from any type of callable object: a member function wrapper, a function created with bind, a plain function pointer, etc. For example, in the example given above, we could attach the result of swap_args to a function object like so:

std::function<double(double, double)> f = 
  swap_args(std::divides<double>());

The class function takes a function-type argument. The syntax is t(a, b, ...), where t is the return type, and the remaining letters are the types of the arguments.

unique_ptr

Part of the additions to the standard library are a couple of new smart pointers, std::shared_ptr and std::unique_ptr. In this post I will talk about std::unique_ptr. Firstly, it is defined in <memory>.

std::unique_ptr replaces the old std::auto_ptr. It is a smart pointer which can only hold one copy of a pointer, and deletes that pointer when its scope exits. std::unique_ptr can be used with normal or array variables, and a custom delete function can be specified. It cannot be copied, and assignment deletes the reference that it currently holds, if any.

Read more…

Lambda functions

One of the biggest features added to C++ is the lambda function—unnamed functions written as an expression. One of their best uses is with the STL algorithms. Instead of having to write a class and instantiate it as a functor, you just write a lambda function right where you need to pass the functor to the algorithm.

When you write a lambda function, you are creating a function object, which when called with operator(), will call the body of the function that you just wrote. Additionally, you can bind local variables to the function object so that their value will be saved if you return the object out of the current function.

The syntax is:
[ capture-list ] ( parameter-list ) -> return_type { statements }

Read more…

Variadic templates, part 3 (or how I wrote a variant class)

Now that I have explained r-value references and variadic templates (part 1 and part 2), I will explain in great detail a stack based replacement for boost::variant. The only assumption that needs to be made here is that all of the objects contained in it have a nothrow move constructor.

A variant is essentially a tagged union. It is a variadic template class which holds one of the types specified in the template. The interface to the class is then designed in such a way that it is impossible to get a type error at runtime. If a value of the wrong type is requested, either nullptr is returned or an exception is thrown, depending on the version of get.

Read more…