QNX’s problem 1: Mix C and C++ code.

It looks like some standard C header files like math.h in QNX toolchain contains C++ elements around by #ifdef __cplusplus preprocessor directives. That will bring some troubles when you need to mix C and C++ in one project.

Let’s see an example. Assume we have a C header file c.h and a C source file c.c, like below

c.h

#ifndef __C_H__
#define __C_H__
#include <stdint.h>
#include <math.h>
struct struct_c {
 int32_t dummy_field;
};
int func_c(struct struct_c * c);
#endif // __C_H__

c.c

#include <stdio.h>
extern "C" {
 #include "c.h"
}
int main()
{
 struct struct_c c;
 c.dummy_field = 1;
return printf("func_c() = %d\n", func_c(&c));
}

Compile them into a shared library libccc.so:

mbp17:qnx_header_test lee$ /Applications/bbndk/host_10_0_9_52/darwin/x86/usr/bin/ntoarmv7-gcc -c c.c
mbp17:qnx_header_test lee$ /Applications/bbndk/host_10_0_9_52/darwin/x86/usr/bin/ntoarmv7-gcc -shared c.o -o libccc.so
mbp17:qnx_header_test lee$ ls -l libccc.so
-rwxr-xr-x 1 lee staff 4725 11 1 11:36 libccc.so

That’s OK.

Now we have another C++ file named cc.cpp

#include <stdio.h>
extern "C" {
 #include "c.h"
}
int main()
{
 struct struct_c c;
 c.dummy_field = 1;
return printf("func_c() = %d\n", func_c(&c));
}

It is very simple. Let’s try to compile it. We got tons of errors! Some listed as below:

mbp17:qnx_header_test lee$ /Applications/bbndk/host_10_0_9_52/darwin/x86/usr/bin/ntoarmv7-g++ -c cc.cpp 2>&1 | more
In file included from /Applications/bbndk/target_10_0_9_386/qnx6//usr/include/math.h:4:0,
 from c.h:5,
 from cc.cpp:4:
/Applications/bbndk/target_10_0_9_386/qnx6//usr/include/xtgmath.h:116:1: error: template with C linkage
/Applications/bbndk/target_10_0_9_386/qnx6//usr/include/xtgmath.h:150:1: error: template with C linkage
/Applications/bbndk/target_10_0_9_386/qnx6//usr/include/xtgmath.h:157:1: error: template with C linkage
/Applications/bbndk/target_10_0_9_386/qnx6//usr/include/xtgmath.h:163:1: error: template specialization with C linkage
/Applications/bbndk/target_10_0_9_386/qnx6//usr/include/xtgmath.h:200:1: error: template with C linkage
/Applications/bbndk/target_10_0_9_386/qnx6//usr/include/xtgmath.h:207:1: error: template specialization with C linkage
/Applications/bbndk/target_10_0_9_386/qnx6//usr/include/xtgmath.h:212:1: error: template specialization with C linkage
/Applications/bbndk/target_10_0_9_386/qnx6//usr/include/xtgmath.h:218:1: error: template with C linkage
/Applications/bbndk/target_10_0_9_386/qnx6//usr/include/xtgmath.h:224:1: error: template specialization with C linkage
/Applications/bbndk/target_10_0_9_386/qnx6//usr/include/xtgmath.h:229:1: error: template specialization with C linkage
/Applications/bbndk/target_10_0_9_386/qnx6//usr/include/xtgmath.h:234:1: error: template specialization with C linkage
/Applications/bbndk/target_10_0_9_386/qnx6//usr/include/xtgmath.h:239:1: error: template specialization with C linkage
/Applications/bbndk/target_10_0_9_386/qnx6//usr/include/xtgmath.h:245:1: error: template with C linkage
/Applications/bbndk/target_10_0_9_386/qnx6//usr/include/xtgmath.h:251:1: error: template specialization with C linkage
/Applications/bbndk/target_10_0_9_386/qnx6//usr/include/xtgmath.h:256:1: error: template specialization with C linkage
I

Check error messages. Obviously math.h includes xtgmath.h internally. In latter some C++ template definitions are there around #ifdef __cplusplus directives. But in compiler’s view, though we wrapped #include “c.h” with extern “C” – it is necessary for linking, __cplusplus is still defined for C++ program. So, templates were incorrectly included into a pure C linkage enviroment.

 

 

14 Replies to “QNX’s problem 1: Mix C and C++ code.”

  1. Hi Holly,

    I gave some tries about the example you posted. Yes, you are correct. There is a weakness of QCC libc header implementation that you can’t add extern “C” around some std C headers in CPP files. The reason is that they have different implementations for C and CPP depends on whether the macro __cplusplus was defined.

    I’m guessing that the C.H in your example is portting form some third-party C LIB. You don’t want to change it much by add extern “C” before every C function declarations. The CC.CPP should be some CPP file in your project that want to use the third-party C lib. So, a work-round is add following statement in you CC.CPP

    extern “C” {
    #undef __cplusplus
    #include “c.h”
    #define __cplusplus 1
    }

    It is tricky, but works.

    1. Using

      #ifdef __cplusplus
      extern “C” {
      #undef __cplusplus
      #include “c.h”
      #define __cplusplus 1
      }
      #endif

      to resolve it.

  2. For me, feiws/hollys solution worked. Although this brought up other problems with the 3rd party lib i had to use. But those are other problems.

    Including cmath at the very start did not solve the problem for me.

  3. BTW, including cmath resolved another problem, but that is also solvable like this:

    #ifdef __cplusplus
    #include
    extern “C” {
    #undef __cplusplus
    #include “whatever.h”
    #define __cplusplus 1
    }
    #endif

    i currently only need the , but it might be an idea to include at this point. The seems to include .

    1. Hmmpf, sorry, the blogsoft deleted some of the words. I’ll retry:

      #ifdef __cplusplus
      #include <cinttypes>
      extern “C” {
      #undef __cplusplus
      #include “whatever.h”
      #define __cplusplus 1
      }
      #endif

  4. Thank you Feiw and Holly. The solution to undefine and redefine __cpluplus worked for me.

    I too was getting errors that started with “template with C linkage” on cmath.h. For some reason this wasn’t an issue when compiling the same code with Visual Studio, it only came up when compiling with g++ for me.

Leave a Reply

Your email address will not be published. Required fields are marked *