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.

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