The code below runs fine in C.
But in C++ (std-C++00), the compilation fails.
#include <complex.h>
int main()
{
float complex a = 0.0;
return 0;
}
Here's the errors i am facing
Error: complex is not pat of 'std'
Error: expected ';' before a
I have read the solution to the problem I am facing here, and I am also aware of std::complex.
But my problem is that, I must port an enormous amount of C code to C++,
where complex numbers are declared and used, as shown above.
So any way of to do it ?
what other options do I have ?
#include <complex>
int main()
{
// Both a and b will be initialized to 0 + 0i.
std::complex<float> a;
std::complex<float> b = 0.0f;
return 0;
}
The C99 complex number syntax is not supported in C++, which instead includes the type std::complex in the C++ standard library. You don't say what your motivation for porting the code is but there may be a couple different things you can do.
std::complex is specified in C++11 to be layout compatible with C99's complex. Implementations of earlier versions of C++ generally happen to provide std::complex layout compatibility as well. You may be able to use this to avoid having to port most of the code. Simply declare the C code's interface in C++ such that C++ code can be linked to the C implementation.
#include <complex.h>
#ifdef __cplusplus
extern "C" void foo(std::complex<float>);
#else
void foo(complex float);
#endif
You may need to modify the above for your implementation. You have to ensure that both name mangling and calling conventions are consistent between the two declarations.
Alternatively, there are compilers that support the C complex syntax in C++ as an extension. Of course since the C complex macro would interfere with std::complex that macro does not get defined in C++ and you instead have to use the raw C keyword _Complex. Or if you don't use std::complex anywhere and you're never going to then you could just define the macro yourself: #define complex _Complex.
#ifdef __cplusplus
#define complex _Complex
#else
#include <complex.h>
#endif
int main()
{
float complex a = 0.0;
return 0;
}
This #define prohibits any use of the C++ complex headers. (and technically it causes undefined behavior if you make any use at all of the standard library, but as long as you avoid the headers <complex>, <ccomplex>, and <complex.h> it will probably be okay in practice.
If you really do need to port the entire codebase to standard C++, you might consider porting it not directly to idiomatic C++, but instead to 'portable' C. I.e. code that compiles as both C and as C++. This way you can continue building as C while you incrementally port it and verify that it continues to work correctly throughout the porting process.
To do this you'll do things like replace float complex with a typedef and then define the typedef appropriately in each language, use the C header <tgmath.h>, define other macros in C to correspond with the C++ complex interface, etc.
#include <complex.h>
#include <math.h>
#ifdef __cplusplus
using my_complex_type = std::complex<float>;
#else
#include <tgmath.h>
typedef float complex my_complex_type;
#define real creal
#define imag cimag
#endif
#define PRI_complex_elem "f"
void print_sine(my_complex_type x) {
x = sin(x);
printf("%" PRI_complex_elem "+%" PRI_complex_elem "i\n", real(x), imag(x));
}
The answer from bames53 has been accepted and is very helpful. I am not able to add a comment to it, but I would suggest that perhaps
void print_sine(my_complex_type x) {
x = sin(x);
printf("%" PRI_complex_elem "+%" PRI_complex_elem "i\n", real(x), imag(x));
}
should use csin(x) in lieu of sin(x).
Related
I have a C++ library, with functions declared in a header file. My function declarations include default arguments.
I would like to use this library in Mathematica via the Wolfram Mathematica WSTP Template Compiler (wscc). This requires writing a C interface to my library. I have used this pattern
#ifdef __cplusplus
extern "C" {
#endif
double my_function(double x, double abs_error = 1E-3);
#ifdef __cplusplus
}
#endif
to prevent name-mangling in my library (compiled with C++). But what about the default arguments? I don't think they're standard C. From Wolfram Mathematica WSTP Template Compiler (wscc), I find
error: expected ‘;’, ‘,’ or ‘)’ before ‘=’ token
double abs_error = 1E-3,
Do I have to make separate C and C++ declarations (essentially two header files)? Is this a common problem or is it related to my use of wscc? Perhaps wscc doesn't support this syntax, although it is usually acceptable?
C does not support default arguments.
I'm therefore assuming you want to keep them for your C++ code, but you're okay with requiring C callers (in your case, Mathematica) to pass values for all arguments.
One possible approach is to define a macro which expands to the default value initializer in C++, but to nothing in C. It's not pretty, but it works:
#ifdef __cplusplus
#define DEFAULT_VALUE(x) = x
#else
#define DEFAULT_VALUE(x)
#endif
#ifdef __cplusplus
extern "C" {
#endif
void foo(int x DEFAULT_VALUE(42), void *y DEFAULT_VALUE(nullptr));
// In C, this becomes void foo(int x, void *y);
// In C++, this becomes void foo(int x = 42, void *y = nullptr);
#ifdef __cplusplus
}
#endif
Rather than macro hackery to work around the fact that C does not support default arguments, I'd introduce a layer of indirection.
First a C++ specific header that your C++ code uses (which I arbitrarily name interface.h.
double my_function_caller(double x, double abs_error = 1E-3);
and a C specific header (which I arbitrarily name the_c_header.h)
double my_function(double x, double abs_error);
/* all other functions that have a C interface here */
In practice, one would probably want include guards in both headers.
The next step is a C++ compilation unit (which I arbitrarily name interface.cpp) that actually interfaces to mathematica
#include "interface.h"
extern "C" // this is C++, so we don't need to test __cplusplus
{
#include "the_c_header.h"
}
double my_function_caller(double x, double error)
{
return my_function(x, error);
}
Then there is just the question of how to call the function. If the caller is C++, then all it needs to do is
#include "interface.h"
// and later in some code
double result = my_function_caller(x);
double another_result = my_function_caller(x, 1E-6);
If the caller is C (built with a C compiler) it simply does
#include "the_c_header.h"
/* and later */
result = my_function(x, 1E-3);
another result = my_function(x, 1E-6);
There are obviously advantages and disadvantages of this, compared with a macro-based solution, including;
None of the traditional disadvantages of macros (not respecting scope, no unintended interactions with other macros, running afoul of some C++ development guidelines that forbid usage of macros for anything except include guards).
Clear separation of which code is C and which is C++: Only interface.cpp needs to take care to have both #include "the_c_header.h" and #include "interface.h" and worry about the mechanics of interfacing of C++ to C. Otherwise, C compilation units (compiled with a C compiler) only need #include "the_c_header.h" and C++ compilation units only need to #include "interface.h".
interface.h can use any C++ language features (not just default arguments). For example, all the functions it declares may be placed in a namespace named mathematica if you wish. C++ developers using your functions need not care that there is actually an interface to C code buried away within that call.
If you decide in future to re-implement my_function() using something other than mathematica you can. Simply drop in the replacements of the_c_header.h and interface.cpp, and rebuild. The separation of concerns means that it is unnecessary to change interface.h, that all C++ callers will not even need to be recompiled in an incremental build (unless, of course, you change interface.h for some other reason).
Practically, the build process will detect mistaken usage of both header files. A C compiler will choke on interface.h because it uses C++-specific features. A C++ compiler will accept contents of the_c_header.h outside of an extern "C" context, but the result will be a linker error if any C++ code ever calls my_function() directly (linking will require a name-mangled definition).
In short, this takes a little more effort to set up than the macro approach, but is easier to maintain in the long run.
The extern C does more than stop name mangling. The function has C calling conventions. It's telling the CPP compiler "you should now speak C". That means exceptions won't propagate, etc. And AFAIK C doesn't have default values.
You can have a function with C calling conventions implemented inside a CPP file, which is very useful sometimes. You can have C calling bits of your CPU code, which is useful.
My suspicion is that how a compiler goes about dealing with default values is up to the compiler writer. If that's true, I can think of at least a couple of ways, one of them not involving putting a value for abs_error on the stack when my_function is called. For example the compiler might include a parameter count on the stack which the function itself uses to spot that abs_error has not been passed and to set a default value. However such a compiler would be very unfriendly indeed if it did that with a function that had C calling conventions without reporting errors. I think I'd test it, just to be sure.
Notes:
I am compiling on OSX using Apple LLVM version 6.0 (clang-600.0.56) (based on LLVM 3.5svn)
Specifically, I am trying to compile a monolithic source from LibIIR, a filter library maintained here by Laurence Withers.
I've already looked at this answer here about using both <complex> and <complex.h> in the same file.
Setup:
I have a file iir.h like so:
#include <complex.h>
#ifdef __cplusplus
extern "C" {
#endif
...
I have C++ source and header files libiir++.cpp and iir++.h like so:
/*** libiir++.cpp ***/
// we need to include "iir.h" first, as it pulls in <complex.h>, which we need
// to take effect before "iir++.h" pulls in <complex>
#include "iir.h"
// now remove the preprocessor definition of complex to _Complex, which is fine
// for the C header but not good for the C++ header
#undef complex
#include "iir++.h"
namespace IIR {
...
-
/*** iir++.h ***/
#include <complex>
namespace IIR {
...
Problem:
clang gives me the following error when compiling:
./iir.h:570:15: error: expected ';' after top level declarator
double complex iir_response_c(const struct iir_coeff_t* coeff, double freq);
^
;
Evidently, the new <complex> import is not happening--or #undef complex is happening again--but I don't see how. Any advice on what might be going wrong, or what to check?
<complex.h> is a C header and it is not compatible with C++.
C++ defines C library compatibility through headers named in the pattern <c***>. So, the C++ counterpart to <complex.h> is named <ccomplex>. Here's what the C++ standard has to say about that:
Header <ccomplex>
The header behaves as if it simply includes the header <complex>.
If you attempt to use the C complex number library, you just get the C++ one instead.
Bottom line: you simply cannot run C complex math through a C++ compiler. At best, you can use the preprocessor to generate equivalent programs depending on __cplusplus.
For example,
#if __cplusplus
# include <complex>
typedef std::complex< double > cdouble;
#else
# include <complex.h>
typedef double complex cdouble;
#endif
Note, std::complex< double > and double complex are layout-compatible per C++14 [complex.numbers] §26.4/4 and C11 §6.2.5/13. The intent seems to be that you can use cdouble for cross-language function prototypes, although strictly speaking it depends on the ABI.
Incidentally, the C++ standard does define what happens when you #include <complex.h>, but it doesn't make any sense:
Every C header, each of which has a name of the form name.h, behaves as if each name placed in the standard library namespace by the corresponding cname header is placed within the global namespace scope. It is unspecified whether these names are first declared or defined within namespace scope (3.3.6) of the namespace std and are then injected into the global namespace scope by explicit using-declarations (7.3.3).
So, #include <complex.h> should give you a global ::complex<T>. This is a defect in the standard.
I would like to know if this is the correct way to port a C library to C++; for this example I wrote a 2 line C header with a function and a typedef managing a pointer.
lib.h
#ifndef LIB_H
#define LIB_H
#include <math.h>
double foo(double a) { return (log(a)); }
typedef double (*PtoFoo)(double);
#endif // LIB_H
lib.hpp
#ifndef LIB_HPP
#define LIB_HPP
namespace lib {
extern "C" {
#include "lib.h"
}
}
#endif // LIB_HPP
and a little test in C++11
#include <iostream>
#include "lib.hpp"
#include <functional>
int main() {
// call to the function
std::cout << lib::foo(42354.343) << "\n";
// trying the pointer to function type
lib::PtoFoo ptr = lib::foo;
std::function<double(double)> f(ptr);
std::cout << f(342.4) << "\n";
return (0);
}
right now my attention is focused on pointers, function pointers and functions, but in general I would like to know if this is the correct way to port standard C code to C++ and using the new c++ interface with namespaces without possible backfires .
Yes, that is the correct way to do it.
Alternatively, you can use the __cplusplus preprocessor token to define the C++ interface in the same header file:
#ifdef __cplusplus
namespace lib {
extern "C" {
#endif
typedef ...
#ifdef __cplusplus
}
}
#endif
The advantage of this approach is that only a single header file is required.
As I commented, C++ is designed to be compatible with C, so just wrapping your C library headers with the appropriate extern "C" { and } /* end extern "C"*/; is enough.
However, you may want to design a C++ friendly interface to your library. This requires some thoughts, and some code (most of it in C++ specific header files). For instance, you may want to provide interfaces using C++ object, overloading, operator, and template facilities.
I can't help more, but look for examples at: libonion and its C++ bindings, GTKmm which is a large C++ binding to GTK (and companion libraries like Glib...), the C++ class interface to gmplib, or even the newest C++11 standard thread library (i.e. std::thread etc, etc...) which could be viewed as a clever C++ wrapping of pthreads ....
I believe that each library could have its own C++ wrapping... How to design that is up to you... (depends a lot on the wrapped library, your available time, and your fluency with C++...).
i am running c code in vs2008. I was curious if i can mix this code with c++ code
The short answer is yes. However, there are some nuances.
C++ generally supports a large subset of C. It means that you can almost anything available in C (such as functions, libraries etc) from C++ code. From this point you have two options, an easy one and a bit harder.
Option #1 - Use C++ compiler.
Just have your code treated as C++. Simply put - use C++ compiler.
Option #2 - Mix C and C++.
You can write your C code and compile it with C++ compiler. Use C-like C++ where you need to use C++ components. For example, you may have a setup similar to the following:
head1.h - declarations of your C functions. For example:
void foo1();
header2.h - declarations of your C functions that intend to use C++ code.
#ifdef __cplusplus
extern "C" {
#endif
void foo2 ();
#ifdef __cplusplus
}
#endif
And two source files, one C and one C++:
source1.c
#include "header1.h"
#include "header2.h"
void foo1 ()
{
foo2 (); /* Call a C function that uses C++ stuff */
}
source2.cpp
#include <vector>
#include "header2.h"
#ifdef __cplusplus
extern "C" {
#endif
void foo2 ()
{
std::vector<int> data;
/// ... etc.
}
#ifdef __cplusplus
}
#endif
Of course, you will have to compile "cpp" files with C++ compiler (but you can still compile "c" files with C compiler) and link your program with standard C++ runtime.
The similar (but slightly more complicated) approach is used by Apple, for example. They mix C++ and Objective-C, calling the hybrid Objective-C++.
UPDATE:
If you opt for compiling C code as C++, I recommend you spend some time studying the differences between C and C++. There are cases when the code could be both legal C and C++, but produce different results. For example:
extern int T;
int main()
{
struct T { int a; int b; };
return sizeof(T) + sizeof('T');
}
If it is a C program then the correct answer is 8. In case of C++ the answer is 9. I have explained this in more details in my blog post here.
Hope it helps. Good Luck!
If you are compiling your code using C++ compiler as a C++ program then you can use std::vector.
If you are compiling your code using C compiler as a C program then you cannot.
This is because std::vector is a type defined by the C++ Standard, C Standard does not define any type as std::vector.
In simple words a C compiler does not understand what std::vector is.
There is a switch to compile .c files as C++ (/TP) . If you enable this, you can use the c as C++. Beware that some c code will not compile as C++ without modification (mainly to do with type casting; c++ has stricter rules for this).
If you are interfacing with some existing C library, then you of course can use C++. If you are compiling as C though, you won't be able to use any C++ features, such as std::vector.
This question already has answers here:
How to call C++ function from C?
(7 answers)
Closed 5 years ago.
I have a header declaring functions that take pointers to C++ objects as parameters. The implementaton is in a seperate C++ file. How can I include this header in C and use the functions in C even though the arguments need to be C++ object pointers?
Unfortunately, my first attempt answered the wrong question....
For the question you did ask...
You can, as someone point out, pass around void *'s. And that's what I would also recommend. As far as C is concerned, pointers to C++ objects should be totally opaque.
C++ functions can be labeled extern "C" as well if they are in the global namespace. Here is an example:
myfunc.hpp:
#ifdef __cplusplus
extern "C" {
#endif
extern int myfunction(int, void *ob);
#ifdef __cplusplus
}
#endif
myfunc.cpp:
#include "myfunc.hpp"
void myfunction(int x, void *vobptr)
{
ClassType *ob = static_cast<ClassType *>(vobptr);
}
afoofile.c
#include "myfunc.hpp"
void frobble(int x, void *opaque_classtype_ptr) {
myfunction(x, opaque_classtype_ptr);
/* do stuff with buf */
}
The other option is to do basically the same thing with creative use of typedefs in C. This, IMHO, is quite ugly, but here is an example anyway:
myfunc.hpp:
#ifdef __cplusplus
extern "C" {
#else
typedef void ClassType; /* This is incredibly ugly. */
#endif
extern int myfunction(int, ClassType *ob);
#ifdef __cplusplus
}
#endif
myfunc.cpp:
#include "myfunc.hpp"
void myfunction(int x, ClassType *ob)
{
// Do stuff with ob
}
afoofile.c
#include "myfunc.hpp"
void frobble(int x, ClassType *opaque_classtype_ptr) {
myfunction(x, opaque_classtype_ptr);
/* do stuff with buf */
}
If your C code just needs to pass the pointers around, and eventually pass it back to some C++ that'll actually deal with the object it points to, you should be able to use a void * in the C code, and cast back to T * when it goes back into C++.
If you plan on the C code actually using the pointer, you're pretty much stuck with reverse engineering what your compiler happens to do, and trying to emulate it closely enough to make things work. Even at best, this is going to be ugly and fragile.
Make a wrapper module that's C++ but whose external functions are declared extern "C". This will allow you to access C++ code cleanly from C. Naturally the wrapper should replace any pointers to types not representable in C (i.e. classes) with either void pointers (the quick and dirty solution) or pointers to incomplete struct types (which would provide some level of type-safety as long as they're used consistently.
The secret is "extern C", whose primary purpose is the prevention of name decoration.
You can't. You'll have to create a C-compatible abstraction layer:
typedef struct foowrapper *foohandle;
foohandle foo_create();
void foo_delete(foohandle);
int foo_getvalue(foohandle);
void foo_dosomething(foohandle, const char* str);
Leaving this as after reading allsorts of posts on this topic, this was the easiest to follow.
http://research.engineering.wustl.edu/~beardj/Mixed_C_C++.html
Also, in netbeans the example ran out of the box without having to touch the makefile.
Check out this link:-
http://developers.sun.com/solaris/articles/mixing.html
The link contains the following topics:
Using Compatible Compilers
Accessing C Code From Within C++ Source
- Accessing C++ Code From Within C Source
Mixing IOstream and C Standard I/O
Working with Pointers to Functions
Working with C++ Exceptions
Linking the Program