Writing subset-of-C C++ code

Hi everyone,

Is there a way on one or more compilers to enforce only using a C++-compatible subset of C? (Would be most interested in gcc.)

e.g.
int* p1 = malloc(10 * sizeof(int));
is not C++ code, but is C code, so I would want try to compile it C but have it give a warning or error that it isn't valid C++ code. Or is the solution to simply have two build options: One for c++, one or c, and try it twice.

I was reading http://isocpp.github.io/CppCoreGuidelines/CppCoreGuidelines#S-cpl and I'm really just curious more than anything. Not sure if it has much practical use since you can always use #ifdefs for things that are C++ but not C.
Last edited on
Actually

int* p1 = malloc(10 * sizeof(int));

cannot/should not be compilable in C++ since malloc(...) returns void * which cannot be imiplicitely converted to int * in C++.
Yes, that's why I said it wasn't C++ :)
To clarify: That example was an example of something that I would want the compiler to flag for me.

I'm starting to think the easier solution would be to just have two build setups (one for C, one for C++) instead of finding some obscure compiler setting, but still curious if there is one.
Last edited on
I haven't heard of such a compiler flag.

One idea is to set up your build system in such a way that it compiles as both C and C++ at the same time.

Otherwise, if you are more familiar with one of the languages it's probably a good idea to compile in the other language, because then you are more likely to get helped by the compiler. If you are unsure about something, look it up. From time to time, compile in your best language to verify that it actually works.
Last edited on
save it as .cpp and compile with g++
error: invalid conversion from ‘void*’ to ‘int*’ [-fpermissive]

(that flag is for converting the error to just a warning)
Last edited on
It would make sense to put C and C++ in different compiler units (and tell the compiler to use C or C++ respectively).

You can use extern "C" to use C code in C++.
This may be done when you want to create a dll with C interface [for other languages].
I think most compilers can tell by extension (.c vs .cpp) and will work fine if you keep them in distinct files.

C accepts the cast on malloc, but its considered to be bad practice in C. But it works just fine, its just an ugly.

so

int* p1 = (int*)malloc(10 * sizeof(int)); //works fine on both c and c++ compilers

and I can't think of much else apart from malloc that does not work just fine in c++ (may warn, but no errors).
Thanks guys, probably a flag doesn't exist. I guess I would just go with compiling it twice, once for each language, or use extern "C" with #ifdefs.
While it's perfectly reasonable to compile the same file twice (once in C mode and once in C++ mode - e.g. gcc -x c++ file.c), as a useful sanity check, that will only flag C-isms that are invalid C++.

Unfortunately, there are C-isms that are valid, but different C++.

The best known one is the difference in the type of character literals:
 
printf("%zu", sizeof 'a'); // prints 1 in C++, 4 (or whatever sizeof(int) is) in C 
, but there are other, sneakier ones - I've seen such issues caused by differences of scoping rules of for-loops and structs between C and C++.

So in general, it is impossible to statically verify that a piece of code is written in C++-compatible subset of C.

It would make sense to put C and C++ in different compiler units

That's how it is normally done when a code base uses both C and C++, but the header files end up being shared between the two languages, and are subject to these compatiblity issues.
Last edited on
I'm starting to think the easier solution would be to just have two build setups (one for C, one for C++) instead of finding some obscure compiler setting, but still curious if there is one.
I can't imagine why such a setting would exist. The best way to see if code is valid C++ is to compile it with a C++ compiler.
Yep, and Cubbi's example solidifies that absolutely, it looks like. I hadn't even thought about something behaving differently.
I'll stick to doing it similar to how FFTW does it, with extern "C"
https://github.com/MangoTheCat/fftw3/blob/7c52cce9fe281fb4e1c8904947f34a34610cade6/src/fftw-3.3.4/kernel/ifftw.h
Topic archived. No new replies allowed.