Awesome list. I think the list missed this one: in C++, if an enum is defined inside a struct, its values are namespaced. Whereas in C, the enum values are in the global namespace (i.e. C’s only namespace).
struct S {
enum { E } e;
};
struct S s;
s.e = E; // OK in C, error in C++
s.e = S::E; // OK in C++, error in C
Code that compiles as one out of C or C++ and is an error in the other.
Code that compiles as C/C++ but has different semantics.
The first of these is not very interesting because 90% of C++ is in this category. The second is a lot more interesting. In particular, things like void foo() are very bad because they disable type checking on arguments and force the K&R calling convention in C, whereas in C++ they are equivalent to void foo(void). C23 is fixing this and making it an error in C.
The typical examples of mismatched semantics depend on the fact that C++ doesn’t require tags for referencing struct definitions and so expressions such as sizeof that take a size or a type will see a different value depending on the language.
I think that dropping file extensions from C++ standard library headers was one of the biggest mistakes that the original C++ standard made. It would be much better to have three different extensions for C, C++ and C/C++ headers. Hopefully the modules tooling will grow support for importing C headers (e.g. the Linux kernel headers that use a lot of syntax that is invalid C++ but that don’t do anything that you can’t map to a C++ AST).
Awesome list. I think the list missed this one: in C++, if an
enum
is defined inside astruct
, its values are namespaced. Whereas in C, theenum
values are in the global namespace (i.e. C’s only namespace).The article mixed a couple of things together:
The first of these is not very interesting because 90% of C++ is in this category. The second is a lot more interesting. In particular, things like
void foo()
are very bad because they disable type checking on arguments and force the K&R calling convention in C, whereas in C++ they are equivalent tovoid foo(void)
. C23 is fixing this and making it an error in C.The typical examples of mismatched semantics depend on the fact that C++ doesn’t require tags for referencing
struct
definitions and so expressions such assizeof
that take a size or a type will see a different value depending on the language.I think that dropping file extensions from C++ standard library headers was one of the biggest mistakes that the original C++ standard made. It would be much better to have three different extensions for C, C++ and C/C++ headers. Hopefully the modules tooling will grow support for importing C headers (e.g. the Linux kernel headers that use a lot of syntax that is invalid C++ but that don’t do anything that you can’t map to a C++ AST).