Where C and C++ Differ

By Alex Allain Gotchas for a C programmer using C++ Implicit Assignment from void* You cannot implicitly assign from a void* to any other type. For instance, the following is perfectly valid in C (in fact, it's arguably the int *x = malloc(sizeof(int) * 10); but it won't compile in C++. (Try it yourself!)



The explanation from Bjarne Stroustrup himself is that this isn't type safe. What this means is that you can have a void* that points to anything at all, and if you then assign the address stored in that void* to another pointer of a different type, there isn't any warning at all about it.



Consider the following: int an_int; void *void_pointer = &an_int; double *double_ptr = void_pointer; *double_ptr = 5; When you assign *double_ptr the value 5, it's writing 8 bytes of memory, but the integer variable an_int is only 4 bytes. Forcing a cast from a void pointer makes the programmer pay attention to these things. Freeing arrays: new[] and delete[] In C, there's only one major memory allocation function: malloc. You use it to allocate both single elements and arrays: int *x = malloc( sizeof(int) ); int *x_array = malloc( sizeof(int) * 10 ); and you always release the memory in the same way: free( x ); free( x_array ); In C++, however, memory allocation for arrays is somewhat different than for single objects; you use the new[] operator, and you must match calls to new[] with calls to delete[] (rather than to delete). int *x = new int; int *x_array = new int[10]; delete x; delete[] x_array; The short explanation is that when you have arrays of objects, delete[] will properly call the destructor for each element of the array, whereas delete will not. You must declare functions before use Although most good C code will follow this convention, in C++ it is strictly enforced that all functions must be declared before they are used. This code is valid C, but it is not valid C++: #include <stdio.h> int main() { foo(); return 0; } int foo() { printf( "Hello world" ); } Gotcha for a C++ programmer using C Structs and Enums You have to include the struct keyword before the name of the struct type to declare a struct: In C++, you could do this struct a_struct { int x; }; a_struct struct_instance; and have a new instance of a_struct called struct_instance. In C, however, we have to include the struct keyword when declaring struct_instance: struct a_struct struct_instance; In fact, a similar situation also holds for declaring enums: in C, you must include the keyword enum; in C++, you don't have to. As a side note, most C programmers get around this issue by using typedefs: typedef struct struct_name { /* variables */ } struct_name_t; Now you can declare a struct with struct_name_t struct_name_t_instance; But there is another gotcha for C++ programmers: you must still use the "struct struct_name" syntax to declare a struct member that is a pointer to the struct. typedef struct struct_name { struct struct_name instance; struct_name_t instance2; /* invalid! The typedef isn't defined yet */ } struct_name_t; C++ has a much larger library C++ has a much larger library than C, and some things may be automatically linked in by C++ when they are not with C. For instance, if you're used to using % g++ foo.cc or % gcc foo.c -lm No Boolean Type C does not provide a native boolean type. You can simulate it using an enum, though: typedef enum {FALSE, TRUE} bool; main Doesn't Provide return 0 Automatically In C++, you are free to leave off the statement 'return 0;' at the end of main; it will be provided automatically: int main() { printf( "Hello, World" ); } but in C, you must manually add it: int main() { printf( "Hello, World" ); return 0; } C++ was based on C and retains a great deal of the functionality. C++ does not retain complete source-level compatibility with C. There are a few gotchas for C++ programmers trying to write C code, and C programmers trying to compile with a C++ compiler.You cannot implicitly assign from a void* to any other type. For instance, the following is perfectly valid in C (in fact, it's arguably the preferable way of doing it in C)but it won't compile in C++. (Try it yourself!)The explanation from Bjarne Stroustrup himself is that this isn't type safe. What this means is that you can have a void* that points to anything at all, and if you then assign the address stored in that void* to another pointer of a different type, there isn't any warning at all about it.Consider the following:When you assign *double_ptr the value 5, it's writing 8 bytes of memory, but the integer variable an_int is only 4 bytes. Forcing a cast from a void pointer makes the programmer pay attention to these things.In C, there's only one major memory allocation function: malloc. You use it to allocate both single elements and arrays:and you always release the memory in the same way:In C++, however, memory allocation for arrays is somewhat different than for single objects; you use the new[] operator, and you must match calls to new[] with calls to delete[] (rather than to delete).The short explanation is that when you have arrays of objects, delete[] will properly call the destructor for each element of the array, whereas delete will not.Although most good C code will follow this convention, in C++ it is strictly enforced that all functions must be declared before they are used. This code is valid C, but it is not valid C++:You have to include the struct keyword before the name of the struct type to declare a struct: In C++, you could do thisand have a new instance of a_struct called struct_instance. In C, however, we have to include the struct keyword when declaring struct_instance:In fact, a similar situation also holds for declaring enums: in C, you must include the keyword enum; in C++, you don't have to. As a side note, most C programmers get around this issue by using typedefs:Now you can declare a struct withBut there is another gotcha for C++ programmers: you must still use the "struct struct_name" syntax to declare a struct member that is a pointer to the struct.C++ has a much larger library than C, and some things may be automatically linked in by C++ when they are not with C. For instance, if you're used to using g++ for math-heavy computations, then it may come as a shock that when you are using gcc to compile C, you need to explicitly include the math library for things like sin or even sqrt:C does not provide a native boolean type. You can simulate it using an enum, though:In C++, you are free to leave off the statement 'return 0;' at the end of main; it will be provided automatically:but in C, you must manually add it:





