Compatibility of C and C++ - Constructs Valid in C But Not in C++

Constructs Valid in C But Not in C++

One commonly encountered difference is that C allows a void* pointer to be assigned to any pointer type without a cast, whereas C++ does not; this idiom appears often in C code using malloc memory allocation. For example, the following is valid in C but not C++:

void* ptr; int *i = ptr; /* Implicit conversion from void* to int* */

or similarly:

int *j = malloc(sizeof(int) * 5); /* Implicit conversion from void* to int* */

In order to make the code compile in C++, one must use an explicit cast:

void* ptr; int *i = (int *) ptr; int *j = (int *) malloc(sizeof(int) * 5);

Another portability issue from C to C++ are the numerous additional keywords that C++ introduced. This makes C code that uses them as identifiers invalid in C++. For example:

struct template { int new; struct template* class; };

is valid C code, but is rejected by a C++ compiler, since the keywords "template", "new" and "class" are reserved.

C++ compilers prohibit using goto or switch from crossing an initialization, as in the following C99 code:

void fn(void) { goto flack; int i = 1; flack: ; }

There are many other C syntaxes which are invalid or behave differently in C++:

  • The comma operator can result in an "l-value" (a quantity that can be used for the left-hand side of an assignment) in C++, but not in C.
  • C does not allow a given typedef to be duplicated in the same scope, whereas C++ allows repeated typedefs.
  • Enumeration constants (enum values) are always of type int in C, whereas they are distinct types in C++ and may have size different from that of int.
  • C++ identifiers are not allowed to contain two or more consecutive underscores in any position. C identifiers are not allowed to start with two or more consecutive underscores, but may contain them in other positions.
  • C++ also changes some C standard library functions to add additional const qualifiers, e.g. strchr returns char* in C and const char* in C++.
  • In both C and C++ one can define nested struct types, but the scope is interpreted differently (in C++, a nested struct is defined only within the scope/namespace of the outer struct).
  • Non-prototype ("K&R"-style) function declarations are not allowed in C++, although they have also been deprecated in C since 1990. Similarly, implicit function declarations (using functions that have not been declared) are not allowed in C++, but have also been deprecated in C since 1999.
  • C allows struct, union, and enum types to be declared in function prototypes, whereas C++ does not.
  • A struct, union, or enum declaration in C++ usually implies an implicit typedef of the same name, while in C it does not.
  • In C, a function prototype without arguments, e.g. int foo;, implies that the parameters are unspecified. Therefore it is legal to call such a function with one or more arguments, e.g. foo(42, "hello world"). In contrast, in C++ a function prototype without arguments means that the function takes no arguments, and calling such a function with arguments is ill-formed. In C, the correct way to declare a function that takes no arguments is by using 'void', as in int foo(void);.
  • C++ is more strict than C about pointer assignments that discard a const qualifier (e.g. assigning a const int* value to an int* variable): in C++ this is invalid and generates a compiler error (unless an explicit typecast is used), whereas in C this is allowed (although many compilers emit a warning).

Read more about this topic:  Compatibility Of C And C++

Famous quotes containing the words constructs and/or valid:

    To me the “female principle” is, or at least historically has been, basically anarchic. It values order without constraint, rule by custom not by force. It has been the male who enforces order, who constructs power structures, who makes, enforces, and breaks laws.
    Ursula K. Le Guin (b. 1929)

    Just as soon as we notice that someone has to force himself to pay attention when dealing and talking with us, we have a valid demonstration that he does not love us or that he does not love us anymore.
    Friedrich Nietzsche (1844–1900)