C este un subset C++; teoretic, orice program valid C este, de asemenea, un program valid C++. Si totusi, in practica, exista incompatibilitati subtile; unele dintre acestea pot fi diagnosticate de catre compilator, in timp ce altele pot produce efecte surprinzatoare. Aceste incompatibilitati sunt cauzate de diferentele dintre ISO C si subsetul C din ANSI/ISO C++.

  1. Lista parametrilor unei functii
  2. Declararea unei functii
  3. Lista vida de parametri
  4. Tipul implicit pentru declaratiile lipsa
  5. Declaratii repetate ale variabilelor globale
  6. Conversia implicita a pointerilor de tip void*
  7. Reprezentarea interna a pointerilor NULL
  8. Linkage implicit pentru constantele globale
  9. Tablouri de caractere terminate cu NUL
  10. Atribuirea de intregi tipurilor enum
  11. Definirea structurilor in lista parametrilor unei functii sau in tipul returnat
  12. Dimensiunea unei constante caracter
  13. Valoarea returnata de main()
  1. Lista parametrilor unei functii

  2. In pre-standard C lista parametrilor unei functii se putea preciza astfel:
    
    int negate(n)
    int n;
    {
      return -n;
    }
    
    Acest stil vechi este inca legal in ISO C; in C++ este ilegal!
  3. Declararea unei functii

  4. In C este doar recomandat, nu si obligatoriu, ca o functie, pentru a fi apelata, sa i se precizeze anterior declaratia (prototipul). In C++ o functie nu poate fi apelata fara o declaratie anterioara. Din acest motiv urmatoarea secventa de cod este valida in C si invalida in C++:
    
    int main(){
      int n;
      n=negate(5);
      return 0;
    }
    
  5. Lista vida de parametri

  6. O functie declarata cu o lista vida de parametri poate avea, in C, orice numar de argumente, de orice tip. In C++ o astfel de functie nu accepta argumente.
    
    int f();
    void g(int i){
      f(i); /* valid in C, dar nu si in C++ */
    }
    
  7. Tipul implicit pentru declaratiile lipsa

  8. 
    /* valid in C, dar nu si in C++ */
    void func(){
      const k=0; /* in C, implicit int; invalid in C++*/
    }
    
    ISO C este in proces de revizie astfel incat declaratiile implicite int sa nu mai fie permise.
  9. Declaratii repetate ale variabilelor globale

  10. In C o variabila globala poate fi declarata de mai multe ori, fara a utiliza specificatorul extern. In C++ o variabila globala poate fi definita o singura data; definitii repetate in unitati de traducere distincte conduc la erori de link-editare.
    
    /* valid in C, dar nu si in C++ */
    int flag;
    int num;
    int flag; /* definitie repetata */
    
  11. Conversia implicita a pointerilor de tip void*

  12. In C, un pointer void* este implicit convertit spre orice alt tip in atribuiri si initializari. De exemplu:
    
    long *pl=malloc(sizeof(long)); /* conversie implicita din void* in long* */
    
    In general, aceste conversii implicite sunt nedorite deoarece pot conduce la bug-uri:
    
    long *pl=malloc(sizeof(short)); /* oops! */
    
    In C++ pointerii de tip void* trebuie convertiti in mod explicit la tipul dorit!
  13. Reprezentarea interna a pointerilor NULL

  14. NULL este un pointer constant cu o definitie dependenta de implementare; in C el este definit in mod uzual prin:
    
    #define NULL ((void*)0)
    
    In C++, deoarece pointerii sunt tare tipizati, daca aceasta conventie ar fi pastrata, atunci o instructiune
    
    char* p=NULL;
    
    ar fi expandata in
    
    char* p=(void*)0;
    
    ceea ce ar genera eroare la compilare!
    Din acest motiv NULL este definit in unele implementari C++ ca fiind const int NULL=0 iar in altele #define NULL 0.
  15. Linkage implicit pentru constantele globale

  16. In C o constanta globala are linkage extern; in plus, ea este initializata implicit cu 0.
    In C++ o constanta globala (nedeclarata explicit cu extern) are linkage intern si trebuie initializata!
  17. Tablouri de caractere terminate cu caracterul NUL

  18. In C un tablou de caractere poate fi initializat cu un literal a.i. el sa nu contina si caracterul terminator.
    In C++ tabloul trebuie sa fie suficient de mare pentru a contine si caracterul '\0'(NUL)!
    
    const char message[5]="hello"; /* message nu contine '/0'; valid in C, dar nu si in C++ */
    
  19. Atribuirea de intregi tipurilor enum

  20. Deoarece C++ este tare tipizat, nu mai este permisa atribuirea de intregi variabilelor de tip enum fara a utiliza o conversie explicita!
  21. Definirea structurilor in lista parametrilor unei functii sau in tipul returnat

  22. Nu mai este legala in C++.
  23. Dimensiunea unei constante caracter

  24. In C sizeof('a')==sizeof(int). In C++ sizeof('a')==sizeof(char).
  25. Valoarea returnata de main()

  26. In C, terminarea functiei main() fara a executa o instructiune return determina returnarea unei valori nedefinite catre mediu. In C++, main() executa implicit un return 0 intr-un astfel de caz!