The Mi­nor Dif­fer­ences Be­tween C and C++

This ar­ti­cle dis­cusses the sub­tle and minute dif­fer­ences be­tween C and C++.

OpenSource For You - - Contents -

An ar­ti­cle ti­tled ‘Ma­jor Dif­fer­ences Be­tween C and C++’ would have been quite ridicu­lous be­cause every­body knows that C and C++ are two in­de­pen­dent pro­gram­ming lan­guages, both backed by com­mu­ni­ties that are quite fa­nat­i­cal in their sup­port for their re­spec­tive pref­er­ence. There will prob­a­bly be a small group of novice pro­gram­mers who still post ques­tions in Stack­Over­flow with the tag ‘C/ C++’ and will get panned uni­ver­sally by pro­fes­sional pro­gram­mers be­long­ing to both the camps. In this ar­ti­cle, I plan to point out a few sub­tle dif­fer­ences be­tween C and C++, al­to­gether avoid­ing the ma­jor dif­fer­ences like C be­ing an im­per­a­tive pro­gram­ming lan­guage whereas C++ is an ob­ject-ori­ented pro­gram­ming lan­guage. This ar­ti­cle tries to point out that even though text books of­ten de­fine C++ as a su­per­set of C, even that part of C++ that is a sub­set of C is slightly dif­fer­ent from tra­di­tional C.

I will try to prove the ex­is­tence of such minute dif­fer­ences be­tween C and C++ that of­ten es­cape the no­tice of even sea­soned pro­gram­mers with a small ex­am­ple. This is a ques­tion I have asked re­cently in a pro­gram­ming com­pe­ti­tion: “Write an er­ror-free C pro­gram that will give an er­ror when compiled as a C++ pro­gram.” Since the clas­si­cal def­i­ni­tion of C++ says that it is a su­per­set of C, ev­ery C pro­gram should also com­pile as a C++ pro­gram with­out any er­rors. This might be the case the­o­ret­i­cally though not so prac­ti­cally. The fol­low­ing pro­gram Ex­am­ple 1 fails when compiled with the g++ com­piler as a C++ pro­gram, but when compiled as a C pro­gram with the gcc com­piler, it com­piles suc­cess­fully.

#in­clude<stdio.h> int main()

{

int class;

}

Ex­am­ple 1

What is the rea­son for the er­ror when compiled as a C++ pro­gram? That’s very sim­ple—the key­word class in C++ can be used as a vari­able name in C. But to crown it all, the first prize went to a pro­gram­ming whizz-kid who knew that anony­mous struc­tures are okay in C but will lead to an er­ror in C++. The pro­gram Ex­am­ple 2 with an anony­mous struc­ture will com­pile as a C pro­gram with a warn­ing, whereas in C++ the pro­gram will re­sult in an er­ror. All the pro­grams in this ar­ti­cle are compiled as C pro­grams with gcc and as C++ pro­grams with g++.

#in­clude<stdio.h>

struct {

int a;

};

int main() {

}

Ex­am­ple 2

There are many such ex­am­ples where C and C++ show their dif­fer­ences in the least ex­pected places. For ex­am­ple, the pro­gram Ex­am­ple 3 will dis­play dif­fer­ent out­puts on the screen when compiled as C and C++ pro­grams.

#in­clude<stdio.h> int main()

{

int i,j; i=sizeof(‘a’); i=--i/3*32+65; for(j=i;j<i+26;j++) {

printf(“%c “,j); } printf(“\n”);

} Ex­am­ple 3

The pro­gram when compiled as a C pro­gram will out­put the lower case let­ters, and the same pro­gram will out­put up­per case let­ters when compiled as a C++ pro­gram. This is due to the fact that the size of a char­ac­ter lit­eral is 4 bytes in C and 1 byte in C++, be­cause C treats a char­ac­ter lit­eral as in­te­ger type and C++ treats a char­ac­ter lit­eral as char­ac­ter type. Fig­ure 1 shows the out­put of the pro­gram ex­e­cu­tion as C and as C++.

Fig­ure 1: C and C++ out­puts

In C, by de­fault, the re­turn type of a func­tion is an in­te­ger. But this de­fault to the int rule is not valid in C++. You have to men­tion the re­turn type as in­te­ger ex­plic­itly. Due to this, the pro­gram Ex­am­ple 4 will show an er­ror when compiled as a C++ pro­gram.

#in­clude<stdio.h>

fun() {

}

int main() { fun();

} Ex­am­ple 4

In C, an empty func­tion pro­to­type tells the com­piler that the func­tion can have any num­ber of arguments. But in C++, it means the func­tion can­not take any arguments. For ex­am­ple, the func­tion dec­la­ra­tion int fun( ); in C can re­ceive zero or more arguments, whereas in C++, this func­tion has zero arguments. The pro­gram Ex­am­ple 5 shows an er­ror when compiled as a C++ pro­gram.

