C versus C++

This is important to AJAX where C++ data structures and concepts are in some cases being implemented in ANSI C.

Much of this detail is from C++ books that describe how to make C code compile with a C++ compiler.

Much of it turns out to be differences with "non-ANSI" (classic) C, which should be avoided anyway. They are related to the much stronger type checking available in ANSI C.

Function calls

C++ has class scope. For C there needs to be some naming convention to avoid clashes. The C++ compilers do this by adding extra characters to the function names internally ("name mangling"). For C it must be explicit.

For example, in C++:

	double Internal::sense (int a,
                                unsigned char *text,
				Internal &p, ...);
becomes:
	_sense__8InternaliPUcR8Internale
derived from:
        _sense__      _name__
	8Internal     (namelen) class
	i             int
	PUc           Ptr-Unsigned-char
	R8Internal    Reference (namelen) class
	e             ellipses
so these names can get very long (and quite silly).

Using static functions in C helps to hide function names that may be used in other places.

Function parameters must be defined in the ANSI C style for C++.

Function prototypes should go in header files. They are compulsory for C++ and can be enforced with compilation options in C. (OSF: -warnprotos GNU: -Wstrict-prototypes -Wmissing-prototypes -Wconversion)

C++ allows call-by-reference where C requires the pointer to be passed and explicitly dereferenced when used.

Variable arguments uses <stdarg.h> in C++ and <varargs.h> in C. C++ and ANSI C both require at least one parameter of known type.

Pointers to functions are the same in C++ and ANSI C.

Parameterless functions can (and should) be declared with (void) in both C++ and ANSI C.

Use of const

const can replace #define for constants, and allows more checking by the compiler. This should work also in ANSI C.

const can also be used with pointers and strict prototyping to ensure that the data value is not changed when pointers are pased around. This involves using const twice, for example:

	const char *const msg = "string";
The first const prevents the value "string" being changed. The second prevents the pointer "msg" being reassigned to point somewhere else.

The big headache with this is that once started, const *must* be used in all function calls. Otherwise somewhere down the line a function withou the "const" will be assumed by the compiler (from its prototype) to be capable of changing the pointer or its value and the call will result in compile-time error.

This can be avoided with a (char *) cast in the function call, but if the function prototypes have const for all unchanged pointers/data, and if there is no cheating going on with casts the results should be much improved type checking of code.

Sadly, a similar replacement of ANSI C macros with C++ inline functions is not available. "inline" is in C++ only.

Dynamic memory allocation

ANSI C uses malloc and free, called explicitly when needed. C++ uses new and delete constructors and destructors, which are invoked automatically. So long as these are kept together, even in mixed C++ and ANSI C applications all should be well.

Could be useful though to mimic the C++ behaviour for data structures, with a "XxxNew" and "XxxDel" function for each one.