shared_ptr almost like intrusive_ptr

The current C++11 Standard consists of a very important remark in section 20.9.11.2.6. It is about creation of shared_ptr object. The remarks state:

Implementations are encouraged, but not required, to perform no more than one memory allocation.
[Note: this provides efficiency equivalent to an intrusive smart pointer. end note]

At work [1], I use Visual C++ 2010+ implementation of C++. I couldn’t resist myself to check if the standard managed to encourage Stephan T. Lavavej (STL) and his team at Microsoft to go for this optimisation.

I compiled and run a quick test:


#include <memory>
int main()
{
    std::shared_ptr<int> p0(
       new int(3)); // #1

    std::shared_ptr<int> p1
        = std::make_shared<int>(3); // #2
    return 0;
}

Quick check using breakpoints confirmed that Visual C++ 2010 indeed optimises construction of the shared_ptr. The difference between #1 and #2 is an important one: the second version causes 50% less memory allocations than the first one. Namely, one allocation. std::make_shared packs bookkeeping data and the user-defined data into a single block of memory.

Know your tools or suffer fragmented.

GCC At Home

I couldn’t leave a blog post alone without some kind of unrelated off-topic and pointless digression. So, here is one: Stephan T. Lavavej on his homepage provides custom-built distribution of MinGW toolset with What MinGW Is section starting as follows:

I recommend that anyone who is learning Standard C++ and who uses Windows for a primary development environment should use two compilers: the most modern version of Microsoft Visual C++ (currently 2010 SP1) and the most modern version of GCC, the GNU Compiler Collection.

Stephan works at Microsoft. I admire this kind of professionalism free from strategically competitive marketing b******t. GCC should definitely be included in the list of New Seven Wonders of the World. Recently, a new wonder has emerged: LLVM/Clang. I’m a user of all the three compilers (and related toolsets). It is easy for me to dream about Visual C++Visual Studio IDE based on LLVM/Clang as C++ compiler and shipped with C/C++ standard libraries provided by GCC. That would be a real C++ Renaissance

Inconsistent int64_t definition in GCC?

While compiling programs on Linux 32-bit with Comeau C/C++ 4.3.10.1 front-end and GCC 4.3.3 I encountered some problems using Boost Integer library, namely boost/cstdint.hpp header. Here we go:

If I first include sys/types.h (added with POSIX), directly or indirectly, and then include boost/cstdint.hpp in C++ program:

#include <sys/types.h>
#include <boost/cstdint.hpp>
int main()
{
    boost::int64_t a(0);
}

then it does not compile:

$ como -I/home/mloskot/dev/boost/_svn/trunk test1.cpp
MODE:non-strict warnings C++ noC++0x_extensions
"/home/mloskot/dev/boost/_svn/trunk/boost/cstdint.hpp", line 111: error: the
          global scope has no "int64_t"
    using ::int64_t;
            ^
"bad.cpp", line 5: error: namespace "boost" has no member "int64_t"
      boost::int64_t a(0);
             ^

Then, if stdint.h (added with C99) is included first (again, directly or indirectly), then the program compiles without any errors:

#include <stdint.h>
#include <boost/cstdint.hpp>
int main()
{
    boost::int64_t a(0);
}

It turns out that there is some amount of overlap in the stdint.h and sys/types.h headers. The issue is that the overlapped parts slightly differ. For the architecture, operating system and compilation toolset I use, both headers define int64_t type as follows:

typedef long long int int64_t;

However, the definition in sys/types.h header is guarded with different preprocessor condition testing __GLIBC_HAVE_LONG_LONG:

#  elif __GLIBC_HAVE_LONG_LONG
__extension__ typedef long long int int64_t;
#  endif

If I change sys/types.h replacing the clause with simple #else:

#  else
__extension__ typedef long long int int64_t;
#  endif

then the first variant of my program, the one including sys/types.h, does compile perfectly well.

Now, is this small difference a bug in the GNU C Library?
I’m going to try to confirm it.

como adventures with boost/cstdint.hpp

While compiling a program that uses boost/cstdint.hpp from Boost Integer Library:

#include <iostream>
#include <boost/cstdint.hpp>
int main()
{
    boost::int64_t i64 = -2;
    boost::uint64_t ui64 = 2;
    boost::uint64_t d = ui64 - i64;
    std::cout << d << std::endl;
    return 0;
}