#in­clude<stdio.h> int fun(); int main()

{

fun(123); } int fun(int n) { printf(“\n Num­ber is %d\n”,n);

}

Ex­am­ple 5

The unary in­cre­ment and decre­ment op­er­a­tors in C++ re­turn an lvalue. But in C, they re­turn an rvalue. So (++i)++; is valid in C++ but it will lead to an er­ror in C. The pro­gram Ex­am­ple 6 will show the er­ror mes­sage ‘lvalue re­quired’ in C whereas in C++, the pro­gram will suc­cess­fully com­pile and show the out­put as ‘i= 3’.

#in­clude<stdio.h>

int main() { int i=1;

(++i)++; printf("\ni = %d\n",i); } Ex­am­ple 6

In C, we can­not get the ad­dress of a reg­is­ter vari­able. But in C++, it is pos­si­ble to get the ad­dress of a reg­is­ter vari­able. The pro­gram Ex­am­ple 7 is not an er­ror-free C pro­gram but when compiled as C++, the pro­gram runs with­out any er­rors.

#in­clude<stdio.h>

int main()

{ reg­is­ter int x=123; printf(“\n Ad­dress of x = %u\n”,&x); } Ex­am­ple 7

In C and C++, static vari­able ini­tial­i­sa­tion is dif­fer­ent. In C, static vari­ables can only be ini­tialised with con­stant val­ues whereas in C++, this is not nec­es­sary. The pro­gram Ex­am­ple 8 will not com­pile as a C pro­gram but it is valid when compiled with g++ as a C++ pro­gram.

#in­clude<stdio.h>

int main() { int x=123; static int y=x; printf(“\ny = %d\n”,y); } Ex­am­ple 8

The way case la­bels are treated in C and C++ is dif­fer­ent. C++ al­lows con­stant in­te­ger vari­ables as case la­bels, whereas C will give you an er­ror. The pro­gram Ex­am­ple 9 will give an er­ror as a C pro­gram but as a C++ pro­gram, it com­piles with­out any er­rors.

#in­clude<stdio.h>

int main() {

int i=1; const int j=1; switch(i)

{

case j: printf(“\nWorks for C++\n”); break; case 2: printf(“\nEr­ror for C\n”); break; de­fault:

printf(“\nCheck by com­pil­ing\n”); } } Ex­am­ple 9

In C, unini­tialised con­stant vari­ables are just fine but these will lead to an er­ror in the case of C++. For ex­am­ple, a pro­gram with the line of code const int a; will com­pile fine as

a C pro­gram, whereas it will show a com­pile time er­ror when compiled as C++ and dis­play the er­ror mes­sage unini­tial­ized const. An­other dif­fer­ence arises when the key­word type­def is used in C and C++. C++ treats the names of struct, union, enum, etc, as im­plicit type­def names. This is not the case with C, so pro­gram Ex­am­ple 10 is a valid C pro­gram, whereas if compiled as a C++ pro­gram, you will get the er­ror mes­sage us­ing type­def-name ‘type’ af­ter ‘struct’.

#in­clude<stdio.h>

type­def int type; struct type

{ type a; }; struct type sv;

int main() {

} Ex­am­ple 10

In C, a pointer of type void is au­to­mat­i­cally cast into the tar­get pointer type when as­signed to a pointer of any other type. So, there is no need for ex­plicit type-cast­ing in C. Whereas in C++, ex­plicit type-cast­ing is re­quired when a void pointer is as­signed to a pointer of an­other type. So, the line int *ptr = mal­loc(sizeof(int)); is fine in C, whereas in C++, you will get the com­pile time er­ror mes­sage: in­valid con­ver­sion from ‘void*’ to ‘int*’. You can down­load this and all the other pro­grams dis­cussed in this ar­ti­cle from open­source­foru.com/ar­ti­cle_­source_­code/june17cPlus.zip. To save some space, I haven’t used any code other than the fea­ture be­ing dis­cussed in many of the pro­grams. But you can add any valid C or C++ code in all these pro­grams.

K& R style func­tion def­i­ni­tions are still valid in C. But this will lead to an er­ror in case of C++. So, the pro­gram Ex­am­ple 11 is a valid C pro­gram but it is not a valid C++ pro­gram.

#in­clude<stdio.h> void fun(a, b) int a; int b;

{

printf(“\na = %d \nb = %d\n”,a,b); } int main() { fun(11,22);

} Ex­am­ple 11

Newspapers in English

Newspapers from India

© PressReader. All rights reserved.