A89: Re: Re: Re: tigcc - some REAL routines this time [OT]


[Prev][Next][Index][Thread]

A89: Re: Re: Re: tigcc - some REAL routines this time [OT]





> C is NOT a subset of C++, although 99% of C is a subset of C++.

>Example 1: In C, a function need not to have a prototype if the
>return type is int, and if all arguments are int. in C++, each
>function MUST have a prototype.

>Example 2: C++ has stronger type checking.

> Zeljko Juric
>

Well, I hoped no one would bring this up but you did :) I will have to
actually explain my view (dang it).

When I refer to C I will be refering to ISO C and when I refer to C++ I will
be refering to ANSI/ISO C++.

Example #1

int negate (n)
int n; /* parameter declaration  appears here*/
{
  return -n;
}

Even thought this was from the pre C standard it still will compile under C
compilors. It will not compile under C++ compilors. The function that would
be leagle in both C and C++ is:

int negate (int n)
{
  return -n;
}

Example #2

As Zeljko Juric said in C you do  not have to declare some functions, in C++
you do.

Example #3

In C, a function that is declared with an empty list of parameters such as

int f();
void g( int i)
{
  f(i)  /* valid in C but not in C++ */
}

can take any number of arguments of any type. In C++, such a function does
not take any arguments.

Example #4

In C and in pre-Standard C++, the default type for missing declarations is
int. For example

/* valid in C but not in C++ */
void  func()
{
  const k =0; /*int type assumed in C; invalid in C++*/
}

Example #5

In C, global variables can be declared more than once without the extern
specifier. As long as a single initialization (at most) for the same
variable is used, the linker resolves all the repeated declarations into a
single entity:

/* valid in C but not in C++ */
int flag;
int num;
int flag; /* repeated declaration of a global variable */
void func()
{
  flag = 1;
}

In C++, an entity must be defined exactly once. Repeated definitions of the
same entity in separate translation units result in a link-time error.

Example #6

In C, a void pointer is implicitly cast to any other pointer type in
assignments and initializations. For example

/* valid in C but not C++*/
#include <stdlib.h>
long * p_to_int()
{
  long * pl = malloc(sizeof(long)); /* implicit conversion of void* to long*
*/
  return pl;
}

In general, implicit conversion of void * is undesirable because it can
result in bugs that can otherwise be detected by the compiler. Consider the
following example:

/* valid in C but not C++*/
#include <stdlib.h>
long * p_to_int()
{
  long * pl = malloc(sizeof(short)); /* oops!  */
  return pl;
}
In C++, void pointers have to be cast explicitly to the desired type. The
explicit cast makes the programmer's intention clearer and reduces the
likelihood of unpleasant surprises.

Example # 7

NULL is an implementation-defined const null pointer. C implementations
usually define NULL as follows:

 #define NULL  ((void*)0)

However, In C++, NULL is usually defined as the literal 0 (or 0L), but never
as void *:

const int NULL = 0; file://some C++ implementations use this convention
#define NULL 0; file://others might use this convention

The difference in the underlying representations of NULL pointers between C
and C++ derives from the fact that C++ pointers are strongly typed, whereas
in C they are not. If C++ retained C's convention, a C++ statement such as

char * p = NULL;

would be expanded into something similar to

char * p = (void*) 0;   // compile time error: incompatible pointer types

Because 0 is the universal initializer for all pointer types in C++, it is
used instead the traditional C convention; in fact, many programmers simply
use the literal 0 or 0L instead of NULL.

Example #8

In C, the default linkage of global const variables is extern. An
uninitialized const variable is implicitly zero initialized. For example

/*** valid in C but not C++ ***/
/* file error_flag.h */
const int error; /*default extern linkage */
/*** end file ***/
#include"error_flag.h"
int func();
int main()
{
  int status = func();
  if( status == error)
  {
    /*do something */
  }
  return 0;
}

In C++, a global const variable that is not explicitly declared extern has
static linkage. In addition, a const variable must be initialized.

Example #9

In C, character arrays can be initialized with a string literal without the
null-terminating character. For example

/*** valid in C but not C++ ***/
const char message[5] =  "hello"; /* does not contain a null terminator */

In C++, character arrays that are initialized by a string literal must be
large enough to contain a null terminator.

Example #10

In C, the assignment of integers to an enumerated type is valid. For example

/*** valid in C but not C++ ***/
enum Status {good, bad};
void func()
{
  Status stat = 1;  /* integer assignment */
}

In C++, enums are strongly typed. Only enumerators of the same enum type can
be assigned to an enum variable. Explicit type casting is required
otherwise. For example

//C++
enum Status {good, bad};
void func()
{
  Status stat = static_cast<Status> (1);  // stat = bad
}

Example #11

In C, a struct can be defined in a function parameter list as well as in its
return type. For example

/*** valid in C but not C++ ***/
/* struct definition in return type and parameter list of a function */
struct Stat { int code; char msg[10];}
    logon (struct User { char username[8];  char pwd[8];} u );

In C++, this is illegal.

Example #12

A jump statement unconditionally transfers control. A jump statement is one
of the following: a goto statement, a transfer from the condition of a
switch statement to a case label, a break statement, a continue statement,
or a return statement. In C, the initialization of a variable can be skipped
by a jump statement, as in the following example:

/*** valid in C but not C++ ***/
int main()
{
  int n=1;
  switch(n)
  {
  case 0:
    int j=0;
    break;
  case 1: /* skip initialization of j */
    j++;  /* undefined */
    break;
  default:
    break;
  }
  return 0;
}

In C++, bypassing an initialization is illegal.

Example #13

In C, the size of an enumeration equals the sizeof(int). In C++, the
underlying type for an enumeration is not necessarily an int -- it can be
smaller. Furthermore, if an enumerator's value is too large to be
represented as an unsigned int, the implementation is allowed to use a
larger unit. For example enum { SIZE = 5000000000UL };

Example #14

In C, the result of applying the operator sizeof to a character constant --
for example, sizeof('c'); -- equals sizeof(int). In C++, on the other hand,
the expression sizeof('c'); equals sizeof(char).

Example #15

C and C++ compilers define the following macros:

__DATE__ /*a literal containing compilation date in the form "Apr 13 1998"
*/
__TIME__ /*a literal containing the compilation time in the form "10:01:07"
*/
__FILE__  /*a literal containing the name of the source file being compiled
*/
__LINE__ /* current line number in the source file */

C++ compilers exclusively define the following macro:

__cpluplus

Standard-compliant C compilers define the following macro symbol:

__STDC__

Whether a C++ compiler also defines the macro symbol __STDC__ is
implementation-dependent.

Example #14

In C, when control reaches the end of main() without encountering a return
statement, the effect is that of returning an undefined value to the
environment. In C++, however, main() implicitly executes a

return 0;

statement in this case.

**************************************************
**************************************************
**************************************************

Well, i Think that is enough. Even thought  I probably just killed my view
for all of you I still belive that C is a subset of C++. Althought I must
admit that they arn't 100% compatible.

    - ALT_255 - webmaster@communitycrc.org



References: