Hi Everyone,
I have a C function which accepts pointer arguments. When I include the header file for that function in my xc file and use that C function in an xc file I get an error from the linker. The linker states that there is a symbol mismatch of the function used, specifically a conflict between an xc pointer being used as a parameter and a C pointer being defined as the arguments.
I've read a few solutions on the forum that involve modifying the C header with some predefined macros from xccompat that change the function definition to an xc compatible one. However, I'd like to modify the C code as little as possible with no modifications being the ideal.
I found one solution where you can enclose the c header #includes in the xc file in an extern "C" block. This solution worked for me and is what I would want to do continue doing in the future, but I had some questions about the effect of extern "C" in xc specifically with pointers.
I know that when using extern "C" to call c code from c++ the C++ compiler will prevent name mangling so that exported function from C code maintain their C ABI. In this instance, what is the xc compiler doing under the hood to make the xc pointer compatible with the C pointer?
Is the xc compiler converting the C pointers to xc pointers (restricted pointers)? Does the xc compiler automatically wrap the C functions in unsafe blocks?
Thanks!
Effect of extern C on C Functions with pointer args
-
- Experienced Member
- Posts: 93
- Joined: Wed Sep 16, 2015 2:38 pm
-
- XCore Addict
- Posts: 169
- Joined: Fri Oct 23, 2015 10:23 am
Hi aneves,
The 'extern "C"' block dose the same as having an 'unsafe' block.
(It makes the default pointer 'unsafe' rather than 'restrict' or 'alias' - you can always be explicit!).
extern C blocks can only be used at file scope, unsafe blocks can be used within bocks.
Here are two examples that may clarify.
extern "C" { // unsafe block, so can use and declare unsafe pointers.
int foo(int*p); // Implicit 'int * unsafe'.
int bar(int*restrict p); // Must explicitly declare as 'int * restrict'.
int main() {
int v = 9;
return foo(&v); // Implicit 'int * unsafe'.
}
}
int foo(int*unsafe p); // Must explicitly declare as 'int * unsafe'.
int bar(int*p); // Implicit 'int * restrict'.
int main() {
int v = 9;
unsafe {
return foo(&v); // Implicit 'int * unsafe'.
}
}
The 'extern "C"' block dose the same as having an 'unsafe' block.
(It makes the default pointer 'unsafe' rather than 'restrict' or 'alias' - you can always be explicit!).
extern C blocks can only be used at file scope, unsafe blocks can be used within bocks.
Here are two examples that may clarify.
extern "C" { // unsafe block, so can use and declare unsafe pointers.
int foo(int*p); // Implicit 'int * unsafe'.
int bar(int*restrict p); // Must explicitly declare as 'int * restrict'.
int main() {
int v = 9;
return foo(&v); // Implicit 'int * unsafe'.
}
}
int foo(int*unsafe p); // Must explicitly declare as 'int * unsafe'.
int bar(int*p); // Implicit 'int * restrict'.
int main() {
int v = 9;
unsafe {
return foo(&v); // Implicit 'int * unsafe'.
}
}