Cross Language interfaces between C and C++ (2017)
gustedt.wordpress.com
gustedt.wordpress.com
Also regarding generic constants, C++ allows template variables:
https://en.cppreference.com/w/cpp/language/variable_template
One of the big gotchas of C++ is that lots of people think it's a superset of C, but that's only (mostly) correct for ANSI C (C89).
In my experience not even C99 is completely compatible with C89. One of the initial pain points when clang was young was that GCC used C89 as default, so lots of old stuff didn't build out of the box due to changes to how `inline` behaves or undefined symbols not being allowed anymore.
* add extern "C" to some of the headers
* include stdbool.h for bool
* include stdint.h for uint64_t et al.
* include stdlib.h and change nullptr to NULL
* change constexpr to enum
* change static_cast to C-style casts
* rewrite a function to take a pointer, rather than a reference
* write a min() function
I probably could have rewritten it as standard C++, but that somehow seemed like a more daunting prospect at the time.
> ... C and C++ have different rules for implicit conversion from an to these types, so you better avoid using them [in function parameters]
Correct me if I misunderstood, but don't these differences cancel each other out? For example:
/* In header file */
enum Foo { FOO_A, FOO_B };
void bar(Foo f);
/* In code */
bar(FOO_A);
In C, FOO_A is an integer, but it's implicitly convertable to Foo so the call to bar is fine. In C++, int cannot implicitly convert to type Foo, but FOO_A is already of type Foo to begin with, so the function call is still fine. (In fact the call to bar() would in a .c or .cpp file so is allowed to be different between the two languages anyway.)Edit: Another oddity in the article: If you want a function to work with a small number of different types, you would surely use simple function overloading rather than function template specialisation. In general it's a mistake to use function template specialisation, and there's certainly no need to use it here.
enum Foo { FOO_A, FOO_B };
is implicitly convertible to int even in C++. enum class Foo { FOO_A, FOO_B };
is not implicitly convertible, but can still be converted using static_cast.The only sane way is to consider `enum` as a deprecated construct in C++ and use it as sparingly as possible, preferably only when interoperability with C makes them unavoidable.