C/C++ Arena

Step 7 of 7

Where C and C++ differ

C++ grew out of C, and most C code is also valid C++. But the languages have been developed separately for decades, and some differences bite when you move code between them or mix them in one project.

C C++
void * to another pointer converts automatically: int *p = malloc(n); needs a cast (or better, new, std::vector, std::make_unique)
void f() "unspecified arguments" before C23; write void f(void) no arguments, same as f(void)
struct Point the type is struct Point, unless you add a typedef the type is just Point
sizeof('a') sizeof(int), usually 4: a character literal is an int 1: it's a char
variable-length arrays int a[n]; standard in C99, optional since C11 not standard; GCC and Clang accept them as an extension (Clang warns)
designated initializers any order, nested, and for arrays: {.y = 2, .x = 1}, [3] = 7 C++20, but only in declaration order and not for arrays (GCC rejects {.y = 2, .x = 1}, Clang warns)
string literal type char[N] (writing to it is still undefined) const char[N]
a const global visible to other files private to its file unless marked extern
bool, true, false from <stdbool.h> before C23, keywords since keywords
new, class, delete, this ordinary names you can use for variables reserved keywords
#include <cstdlib>
#include <iostream>

struct Point {
    int x;
    int y;
};

int main() {
    Point p{.x = 1, .y = 2};                                        // designators in declaration order
    int* nums = static_cast<int*>(std::malloc(3 * sizeof(int)));    // C++ needs the cast from void*
    if (!nums) return 1;
    nums[0] = p.x + p.y;
    std::cout << sizeof('a') << " " << nums[0] << "\n";              // 1: a char literal is a char
    std::free(nums);
}
1 3

Mixing C and C++ in one program

A C library can be used from C++ (the extern "C" section in the design patterns module shows how the headers make that work), and C++ can offer functions that C calls. What can't cross the boundary is C++-only machinery: classes with constructors, references, templates, overloading and exceptions. So libraries meant for both languages expose a plain C interface and use C++ inside.

In C++ code, prefer the C++ versions of C headers (<cstdlib>, <cstring>, <cstdio>), which put the names in namespace std, and prefer C++ facilities over C ones: std::string over char arrays, std::vector over malloc, streams or std::format over printf.

Your turn: this code was copied from a C project, and it doesn't compile as C++. Fix make_buffer so it compiles and works: Buffer's designated initializers must follow the declaration order, and malloc's result needs a cast. Keep free_buffer as it is.

Previous: Whole lines with getline