http://www.pronix.de -> Forum -> Knobelecke

Forum: Knobelecke

Moderatoren: broesel, juergen

Thema: C / C++

Re: C / C++

icefire am 01.07.2010 um 21:08

Hi,

Hab grad die Keyword-Listen von C99 und C++ 2003 verglichen (Seite 51 bzw. Seite 14).

C-Code mit den Keywords restrict, _Bool, _Complex und _Imaginary dürfte unter C++ nicht funktionieren.

Ich schlag also mal das erste Beispiel des restrict-Kapitels aus dem C99-Dokument als Rätsellösung vor:


void f(int n, int * restrict p, int * restrict q)
{
while (n-- > 0)
*p++ = *q++;
}


mfg, Wolfgang

--
Hex, Bugs and Rock 'n Roll

 

Re: C / C++

broesel (webmaster) am 02.07.2010 um 09:18

Oh super, daran hatte ich gar nicht gedacht. Ich hab den Code mal aufs Wesentliche gekürzt:


int main(int argc, char * restrict argv[]) { }



Bei meinem C-Compiler (gcc version 4.5.0 20100610 (prerelease)) muss ich explizit --std=c99 angeben, um keinen Error zu erhalten. Ist das bei euch auch so?

Zu typedef + struct/union/enum:
Typdefinitionen mit typedef dürfen in C wiederholt werden, nicht in C++; das hilft uns bei diesem Rätsel aber nicht weiter. struct/enum/union sind in C++ Typen erster Klasse, nicht in C, das wird also auch nicht helfen. Aber in C sind Typdeklarationen mit struct/enum/union in Funktionsprototypen erlaubt, in C++ nicht. Damit erhalten wir:


int f(enum {foo} bar);
int main(void) {}


Mein gcc spuckt dazu übrigens eine liebenswürdige Meldung aus:

enum.c:1:13: warning: anonymous enum declared inside parameter list
enum.c:1:13: warning: its scope is only this definition or declaration, which is probably not what you want



Wir haben also bisher:

- Reservierte Schlüsselwörter in C++, aber nicht in C
- Reservierte Schlüsselwörter in C, aber nicht in C++
- enum/struct/union-Deklaration in Funktionsprototyp

Und bevor sich jetzt jemand auf Dinge stürzt, die noch nutzloser sind als eine enum-Definition in einem Funktionsprototyp: es gibt noch eklatante Unterschiede zwischen C und C++, auf die man mit ganz gewöhnlichem C-Code stossen kann.

Jemand eine Idee? Grafik: Smilie Gluecklich

Gruss,
Philip

--
The C Programming Quiz (externer link) - bitte Fragen einreichen :)

 

Re: C / C++

Anonym am 02.07.2010 um 09:51

Hi,
C++ ist um einiges penibler als C wenn es um Typkonvertierungen geht. C++ verlangt z.B. einen expliziten Cast wenn man einen void* z.B. einem double* zuweisen will.

#include <stdlib.h>

int main ( void )
{
    double *const values = calloc ( 1000, sizeof ( *values ) );
    
    if ( values )
        free (values);

    return EXIT_SUCCESS;
}


Gleiches gilt wenn man einem enum Typ direkt einen int zuweist.
 

Re: C / C++

broesel (webmaster) am 03.07.2010 um 01:14

Na endlich! In C wird void* in den jeweils passenden Pointertyp konvertiert, in C++ nicht. Typisches Beispiel sind, wie oben erwähnt, malloc() bzw. calloc().

Hier wieder eine minimale Version:


int main(void) { void *p; int *i = p; }


Wir haben bislang also:

- Reservierte Schlüsselwörter in C++, aber nicht in C
- Reservierte Schlüsselwörter in C, aber nicht in C++
- enum/struct/union-Deklaration in Funktionsprototyp
- Impliziter void*-Cast

Einen letzten "einfachen" hab ich noch, und noch ein simpler der aber schwer zu finden ist.

Wer hat noch Lust? ;)

Gruss,
Philip

--
The C Programming Quiz (externer link) - bitte Fragen einreichen :)

 

[EDIT] - Re: C / C++

jengelh am 04.07.2010 um 22:33

Zitat:

Oft wird ja behauptet, C++ sei eine Obermenge von C, oder C sei vollständig in C++ enthalten.

Ja ja... ein Apfel ist auch keine Birne nur weil sie beide an Bäumen wachsen. Java ist auch keine Obermenge von C, obwohl es - wie C++ - syntaktische Ähnlichkeiten gibt; mal mehr mal weniger.
Weitere Codes, die C, aber nicht C++ sind:
C99 Compound Literals

struct foo { int x; };
void callme(struct foo *x)
{
}
int main(int argc, char **argv)
{
        callme(&(struct foo){.x = 2});
        return 0;
}

C99 Designated Initializers:

struct { int x; } b = {.x = 5};

C99 Hex Floats:

double x = 0x1.fp3;

C99 zero-size arrays:

struct { int x; int y[]; } z;

C99 VLAs:

int main(int argc, char **argv)
{
        int q[argc];
        return 0;
}