C compiles with g++ but not with Cilk++

C compiles with g++ but not with Cilk++

My code compiles perfectly with g++. When replacing g++ with cilk++, I get a lot of:

error: Calling Cilk functionF from non-Cilk context G

error: invalid conversion from'void (cilk*)()' to 'void (*)()'

9 posts / 0 new
Last post
For more complete information about compiler optimizations, see our Optimization Notice.


Cilk++ functions have different linkage from C++ functions. Although C++ functions can be called directly from Cilk++ functions, you cannot go the other way. In your code, G() is a C++ function, and it cannot call F(), a Cilk++ function.

There are a couple of solutions:

1. If this is a simple test program, you can make _all_ functions Cilk++ by compiling all of the files with the cilk++ compiler. Also, rename main() to cilk_main() which is an indication to the compiler to use cilk_main(), a function with Cilk++ linkage,as your entrypoint (main() is a C function).

2. You can call F() from G() by using cilk::run(). There is some overhead associated with entering Cilk++. It shouldn't be a problem if you're only doing it once. But if you have, e.g., a loop:

G () {
for (int i = 0; i < 1000; ++i) F();

then you might consider making G() a Cilk++ function or at least refactor the loop out of G().

3. The _new_ Cilk (Intel Cilk Plus) has better integration with C++ so that the linkage is the same. In Cilk Plus, you can simply call F() from G() without an error. To enter the Beta program you can email Ron Green (ronald.w.green@intel.com).

The code I compile is actually legacy C code. I only changed the makefile. I compile all the code with cilk++ but it does call some precompiled libraries. Currently there is no Cilk++ functions in the code. I tried to rename main to cilk_main but it did not help.

cilk++ assumes all functions are Cilk++ (except those in system headers), so you have to identify other functions as having C or C++ linkage. This is a portability change you have to makegoingfrom C to C++ anyway, if the libraries are compiled by a C compiler.

The libraries that are pre-compiled presumably have header files. You should specify that the functions are C functions in the header files like so:

extern "C" {
void foo ();
void bar ();
/* etc. */

The "extern" with a language string indicates to the compiler that it should treat the functions declared (or defined) within as having linkage (which will be reflected in name mangling) of that language. You can do it to the whole header file either within the header or in the .cilk file that includes them. E.g.,

extern "C" {
#include "baz.h"

You can avoid having to modify your header files by using the -isystem option instead of -I to specify include directories. The compiler will assume that the default linkage for files in that directory is C++.

- Barry

I added -isystem . -isystem /usr/include (well, there was no -I previously) in the makefile, but still getting the same errors.

What are the error messages you're getting, exactly?

Multiple of the following:

error: Calling Cilk function 'void cilk G()' from non-Cilk context 'void F()'
invalid conversion from 'void (cilk*)(void*)' to 'void (*)(void*)'

Is F() declared or defined within an 'extern "C"' or 'extern "C++"' block? If so, and if you want to keep the linkage of the other functions in that context, you can use 'extern "Cilk++"' within the 'extern "C++"' block to specify Cilk++ linkage for F().

Leave a Comment

Please sign in to add a comment. Not a member? Join today