Loud ramblings of a Software Artisan

Wednesday 12 June 2013

C++ 11 in your project

C++ 11 is now available in both gcc and clang. That mean it is really available where it matters.

Using C++ 11 in your project (with autoconf).

First if you use autoconf, you have to detect it. The autoconf archive has a macro. Download the .m4 definition and put it in your m4 directory in your project.

In the configure.ac, add the following line:

AX_CXX_COMPILE_STDCXX_11(noext,mandatory)

Make sure it appears after

AC_GNU_SOURCE

This is will make configure detect C++11 support, without GNU extension (I tend to avoid these in general) and fail if it doesn't exist. If you prefer to make it optional, read the above documentation that has more details.

The interesting features

I'm interested in several features from C++11.

  1. auto to automatically deduct the type where it can. Ever gotten annoyed by the long type name for iterators of containers? Just use auto instead.
  2. Lambda: now you can write lambda functions like in Python or JavaScript. This is overly convenient when you iterate over containers or use std::for_each().
  3. The smart pointers: I was using the one from Boost, then the one from std::tr1::. Just replace with std::
  4. std::bind and std::function to replace Boost own versions.

There are more, I'll talk about it when I get to look at them.

Saturday 15 October 2011

Punk rock languages

Excellent write-up about why C has won the language battle: punk rock languages

Also, if you know C and C++, read the Deep C (and C++) PDF deck of slides, and become surprised (or not).

Sunday 28 August 2011

A case for braces

I am one of those who believe C and C++ should have made curly braces mandatory.

Recent version of gcc and other compiler emit a warning when you have the following:

if(foo)
  ;

It does it because you could do something like

if(foo);
{
  // do something for foo
}

And this is likely a bug. But imagine the following case:

if(foo)
  DEBUG_MESSAGE("foo");

Now you have DEBUG_MESSAGE() defined as a macro that is empty in non-debug (you don't want these for your users). Then you end up with the warning for the situation above when doing your builds. There would be no problem had you written it this way:

if(foo)
{
  DEBUG_MESSAGE("foo");
}

Also another case:

if(foo)
  if(bar)
    do_bar();
else
  dont_foo();

Do you see the bug? That's right, the code is wrong: dont_foo() is executed in the else case for if(bar). Had you put curly braces it would have been clearer of what is happening. Like that:

if(foo)
{
  if(bar)
  {
    do_bar();
  }
}
else
{
  dont_foo();
}

Also if you find this a bit too hard because of the many like, can write with that style of bracing:

if(foo) {
  if(bar) {
    do_bar();
  }
}
else {
  dont_foo();
}

The opening brace at the end of the opening statement.

Another case:

if(obj)
  obj->data->foo = 1;

Now you know that data can not be null and want to catch it when testing. So you add one line:

if(obj)
  DEBUG_ASSERT_NOT_NUUL(obj->data);
  obj->data->foo = 1;

Oops. Did you realize this is wrong? Mistakes happen. Mistakes can be prevented. Curly braces would have prevented it.

Note: in the code above you should still ensure that obj->data is not NULL before dereferencing, but that's a different subject, for another time.

Bottom line, don't be lazy. Make the use a curly braces mandatory in your coding style. If your compiler has a warning for that, enable it.

Saturday 26 March 2011

About libraries

Read somewhere on the interweb:

Library code is ugly because it cannot use global variables. Libraries are more difficult to modify, build, install, and test than standalone programs, and so are inappropriate for file formats that change every day.

The result is just full of global variables that get changed here or there, making a function behaviour totally change. And when it comes to adding a new file format? If you are lucky, it will easy. If not, good luck.

File this in the "DON'T" folder.

Friday 26 March 2010

C++ Coding Standards

I finally read C++ coding standards by Herb Shutter and Andrei Alexandrescu. One of these books I should have read a long time ago and for which I felt I learned something when finishing it.

Coding standard is about code quality and language usage, not about indentation and other cosmetic and personal taste. This book list 101 things to following when coding in C++. Includes things on topics including type safety, STL, coding style (semantics, not presentation), design, etc.

Several projects I know don't even enforce or follow what's is told in this book, even though they should, and I just wish we all used tools that could enforce most of the issues listed in there at compile time.

Wednesday 28 January 2009

Thanks for the laugh

QT adds almost as much boilerplate and macros as GObject is doing on top of C

Thanks for the laugh Philip. I guess we are not living in the same space-time continuum. The one where 5 lines to subclass QObject (in C++) is as much boilerplate as the 25 to subclass GObject (in C).

Tuesday 21 October 2008

Workaround

Dom:, just make the predicate a functor class that will accept both comparison operators. I know it looks ugly, but at least you can work around the bug.

Or use STLPort :-)

Wednesday 18 June 2008

gcc in C++?

Ian Lance Taylor has posted his gcc summit slides, one set about gold, the new ELF linker for gcc that he wrote in C++, and the other one about writing gcc in C++. Very interesting and short.

Tuesday 25 March 2008

sigc++ and boost::bind

I have been using Gtkmm a lot for a personal project.

I discovered that you can pass boost::bind to Gtkmm signals (that use sigc), thanks to the magic of templates.

Something like that:

m_selection->signal_selected
    .connect(boost::bind(&LibraryMainView::on_selected,
        m_mainview, _1));

Why? Because I'm more familiar with Boost.Bind and for me it looks more flexible. Also because you can pass a shared_ptr<> to it, unlike with sigc::mem_fun.

Sunday 23 March 2008

New GNU linker

A new linker for GNU binutils, gold, targetting ELF, has been announced. It is apparently 5 times faster to run than the regular GNU ld. It is written in C++, and Tom Tromey praise it for its performance and its coding style.

Off course it is still pre-release and will probably need a lot of testing as well as being ported to new target architectures, as it currently only support i386 and x86_64.

And I actually need to give it a try.

Sunday 23 December 2007

Detecting boost

One of the problem with boost is to detect it in configure as there is no pkg-config and there are several modules that some distro tend to split out.

I ended up finding boost.m4 which is a simple m4 file that contain various macros to detect the various boost modules. It also take into account the various flavor of boost, etc.

Sunday 11 November 2007

Passing Glib::RefPtr<> to boost::bind

I ran into a limitation of Glibmm while using std::for_each() with boost::bind() and Glib::RefPtr<>.

boost::bind() works well with any of the Boost.SmartPointer, or with raw pointers, but not with Glib::RefPtr<> as it lack the get_pointer() function.

I tried to do this:

Glib::RefPtr<Foo> foo;
std::vector<Bar> v;
/* ...initialize foo and v */
std::for_each(v.begin(), v.end(), 
	boost::bind( &Foo::do_something_with_bar, foo, _1 );

But it failed to compile as I was missing the function below.

namespace Glib {
/** Dereference Glib::RefPtr<> for use in boost::bind */
template< class T_CppObject >
T_CppObject *get_pointer(const Glib::RefPtr< T_CppObject >& p)
{
	return p.operator->();
}
};

Some explanations: the function is templated to work with any instance of Glib::RefPtr<>. It is in the the Glib namespace, and will be looked up naturally by the Koenig lookup which in principle allow looking the function up in the same namespace that the argument is in. It uses this ugly operator->() member call because there is no other way to get the raw pointer from the Glib::RefPtr<>, but this is an implementation detail.

Filed bug 495762. Adding it to Glibmm will not break the ABI as it is not a method, and it is a template function, hence instantiated locally. Maybe it could be maybe inline.

The above code is either under the same license governing Glibmm which is LGPLv2+.