How C is not a subset of C++ compiler pedantry 2017-3-10

It is often said C is a subset of C++. I’m going to show how that isn’t strictly true.

The two following code examples look like they should be C-subset-of-C++ that will compile in C and C++, but will in fact only compile for one language. The differences in one cause compilation errors in the other language, while shared code produces different behaviors. Comments in the code explain the differences.

This will only compile in C:

/*This will compile in C but not C++*/ #include <stdlib.h> #include <stdio.h> /* C can have multiple declarations, not C++ */ int test; int test; int test = 1; int test; double db; void func() { struct db { int a; int b; int c; int d; int e; int f; }; /* Size of struct in C++. Size of double in C. */ int x = sizeof(db); /*hides double in C++*/ printf("%d

", x); /* Size of char in C++. Size of int in C. */ int y = sizeof('a'); printf("%d

", y); /* You can call main in C, not in C++. Also, don't need a prototype for a function in C, but you do in C++. */ main(); } /*Types can be defined in return or argument types in C, not in C++*/ void print(struct X { int i;} x); int main(void) { /* initializing an array without enough room for the trailing nul is an error in C++ but will compile in C */ char b[3] = "Bob"; /* typedef and struct tag names can have same name in C, not in C++ */ typedef double db; struct db; /*error in C++, valid C*/ struct st { db x; double db;/*error in C++, valid C*/ }; /* Trivial, but C++ keywords that aren't used in C can be identifiers. */ int new = 0; /* C can have an implicit conversion from a void* pointer in C, C++ needs a cast */ char *str = malloc(10); if(test) { test = 0; /* A function in C defined with empty params int f(); can take any number of argument of any type. C++ takes this to mean no arguments and will throw a compilation error if one is passed. */ func(b); } return 0; }

This will only compile in C++: