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\n", x);
/*
Size of char in C++.
Size of int in C.
*/
int y = sizeof('a');
printf("%d\n", 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++:
/*This will compile in C++ but not C*/
#include <stdio.h>
/* prototype required in C++ if not defined yet */
void func(void);
int main(void) {
/*
C99 has variable-length arrays, but can't be initialized
*/
const int size=4;
char b[size] = "Bob";
func();
return 0;
}
double db;
void func(void) {
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\n", x);
/*
Size of char in C++.
Size of int in C.
*/
int y = sizeof('a');
printf("%d\n", y);
}