lrleon
lrleon

Reputation: 2648

gcc 4.8.1: combining c code with c++11 code

I have not made ​​much effort to discover the cause, but gcc 4.8.1 is giving me a lot of trouble to compile old sources that combine c and c++ plus some new stuff in c++11

I've managed to isolate the problem in this piece of code:

# include <argp.h>
# include <algorithm>

which compiles fine with g++ -std=c++0x -c -o test-temp.o test-temp.C version 4.6.3, ubuntu 12.04

By contrast, with version 4.8.1, the same command line throws a lot of errors:

In file included from /home/lrleon/GCC/lib/gcc/x86_64-unknown-linux-gnu/4.8.1/include/x86intrin.h:30:0,
                 from /home/lrleon/GCC/include/c++/4.8.1/bits/opt_random.h:33,
                 from /home/lrleon/GCC/include/c++/4.8.1/random:51,
                 from /home/lrleon/GCC/include/c++/4.8.1/bits/stl_algo.h:65,
                 from /home/lrleon/GCC/include/c++/4.8.1/algorithm:62,
                 from test-temp.C:4:
/home/lrleon/GCC/lib/gcc/x86_64-unknown-linux-gnu/4.8.1/include/mmintrin.h: In function ‘__m64 _mm_cvtsi32_si64(int)’:
/home/lrleon/GCC/lib/gcc/x86_64-unknown-linux-gnu/4.8.1/include/mmintrin.h:61:54: error: can’t convert between vector values of different size
   return (__m64) __builtin_ia32_vec_init_v2si (__i, 0);
                                                      ^

... and much more.

The same happens if I execute

g++ -std=c++11 -c -o test-temp.o test-temp.C ; again, version 4.8.1

But, if I swap the header lines, that is

# include <algorithm>
# include <argp.h>

then all compiles fine.

Someone enlighten me to understand what is happening?

Upvotes: 5

Views: 2363

Answers (3)

neuro
neuro

Reputation: 15180

I ran into the same problem. As it is really annoying, I hacked it down to <argp.h>.

This is the code (in standard gcc header argp.h) which trigger the error on ubuntu 14.04 / gcc 4.8.2:

/* This feature is available in gcc versions 2.5 and later.  */
# if __GNUC__ < 2 || (__GNUC__ == 2 && __GNUC_MINOR__ < 5) || __STRICT_ANSI__
#  define __attribute__(Spec) /* empty */
# endif

This is probably to make headers compatible with old gcc AND to strict ANSI C++ definition. The problem is that --std=c++11 set the __STRICT_ANSI__ macro.

I've commented the #define __attribute__(spec) and the compilation worked fine !

As it is not practical to comment a system header, a workaround is to use g++ --std=gnu++11 instead of g++ --std=c++11 as it does not define __STRICT_ANSI__. It worked in my case.

It seems to be a bug in gcc.

Upvotes: 3

Wintermute
Wintermute

Reputation: 1531

Two things come to mind:

1) It's a missing extern "C" in headers, which is not that rare.

2) Something is wrong with data alignment. Probably you are using STL container to store SSE types, which doesn't guarantee aligment for those. In this case you should implement custom allocator, which will use alligned_malloc. But I think it should've compiled fine in this case, but give you segfault at runtime. But who knows what compilers can detect now :)

Here's something your might want to read on that topic: About memory alignment ; About custom allocators

p.s. a piece of your code would be nice

Upvotes: 2

Zeta
Zeta

Reputation: 105905

This is a known bug, apparently some headers are missing extern "C" declarations at the right places:

I also just came across this issue with GCC 4.7.2 on Windows. It appears that all the intrin.h headers are missing the extern "C" part. Since the functions are always inline and thus the symbols never show up anywhere this has not been a problem before. But now that another header declares those functions a second time something must be done.

Upvotes: 3

Related Questions