front-end of Comeau C/C++ 4.3.10.1 compiler complains:

boost/cstdint.hpp", line 111: error: the
          global scope has no "int64_t"
    using ::int64_t;
            ^

However, if I reorder include directives:

#include <boost/cstdint.hpp>
#include <iostream>

then the program compiles well.

I believe that the order of header files should not be relevant here, but seems it is. I’ve submitted a ticket #3548 to Boost.Integer and I’m curious awaiting the diagnosis.

After this issue is fixed, I’m looking forward building the Generic Geometry Library using Comeau C/C++ compiler. This should help us to maintain high quality of standard and yet more portable C++ code.

osgeo.codepad.org

Online compilers are another generation of collaborative debugging tools delivered to Open Source communities. The overall idea is great. Actually, I can not imagine online discussions on IRC channel without being able to paste code snippets or compilation logs.

The codepad.org provides feature called private and project pastes. Some time ago I proposed private general purpose paste service dedicated to OSGeo communities. it is hosted at osgeo.pastebin.com and people has found it useful, as I can see. Today, I registered osgeo.codepad.org – a programmers-oriented paste service. Perhaps, people will find it useful too..

Users of the World’s second best programming editor, Vim (first place taken by Emacs), can install codepad.vim plug-in and send Vim buffers as pastes directly to the codepad.org service. Kudos to Nicolas Weber for the plug-in!

I’ve taken the liberty and modified the plug-in to use the private service at osgeo.codepad.org – here is custom codepad.vim plug-in.

Online Compilers

Sometimes I need to compile and run a tiny snippet of C++ code. For example, I want to proof some concept or I want to give code example while chatting with friends. Sometimes I don’t have access to good compiler. If I’m logged to irc.freenode.net, it’s not a problem – geordi is there. I’ve just found a Web-based alternative – codepad.org. It is a pastebin service that can compile, validate and execute your code.

Hello World!

Portability poem

Meaning of PortabilityNumber of OSGeo stack software written by C/C++ camp have to run on Microsoft Windows systems. I think I wouldn’t be dead wrong if said that most of hackers from OSGeo Community work on Unix systems (Linux, Mac OS X) but there is large number of users who work on Windows.

Conclusion? Portability. Google is bursting at the seams of the essays about how to write portable code in C or C++ language. I’d add a little poem to the collection.

Principles of Portability

  • Obey the standards, because they are not just dumb rules.
  • Make a list of compilers that must be supported. Learn about their differences.
  • If possible, use GCC 4+ and Visual C++ 7.1+.
  • Using old compilers? If possible, use C89 but avoid C99.
  • Prefer GCC 4.3 and Visual C++ 8.0+, so you get C++0x support. C++0x “brings C++ more in line with the C99″ – Wikipedia, so portability is much easier.
  • Write code in C or in C++, but do not write both at the same time.
  • Avoid (direct) use of C POSIX Library.
  • Never ever disable any warnings compiler throw. Fix them.
  • Be pedantic. Compile in highest strict mode possible.
  • If possible, do not use compiler-specific features.
  • Do not make platform/architecture specific assumptions about memory addressing, memory layout, etc.
  • First understand why, then cast the hack.
  • Personal preferences are evil. Make decisions based on reasoning.
  • (Re)Use good code that already exist. Boost C++ Libraries won’t bite you!
  • KIMS (Keep it modular, stupid) and let modules to loose coupling but keep cohesion in architecture, design as well as in development cycle (releases, inter-modular dependencies).

Got new toy

I’ve just got new toy tool. Since yesterday, I’m a happy owner of the most standards-conformant C++ compiler that ever existed – Comeau C/C++ from Comeau Computing.

I’ve successfully installed Comeau C/C++ 4.3.10.1 Beta compiler and libcomo36, accompanying Standard C++ Library, on 32-bit version of latest Ubuntu 9.04.

I’m going to use Comeau C/C++ for purposes like analysis and review of C++ source code I write or use, verification of code portability as well as for learning elements of C++ and experimenting. This is excellent compiler for learning C++ language. Among loads of features, one of the coolest is ability to give clear and informative error messages. This is very helpful while working with complex class and function templates.

Continue reading