Compile Error using g++

w555 wrote on Wednesday, November 05, 2008:

Hi,

   First, Richard, thank you for a great RTOS! 

   I have compiled and used FreeRTOS v5.04 for an arm lpc2138 using gcc without any problems at all.  

  Now I am trying to compile with g++ with the hope of eventually writing some c++ code using FreeRTOS.  I am not trying to compile with anything other than the base demo code right now.  No c++ files or classes or anything. Here is the problem I’m having:

I am getting an invalid conversion error whenever the "listGET_OWNER_OF_NEXT_ENTRY" macro is called and I am having some trouble figuring out where the conversion attempt is taking place…ie…the cause.

The first time the error occurs in my build is on line 1477 in the tasks.c file.
The exact error message I am getting is:

"invalid conversion from ‘void* volatile’ to tskTCB*’ "

The same thing occurs again on lines 1883 and 1886 in the same file whenever that macro is invoked. Similar messages also come up from the croutine.c file when that macro is called.

No doubt its something simple that I’m just not seeing.  Any help would be greatly appreciated.

   Thank you,

     tim

davedoors wrote on Wednesday, November 05, 2008:

This probably has something to do with the data hiding employed by FreeRTOS where inside task.c tskTCB is a structure and outside task.c it is a void* pointer. C will happily convert but C++ might throw an error.  You will probably get the same issue with the queue definition. You could try moving the TCB definition into task.h and the queue structure definition into queue.h, but I dont know why other C++ users have not found the same issue.

You could probably also keep the data hiding by converting the void* to anonymous structure definitions instead.

richard_damon wrote on Wednesday, November 05, 2008:

The issue is C++'s stronger type checking than C, in C a void* can be implicitly converted to any other type of pointer,  in C++ this isn’t allowed.

There are basically 4 possible fixes to this.

1) Undo the data hiding by moving the structures from the C files into the headers, and make program TCB pointers real pointers to the type and not pointer to void. This removes the data hiding, which might be a concern.

2) Change the typedef for TCB handles to be pointers to the TCB struct, but not define the struct in the header. This SHOULD work, but isn’t done as apparently some of the compilers being used can’t handle it (Standard compliance for embedded compilers can be bad)

3) Add explicit casts where needed so that the code can be compiled as c++ code.

4) Compile the .c files as c files, and not c++ files. The headers do declare them as having c linkage (if the headers are compiled as c++) so this should work, and is what I do (I also do 1 for debugging purposes).

w555 wrote on Thursday, November 06, 2008:

Dave, Richard,

Thanks for your quick replies on this.

Yes, the stricter type checking c++ does seem to be the problem. I thought when I looked through the code and saw the extern c linkage specifiers in the header files that it was set up to compile with g++.  I guess not quite that painless.

Of the solutions suggested, #4 would also be my preference.  I prefer not to modify the freeRTOS files at all if possible.  Richard, are you saying that you compile the rtos files separately into ‘C’ object files by themselves and then add those object files to your c++ build…?  If not and you are relying on the linkage specifiers to prevent c++ name mangling issues and the stricter checking etc…if the latter,is there something else I need to do with the code before attempting to compile with g++?  And just to give me a motivational boost…you have working code with the RTOS using c++ files?

  Thanks again,

     tim

richard_damon wrote on Thursday, November 06, 2008:

The extern “C” means that the header files will work right for both C and C++ programs, it doesn’t make the compiler compile those functions a C code.

What you need to do is get gcc to compile those files as C code, not C++, there is probably a command line argument to make it look at the file extension to figure out the mode to compile that file in.