Forum: Compiler & IDEs Funktionsaufruf besser lesbar machen


von Peter Z. (Gast)


Lesenswert?

Hallo,

ich habe eine Funktion der Art:
1
void LCD_Anzeige_Zahl(unsigned char line,unsigned char xpos,unsigned long long int Zahl,unsigned char Stellen,unsigned char Komma)

Aufgerufen wird das z.B. so:
1
LCD_Anzeige_Zahl(3,7,Messwert,4,1);
Wie kann ich den Aufruf besser lesbar machen, ohne dem µC mehr Code zu 
verpassen?

von Peter II (Gast)


Lesenswert?

Peter Zz schrieb:
> Wie kann ich den Aufruf besser lesbar machen, ohne dem µC mehr Code zu
> verpassen?

was ist daran nicht gut lesbar?

von Ralf G. (ralg)


Lesenswert?

Der Aufruf ist okay. Evtl. kann man beim Prototypen die einzelnen 
Parameter untereinander anordnen.

von Falk S. (falkschilling)


Lesenswert?

Wie wär's z.B. so (C99):
1
typedef struct
2
{
3
  unsigned char x;
4
  unsigned char y;
5
} t_pos;
6
7
typedef struct
8
{
9
  unsigned long long Zahl;
10
  unsigned char Stellen;
11
  unsigned char Komma;
12
} t_number;
13
14
void LCD_Anzeige_Zahl(t_pos p, t_number num )
15
{
16
  printf("Pos: (%d,%d)\n", p.x, p.y );
17
  printf("Zahl: %d, Stellen: %d, Komma: %d\n", (int)num.Zahl, num.Stellen, num.Komma);
18
}
19
20
int main(int argc, char** argv)
21
{
22
  unsigned long long val = 123ULL;
23
  LCD_Anzeige_Zahl( (t_pos){.x = 3, .y = 7}, (t_number) { .Zahl = val, .Stellen=4, .Komma=1 });
24
25
  // bzw. ohne designated initialer
26
  LCD_Anzeige_Zahl( (t_pos){3, 7}, (t_number) { val, 4, 1 });
27
28
  return 0;
29
}

: Bearbeitet durch User
von Rufus Τ. F. (rufus) Benutzerseite


Lesenswert?

Falk Schilling schrieb:
> LCD_Anzeige_Zahl( (t_pos){.x = 3, .y = 7}, (t_number) { .Zahl = val,
> .Stellen=4, .Komma=1 });

Das unterstützt bei weitem nicht jeder C-Compiler.

von Falk S. (falkschilling)


Lesenswert?

Rufus Τ. Firefly schrieb:
> Falk Schilling schrieb:
>> LCD_Anzeige_Zahl( (t_pos){.x = 3, .y = 7}, (t_number) { .Zahl = val,
>> .Stellen=4, .Komma=1 });
>
> Das unterstützt bei weitem nicht jeder C-Compiler.

Schon möglich, beim MS-C-Compiler z.B. ist die Zeit ja auch in den 90ern 
stehengeblieben und der kann das nicht.
Mit'm GCC sollte es aber gehen und das ziemlich plattformunabhängig.

Finde es aber 'nen praktischen Ansatz, die structs auf'n Stack als 
automatische Variablen initialisieren zu können, gerade bei kleinen 
Microcontrollern.

von MrC (Gast)


Lesenswert?

Rufus Τ. Firefly schrieb:
> Falk Schilling schrieb:
>> LCD_Anzeige_Zahl( (t_pos){.x = 3, .y = 7}, (t_number) { .Zahl = val,
>> .Stellen=4, .Komma=1 });
>
> Das unterstützt bei weitem nicht jeder C-Compiler.

Deswegen ist der Ansatz von Falk, eine Struktur zu benutzen aber 
trotzdem der richtige Weg. Wird die Struktur zu groß, kann auch ein 
Pointer auf dieselbe übergeben werden.

von Falk S. (falkschilling)


Lesenswert?

Geht auch mit Unions und Bitsets beim GCC, falls es mal jemand braucht:
1
typedef union
2
{
3
  short blub;
4
  unsigned char bla[2];
5
} t_test
6
7
8
void UnionTest(t_test a
9
{
10
  printf("Short: %d\n", a.blub );
11
  printf("High: 0x%x, Low: 0x%x\n", a.bla[1], a.bla[0]);
12
}
13
14
int main(int argc, char** argv)
15
{
16
  UnionTest( (t_test) { .blub = 1000 });
17
  UnionTest( (t_test) { .bla = { 0xE8, 0x3} } );                      
18
19
  return 0;
20
}

von Rufus Τ. F. (rufus) Benutzerseite


Lesenswert?

Naja, noch wissen wir überhaupt nicht, was für "Peter Zz" nun 
"lesbarer" sein mag. Das sind ja alles nur Vermutungen, also sollten wir 
warten, bis sich "Peter Zz" wieder meldet und erwähnt, worin für ihn 
die schlechte Lesbarkeit liegt.

Auf ganz einfacher Ebene wird sein Beispiel durch Einfügen von 
Leerzeichen an den richtigen Stellen schon lesbarer:
1
Statt
2
3
  LCD_Anzeige_Zahl(3,7,Messwert,4,1);
4
5
so:
6
7
  LCD_Anzeige_Zahl(3, 7, Messwert, 4, 1);

Es gibt auch Zeitgenossen, die gerne nach bzw. vor Klammern Leerzeichen 
einsetzen:
1
  LCD_Anzeige_Zahl ( 3, 7, Messwert, 4, 1 );

... aber das ist Geschmackssache (mir beispielsweise missfällt's).

von Karl H. (kbuchegg)


Lesenswert?

anderer Vorschlag.
Auf einem µC wird ja ein bestimmter Wert meistens immer an ein und 
derselben Stelle angezeigt. Und das auch noch mit der immer gleichen 
Formatierung.

Das kann man sich natürlich auch in eine Funktion packen:
1
void LCD_Anzeige_Spannung( unsigned long long int spg )
2
{
3
  LCD_Anzeige_Zahl( 3, 7, spg, 4, 1 );
4
}

eventuell noch ein 'inline' dazu, um den Compiler sanft dazu zu 
überreden, die Funktion immer zu inlinen, und schon sind die Aufrufe der 
Funktion nicht mehr mit Details wie Position oder Formatierung 
überfrachtet.

Wenn man dem inlining nicht traut, bleibt noch das Hilfsmittel eines 
Makros.


Der Könner kombiniert dann natürlich die eine oder andere Methode, je 
nachdem was er genau als das Problem in der Lesbarkeit erachtet, bzw. 
welchen Nebeneffekt er als Draufgabe noch mitnehmen will (meist eine 
bessere Wartbarkeit was zb Positionierung von Ausgabeelementen auf einer 
Anzeige angeht)

: Bearbeitet durch User
von Falk S. (falkschilling)


Lesenswert?

Karl Heinz schrieb:
> anderer Vorschlag.
> Auf einem µC wird ja ein bestimmter Wert meistens immer an ein und
> derselben Stelle angezeigt. Und das auch noch mit der immer gleichen
> Formatierung.

> Das kann man sich natürlich auch in eine Funktion packen:
>
1
> void LCD_Anzeige_Spannung( unsigned long long int spg )
2
> {
3
>   LCD_Anzeige_Zahl( 3, 7, spg, 4, 1 );
4
> }
5
>

Geht in die richtige Richtung, denn:
Wenn man weiß, dass es verschiedene Präsentationsarten gibt, kann man 
sich auch eine softwaretechnisch sauberere Lösung ersinnen, mit dem 
Ziel, den Wert von seiner Präsentation zu trennen.

Wie wäre es z.B. mit der Definition einer Callback als ein Interface, 
gegen das man programmiert. Das definiert man, bevor man Produktivcode 
schreibt.

Man hat dann die Möglichkeit, seine komplette Präsentationsart an nur 
einer Stelle zu ändern:
1
// 
2
typedef unsigned long long t_Value;
3
4
// Schnittstellendefinition einer Funktion:
5
// diese Schnittstelle müssen numerische Ausgabefunktionen erfüllen
6
7
typedef void (*PFN_PRESENTATION)(t_Value val);
8
9
10
// etwas C++ angelehnt, Daten und Funktionen zu kapseln
11
typedef struct
12
{
13
  t_Value Zahl;
14
  PFN_PRESENTATION  fnPresentation;
15
} t_number2;
16
17
18
void LCD_Spannung(t_Value val) // implementiert PFN_PRESENTATION
19
{
20
  LCD_Anzeige_Zahl( 3, 5, val, 4, 1 ); // oder per designated initializer, s.o
21
  // TODO gotoxy + print text for voltage
22
23
}
24
25
void LCD_Prozent(t_Value val) // implementiert PFN_PRESENTATION
26
{
27
  LCD_Anzeige_Zahl( 2, 10, val, 2, 1 );
28
  // TODO gotoxy + print text for percentage
29
}
30
31
void LCD_Ausgabe(const t_number2* const val) // gibt das Objekt val aus
32
{
33
  val->fnPresentation( val->Zahl );
34
}
35
36
int main(int argc, char** argv)
37
{
38
  t_number2  test = { .Zahl=123ULL, .fnPresentation = &LCD_Prozent };
39
  t_number2  test2 = { .Zahl=321ULL, .fnPresentation = &LCD_Spannung };
40
41
  LCD_Ausgabe(&test);
42
  LCD_Ausgabe(&test2);
43
44
  return 0;
45
}


> Der Könner kombiniert dann natürlich die eine oder andere Methode, je
> nachdem was er genau als das Problem in der Lesbarkeit erachtet, bzw.
> welchen Nebeneffekt er als Draufgabe noch mitnehmen will (meist eine
> bessere Wartbarkeit was zb Positionierung von Ausgabeelementen auf einer
> Anzeige angeht)

Dafür kann man beim GCC dann noch die designated initializer nehmen und 
wir kriegen lesbaren C-Code raus.

Edit: Was ich noch vergessen habe - aufgrund der Kapselung im Beispiel 
ist es dann egal, wo die fnPresentation aufgerufen wird, es ist immer 
die richtige Anzeigefunktion. Auf Pointer als Formalparameter für den 
Stackverbrauch habe ich mal in der PFN_PRESENTATION verzichtet - wie man 
die nutzt, wisst ihr sowieso.

: Bearbeitet durch User
von Peter D. (peda)


Lesenswert?

Peter Zz schrieb:
> unsigned long long int Zahl
...
> Wie kann ich den Aufruf besser lesbar machen, ohne dem µC mehr Code zu
> verpassen?

Wenn Du alles in long long rechnest, dann bist Du doch eh schon völlig 
angstfrei in Bezug auf Codegröße.
An Kleinigkeiten zu optimieren, hat dann keinen Effekt mehr.

Vielleicht reicht ja schon float anstatt long long, dann wird der Code 
kleiner.

von Falk S. (falkschilling)


Angehängte Dateien:

Lesenswert?

So, hab heute bissl Langeweile und hab mal versucht, das ganze mal 
ordentlich zu schreiben.

Wenn jemand das für seine Zwecke nutzen will oder irgendwo hier im Wiki 
als Beispiel ablegen will: nur zu. Einzige Bedingung: halt so wie's ist.
1
/////////////////////////////////////////////////////////////////////////////
2
/**
3
   \file    interface_driven_development.c
4
   \author  DB8FS
5
   \licence beerware
6
*/
7
/////////////////////////////////////////////////////////////////////////////
8
9
#include <stdio.h>
10
11
//! the type of our value to display
12
typedef unsigned long long t_NumericValue;
13
14
/////////////////////////////////////////////////////////////////////////////
15
/**
16
   \interface PFN_NUMERICAL_PRESENTATION
17
   \brief Implementers of this interface may display a numeric value.
18
   \remark Other than in C++ we may only use function interfaces!
19
*/
20
/////////////////////////////////////////////////////////////////////////////
21
22
typedef void (*I_NUMERIC_PRESENTATION)(const t_NumericValue* const val);
23
24
25
/////////////////////////////////////////////////////////////////////////////
26
/**
27
   \struct t_Number
28
   \brief An ANSI-C class for numerical values.
29
   \remarks A bit C++ style... :)
30
*/
31
/////////////////////////////////////////////////////////////////////////////
32
33
typedef struct
34
{
35
  t_NumericValue m_Value;
36
  I_NUMERIC_PRESENTATION fnPresentation;
37
} t_Number;
38
39
40
/////////////////////////////////////////////////////////////////////////////
41
/**
42
   \function LCD_Voltage
43
   \brief Implements \ref{I_NUMERIC_PRESENTATION} for outputting voltages.
44
*/
45
/////////////////////////////////////////////////////////////////////////////
46
47
void LCD_Voltage(const t_NumericValue* const val)
48
{
49
  printf("LCD_Voltage: %dV\n", (int)*val );
50
  //LCD_Anzeige_Zahl( 3, 5, val, 4, 1 ); // use designated initializers
51
52
  // TODO gotoxy + print text for voltage
53
}
54
55
/////////////////////////////////////////////////////////////////////////////
56
/**
57
   \function LCD_Percent
58
   \brief Implements \ref{I_NUMERIC_PRESENTATION} for outputting percentages.
59
*/
60
/////////////////////////////////////////////////////////////////////////////
61
62
void LCD_Percent(const t_NumericValue* const val)
63
{
64
  printf("LCD_Percent: %d%%\n", (int) *val );
65
  //  LCD_Anzeige_Zahl( 2, 10, val, 2, 1 );
66
  // TODO gotoxy + print text for percentage
67
}
68
69
70
/////////////////////////////////////////////////////////////////////////////
71
/**
72
   \function LCD_Output_Numeric
73
   \brief    Outputs numeric values on the LCD.
74
   \remark   For demonstration of using an object-oriented ANSI-C style.
75
*/
76
/////////////////////////////////////////////////////////////////////////////
77
78
void LCD_Output_Numeric(const t_Number* const val)
79
{
80
  val->fnPresentation( &val->m_Value );
81
}
82
83
void LCD_Output_String(/*...*/)
84
{
85
  // TODO
86
}
87
88
89
/////////////////////////////////////////////////////////////////////////////
90
/**
91
   \function main
92
   \brief The main function - no explanation needed...
93
*/
94
/////////////////////////////////////////////////////////////////////////////
95
96
int main(int argc, char** argv)
97
{
98
  // create one object for e.g. proresses
99
  t_Number  test = { .m_Value=123ULL, .fnPresentation = &LCD_Percent };
100
101
  // create one object for a voltage
102
  t_Number  test2 = { .m_Value=321ULL, .fnPresentation = &LCD_Voltage };
103
104
  LCD_Output_Numeric(&test);
105
  LCD_Output_Numeric(&test2);
106
107
  return 0;
108
}

von Jörg W. (dl8dtl) (Moderator) Benutzerseite


Lesenswert?

Rufus Τ. Firefly schrieb:

> Das unterstützt bei weitem nicht jeder C-Compiler.

Dafür sind wir ja aber im GCC-Forum. ;-)

von Falk S. (falkschilling)


Lesenswert?

Ach so, noch 'ne Anmerkung für die, die nicht so fit sind beim Thema 
Entwurfsmuster:
das Beispiel hier implementiert in ANSI-C das Strategie-Muster. Die 
Schnittstelle der Strategie wird durch I_NUMERIC_PRESENTATION definiert 
und
LCD_Voltage und LCD_Percent sind konkrete Implementierungen dieser 
Strategie.

Vielleicht sollte man mal 'nen Artikel zum Thema Entwurfsmuster mit 
ANSI-C machen...

von Dr. Sommer (Gast)


Lesenswert?

In C++ kann man etwas machen dass ein bisschen wie named Parameters 
aussieht:
1
myLCD.output(1234).base(Decimal).precision(10);
Oder so:
1
myLCD.output(1234)[Decimal,precision(10),width(13),fill(' ')];
2
myLCD.output(5678)[fill(''),width(5)];
Oder so:
1
auto voltageFormat = defineFormat(Decimal,precision(10),width(13),fill(' '));
2
myLCD.output(91011)[voltageFormat];
Der Fantasie sind keine Grenzen gesetzt :o)
Hier http://en.wikibooks.org/wiki/More_C%2B%2B_Idioms/Named_Parameter 
steht wie das 1. geht, die anderen beiden würde ich mit etwas variadic 
template magic machen.

von Dr. Sommer (Gast)


Lesenswert?

Falk Schilling schrieb:
> Vielleicht sollte man mal 'nen Artikel zum Thema Entwurfsmuster mit
> ANSI-C machen...
Lieber darüber wie man C los wird und das gleich in einer richtigen™ 
Programmiersprache macht...

von Rufus Τ. F. (rufus) Benutzerseite


Lesenswert?

Dr. Sommer schrieb:
> richtigen™ Programmiersprache

Troll Dich.

von Falk S. (falkschilling)


Angehängte Dateien:

Lesenswert?

Dr. Sommer schrieb:
> Lieber darüber wie man C los wird und das gleich in einer richtigen™
> Programmiersprache macht...

Och, na in C++ ist das doch auch nicht komplizierter.
Da nutzt man halt reine abstrakte Klassen anstelle von Callback-Typen. 
Bringt auch gleich noch den minimalen Vorteil, die Bildung 
objektorientierter Architekturen zu fördern und Kopplung zu 
verringern... :)

Siehe Anhang - vielleicht könnte man noch << überladen, dann wird noch 
schicker zu nutzen.

von Dr. Sommer (Gast)


Angehängte Dateien:

Lesenswert?

Falk Schilling schrieb:
> Och, na in C++ ist das doch auch nicht komplizierter.
Ja, z.B. so.

Die Anzahl an Slashes in deinem Code ist etwas... irritierend...

ich hab den Code mal etwas C++ typischer umgebaut (mehr "const"), auf 
neues C++11 angepasst (using, nullptr) und einige der Pointer auf 
Referenzen umgebaut. Damit kann man dann kompakter schreiben:
1
CVoltagePresentation {}.Display (7);
Außerdem habe ich CValue eine Convenience Funktion .Print verpasst s.d. 
man auch kurz schreiben kann:
1
val.Print(CPercentPresentation {});
2
val.Print(CPercentPresentation {5});
An die Präsentation kann man dann auch Parameter übergeben zur 
Spezifizierung der Ausgabe. Somit kommt man dem Ziel eines 
Kompakteren/Lesbareren Aufrufs schon eher näher ;-)

Deine COtherValue Klasse ruft immer zwangsweise den Default Konstruktor 
von m_Presentation auf, ich habe da mal einen zweiten Konstruktor 
hinzugefügt s.d. man das m_Presentation vorbelegen kann (via 
Copy-Konstruktor).

Einige der virtuals, in CValue, waren sinnlos, die hab ich rausgenommen 
(Ineffizienz ohne Not)...

von Falk S. (falkschilling)


Lesenswert?

Dr. Sommer schrieb:

Hi, danke dir für die Modifikationen, ich hatte es bissl von der Leber 
weg implementiert. Das ist auch nur ein Vorschlag, wie man es lösen kann 
- natürlich kann man auch über Callbacks Strategien wechseln. Mir ging 
es darum, mal einen Higher-Level-C++-Ansatz zu zeigen.

> Die Anzahl an Slashes in deinem Code ist etwas... irritierend...

Och, ist so 'ne Angewohnheit - ich mags auf großen Monitoren gerne, gebe 
aber zu, dass das 'ne Geschmacksfrage ist.

> ich hab den Code mal etwas C++ typischer umgebaut (mehr "const"),

Jo, zugegeben, bissl const-korrekter könnte es sein.

> auf neues C++11 angepasst (using, nullptr)

Ja sorry, mit'm 11er C++ bin ich noch nicht ganz so fit. Progge 
hauptberuflich für WinCE 5/6 und da ist mit'm 2008er Studio Sense.

> und einige der Pointer auf
> Referenzen umgebaut.

Wobei die Pointer explizit genommen wurden... angenommen, man ändert 
INumber auf ein gemeinsame abstrakte Klasse (Schnittstelle) für 
generische Zahlen - dann hilft keine Referenz.

> Damit kann man dann kompakter schreiben:
>
1
CVoltagePresentation {}.Display (7);
> Außerdem habe ich CValue eine Convenience Funktion .Print verpasst s.d.
> man auch kurz schreiben kann:
>
1
val.Print(CPercentPresentation {});
2
> val.Print(CPercentPresentation {5});
> An die Präsentation kann man dann auch Parameter übergeben zur
> Spezifizierung der Ausgabe. Somit kommt man dem Ziel eines
> Kompakteren/Lesbareren Aufrufs schon eher näher ;-)

Jo, stimmt, das ist nicht verkehrt.

> Deine COtherValue Klasse ruft immer zwangsweise den Default Konstruktor
> von m_Presentation auf, ich habe da mal einen zweiten Konstruktor
> hinzugefügt s.d. man das m_Presentation vorbelegen kann (via
> Copy-Konstruktor).

thx

> Einige der virtuals, in CValue, waren sinnlos, die hab ich rausgenommen
> (Ineffizienz ohne Not)...

von Falk S. (falkschilling)


Angehängte Dateien:

Lesenswert?

So, hab heute noch mal das ANSI-C-Beispiel für die LCD-Ausgabe in den 
Händen gehabt. Hab mal paar C99-Features für Arrays eingebaut und etwas 
mehr Objektorientierung mit ANSI-C gebastelt.

Geht vielleicht effizienter, aber ich bin nicht der größte Fan von 
vorschnellen Optimierungen.

von Dr. Sommer (Gast)


Lesenswert?

Falk Schilling schrieb:
> Ja sorry, mit'm 11er C++ bin ich noch nicht ganz so fit.
Schaus dir mal an das bringt ne Menge für µC (constexpr) ;-)

Falk Schilling schrieb:
> Wobei die Pointer explizit genommen wurden... angenommen, man ändert
> INumber auf ein gemeinsame abstrakte Klasse (Schnittstelle) für
> generische Zahlen - dann hilft keine Referenz.
doch!!! C++ Referenzen funktionieren in dieser Hinsicht wie Pointer, 
erlauben aber eine kompaktere Syntax beim Aufruf

Falk Schilling schrieb:
> und etwas mehr Objektorientierung mit ANSI-C gebastelt.
Warum, warum verwendet man nicht einfach eine objektorientierte Sprache 
dafür, d.h. C++ ...

von Falk S. (falkschilling)


Lesenswert?

Dr. Sommer schrieb:
> Falk Schilling schrieb:
>> Ja sorry, mit'm 11er C++ bin ich noch nicht ganz so fit.
> Schaus dir mal an das bringt ne Menge für µC (constexpr) ;-)

Hab's mal mit'm 4.6.3er GCC unter Gentoo versucht - war leider nicht von 
Erfolg gekrönt. Probier's nachher nochmal.

> Falk Schilling schrieb:
>> Wobei die Pointer explizit genommen wurden... angenommen, man ändert
>> INumber auf ein gemeinsame abstrakte Klasse (Schnittstelle) für
>> generische Zahlen - dann hilft keine Referenz.
> doch!!! C++ Referenzen funktionieren in dieser Hinsicht wie Pointer,
> erlauben aber eine kompaktere Syntax beim Aufruf

Danke dir, wieder was gelernt!
Macht irgendwo ja auch Sinn, da sich die Referenz immer auf ein 
existierendes Objekt beziehen muss und bei abstrakten Klasse nur durch 
abgelittene Klassen Objekte entstehen.

> Falk Schilling schrieb:
>> und etwas mehr Objektorientierung mit ANSI-C gebastelt.
> Warum, warum verwendet man nicht einfach eine objektorientierte Sprache
> dafür, d.h. C++ ...

Sind eigentlich ein paar Sachen, weswegen ich an C sehr hänge und es 
sehr gerne mag:

1. Es gibt Sprach-Features, um die ich die ANSI-C99-Menschen beneide. 
Lösen sich aber mit'm 11er Standard wohl einige davon auf. Aber die 
Initialisierungssachen aus dem Beispiel hier gehören dazu.

2. Die C-Compiler sind nicht so komplex und hocheffizient. Gerade 
Templates überfordern so manchen Compiler (Stichwort 'export'...)

3. C++ ist Multi-Paradigmen-fähig. Teilweise so sehr, dass man verleitet 
wird, Paradigmen zu mischen - mal schreibt man objektorientiert, mal 
strukturiert und manchmal sogar nur auf der Ebene der Metaprogrammierung 
(Templates). Da ist C konsequenter.

4. Die Herausforderung, Softwarearchitekturen zu entwickeln, die nicht 
zwangsweise objektorientiert sein müssen und sich dafür Best-Practises 
aneignen. Also dass man gute Architekturen sowohl strukturiert mit C als 
auch objektorientiert mit C++ entwickeln kann. Muss man üben - auch 
umgekehrt: OOP mit C.

5. ANSI-C kann ich sogar auf meinem C64 proggen und es kommt halbwegs 
gescheiter Code raus... :)

6. Das Wichtigste: die ABI-Stabilität. Was das betrifft ist C++ eine 
Frechheit. Exportier mal C++-Klassen aus 'ner DLL mit MSV
C++ (vielleicht sogar mit Templates...) und binde diese DLL mal im GCC 
an... da wirste 'nen Kotzkübel brauchen!

7. Ich mag den OOP-Ansatz von Objective-C sehr gerne und finde den 
intuitiver und angenehmer als die C++-Version. Wäre meine C-basierte 
OOP-Lieblingssprache.
Nimm z.B. mal Objective-C++ mit'm GCC und fang an, Klassen zu schreiben. 
Ich glaube kaum, dass du da großartig C++-Klassen schreiben wirst... :)

8. Diversifikation - sich nicht nur von C++ abhängig machen. :)

9. Nochmal Stichwort Objective-C: Garbage Collection für dynamische 
Allokierungen, bessere Lesbarkeit gegenüber C++, usw. usf.

10. Im Grunde noch alles weitere, was dazu geführt hat, dass solche 
monströsen Frameworks wie COM geschaffen werden mussten.
Siehe erstes Kapitel Don Box "Essential COM" und vergleiche IUnknown mit 
NSObject von Objective-C!

11. Mal MISRA-C++ angeschaut - ich sag nur: You shall not!

12. Syntaktisch ist C++ vom Schreibaufwand 'ne Frechheit. Ohne gescheite 
Tools schreibt man sich dumm und dämlich.

13. dynamic_cast<>() - ich sag nüscht dazu, wie lahm das ist.

14. Smart-Pointer - wahrscheinlich erst ab'm 11er Standard zu gebrauchen

15. Threading - siehe 14

... ich hör jetzt auf, die Liste wird zu lang.

: Bearbeitet durch User
von Falk S. (falkschilling)


Lesenswert?

Ok, gebe zu, die letzten Punkte haben jetzt weniger mit ANSI-C zu tun. 
Aber das sind auch Gründe, weswegen C++ für mich nicht das Allheilmittel 
ist.

War vor paar Jahren mal anders, da war ich auch großer C++-Fan. Jetzt wo 
ich ein paar Jahre täglich C++ schreibe - beginnend von C++ unter Linux 
über  Win32 und COM-Servern als Schnittstelle zu .NET in der 
Bildverarbeitung bis jetzt zu C++ unter WinCE.

Wenn du da im 6er VisualStudio oder im EVC unterwegs bist, nützt dir der 
11er Standard gar nix. Da hilft noch nicht mal Boost...

von Dr. Sommer (Gast)


Lesenswert?

> Hab's mal mit'm 4.6.3er GCC unter Gentoo versucht - war leider nicht von
> Erfolg gekrönt. Probier's nachher nochmal.
Nimm mindestens 4.7.3, besser 4.8 - unter Gentoo hat man doch immer so 
topaktuelle Pakete ;-)
> Danke dir, wieder was gelernt!
Büdde ;-)
> 1. Es gibt Sprach-Features, um die ich die ANSI-C99-Menschen beneide.
> Lösen sich aber mit'm 11er Standard wohl einige davon auf. Aber die
> Initialisierungssachen aus dem Beispiel hier gehören dazu.
Mit der unified Initialization Syntax von C++11 ist das alles 
vereinheitlicht und superelegant, da macht auch C nix mehr gegen ;)
> 2. Die C-Compiler sind nicht so komplex und hocheffizient. Gerade
> Templates überfordern so manchen Compiler (Stichwort 'export'...)
"export" ist gar nicht mehr Teil von C++ ;-) Aber jo, C++ Compiler sind 
eine Wissenschaft für sich.
> 3. C++ ist Multi-Paradigmen-fähig. Teilweise so sehr, dass man verleitet
> wird, Paradigmen zu mischen - mal schreibt man objektorientiert, mal
> strukturiert und manchmal sogar nur auf der Ebene der Metaprogrammierung
> (Templates). Da ist C konsequenter.
Wo ist das Problem? Für verschiedene Probleme gibt es verschiedene 
Paradigmen, und OOP und Metaprogrammierung passen eigentlich gut 
zusammen...
> 4. Die Herausforderung, Softwarearchitekturen zu entwickeln, die nicht
> zwangsweise objektorientiert sein müssen und sich dafür Best-Practises
> aneignen.
C++ ist gar nicht so zwangs-OOP (wie zB Java), man schaue mal wie viele 
"free Functions" (d.h. globale Funktionen, keine Member-Funktionen) in 
der C++ Standard Library sind.
> Muss man üben - auch umgekehrt: OOP mit C.
Gerade das würde ich nicht ohne Not machen, weil C dafür einfach nicht 
gemacht ist...
> 5. ANSI-C kann ich sogar auf meinem C64 proggen und es kommt halbwegs
> gescheiter Code raus... :)
Ja obskure Plattformen sind problematisch...
> 6. Das Wichtigste: die ABI-Stabilität. Was das betrifft ist C++ eine
> Frechheit. Exportier mal C++-Klassen aus 'ner DLL mit MSV
> C++ (vielleicht sogar mit Templates...) und binde diese DLL mal im GCC
> an... da wirste 'nen Kotzkübel brauchen!
Die templates würden eh im Client Code landen ;-) Aber ja, das ABI-Zeug 
ist ein großes Problem. Bei Embedded hat man das zum Glück nicht so. Der 
Vorteil ist eben die Effizienz; in Java ist es z.B. genau umgekehrt 
(weniger effizient, mehr kompatibel).
> 7. Ich mag den OOP-Ansatz von Objective-C sehr gerne und finde den
> intuitiver und angenehmer als die C++-Version. Wäre meine C-basierte
> OOP-Lieblingssprache.
Mh, Obj-C hab ich keine Erfahrung mit...
> 8. Diversifikation - sich nicht nur von C++ abhängig machen. :)
Genau, es gibt noch viele ander schöne OOP Sprachen - Scala, ruby, 
python ;-D
> 9. Nochmal Stichwort Objective-C: Garbage Collection für dynamische
> Allokierungen, bessere Lesbarkeit gegenüber C++, usw. usf.
Die ist für C++ auch spezifiziert, nutzt nur keiner ;)
> 10. Im Grunde noch alles weitere, was dazu geführt hat, dass solche
> monströsen Frameworks wie COM geschaffen werden mussten.
> Siehe erstes Kapitel Don Box "Essential COM" und vergleiche IUnknown mit
> NSObject von Objective-C!
Halt Effizienz vs. Kompatibilität...
> 11. Mal MISRA-C++ angeschaut - ich sag nur: You shall not!
Wobei das meiste dieser Sachen von C kommt, wie das Integer Promotion 
Zeug. Nur dass es in C weniger ausmacht wegen des einfachen Typsystems.
> 12. Syntaktisch ist C++ vom Schreibaufwand 'ne Frechheit. Ohne gescheite
> Tools schreibt man sich dumm und dämlich.
Jup, das stimmt. Auch zum Gutteil der C-Kompatibilität geschuldet.
> 13. dynamic_cast<>() - ich sag nüscht dazu, wie lahm das ist.
Wus? Erst sagst du dass du Garbage Collection brauchst, dann meckerst du 
über die Effizienz von dynamic_cast? So selten wie man das (bei 
anständiger Programmierung) braucht sollte das nicht viel ausmachen, und 
die Äquivalente in anderen Sprachen können nicht besser sein.
> 14. Smart-Pointer - wahrscheinlich erst ab'm 11er Standard zu gebrauchen
Vorher auch schon, mit 11 noch besser und vor allem sinnvolle 
vordefinierte SmartPointer-Klassen.
> 15. Threading - siehe 14
Jup.
> ... ich hör jetzt auf, die Liste wird zu lang.
Ja, C++ hat eine Unmenge Nachteile, aber wie Stroustrup schon sagte - es 
gibt 2 Typen von Programmiersprachen, die einen über die jeder lästert 
und die anderen, die keiner benutzt...

Falk Schilling schrieb:
> Aber das sind auch Gründe, weswegen C++ für mich nicht das Allheilmittel
> ist.
Ein Allheilmittel gibts onehin nicht ;)

Falk Schilling schrieb:
> Wenn du da im 6er VisualStudio oder im EVC unterwegs bist, nützt dir der
> 11er Standard gar nix. Da hilft noch nicht mal Boost...
Selber schuld, die neueren VS Versionen können das ;)

Was ich nur sagen wollte ist dass man ohne Not OOP wenn schon mit einer 
OOP-Sprache (wie C++) machen sollte, und nicht in einer 
nicht-OOP-Sprache (wie C).

von Falk S. (falkschilling)


Angehängte Dateien:

Lesenswert?

Dr. Sommer schrieb:
> "export" ist gar nicht mehr Teil von C++ ;-)
Das heißt, Trennung von Deklaration und Implementierung geht jetzt auch 
so, oder gar nicht?

> Wo ist das Problem? Für verschiedene Probleme gibt es verschiedene
> Paradigmen, und OOP und Metaprogrammierung passen eigentlich gut
> zusammen...

Ich hab kein Problem damit, finde nur, dass viel dieser Komplexität in 
heutigen Projekten nicht mehr unbedingt zweckdienlich ist. Gerade .NET 
oder Java zeigt ja eigentlich relativ gut, wie der Source-Code sauber 
bleiben kann. Ich stell mal so dahin: schlechter Java/.NET-Code ist 
einfacher zu entflechten und refactoren als ganz verkackter C++ Code 
(eben aufgrund dieser Multi-Paradigma-Eigenschaft).

> C++ ist gar nicht so zwangs-OOP (wie zB Java), man schaue mal wie viele
> "free Functions" (d.h. globale Funktionen, keine Member-Funktionen) in
> der C++ Standard Library sind.

Ja, man kann auch strukturierte (also nicht-OOP) Software-Entwicklung 
mit C++ machen.

>> Muss man üben - auch umgekehrt: OOP mit C.
> Gerade das würde ich nicht ohne Not machen, weil C dafür einfach nicht
> gemacht ist...

Mal ehrlich: für 'nen AVR möchte ich kein C++ programmieren, weil ich da 
den Nutzen nicht sehe - selbst bei größeren Softwareprojekten.

>> 6. Das Wichtigste: die ABI-Stabilität. Was das betrifft ist C++ eine
>> Frechheit. Exportier mal C++-Klassen aus 'ner DLL mit MSV
>> C++ (vielleicht sogar mit Templates...) und binde diese DLL mal im GCC
>> an... da wirste 'nen Kotzkübel brauchen!
> Die templates würden eh im Client Code landen ;-)

Nicht zwangsweise. Wie wäre es z.B. siehe Anhang?

Um das in 'ne DLL zu packen, musst du das Template als extern markieren 
und im Client-Code 'nen Import machen (für'n Linker).

Dann mach das mal für den häßlichen Fall mit STL-Containern und freu 
dich zur Laufzeit über unterschiedliche DLL-Heaps...

> Aber ja, das ABI-Zeug
> ist ein großes Problem. Bei Embedded hat man das zum Glück nicht so.

Na ja, WinCE würde ich schon auch noch als Embedded bezeichnen und da 
haben wir in der Firma das Problem ziemlich oft gehabt.
Gerade wenn vor 'nem Release irgendein Heisenbug auftritt, der durch 
unpassende ABI zwischen den Komponenten aufgerufen wird, kannste paar 
graue Haare kriegen.

> Der Vorteil ist eben die Effizienz; in Java ist es z.B. genau umgekehrt
> (weniger effizient, mehr kompatibel).

Und gerade weil C++ bei diesen softwaretechnischen Anforderungen an 
Wartbarkeit, Portierbarkeit, usw. usf. gegenüber Java/.NET ins 
Hintertreffen geraten ist, sehe ich das Performance-Argument nur 
begrenzt als gültig. Guck mal die ARM-Prozessoren mit Jazelle, da lohnt 
sich's aus Performance-Sicht doch praktisch kaum noch, überhaupt C++ zu 
schreiben.

Ist halt nur dann schlecht, wenn du von 'ner Jazelle auf 'ne 
Nicht-Jazelle-Plattform umziehst...

> Mh, Obj-C hab ich keine Erfahrung mit...

Eigentlich wie C, nur eine einzige Spracherweiterung: nämlich die 
eckigen Klammern für Methodenaufrufe. Kannst ja mal den GCC anwerfen mit 
GNUStep - lohnt sich, rein vom Verständnis des Ablaufs.

Hat man sich an Obj-C gewöhnt, merkt man, um wieviel präsenter da die 
Objektorientierung ist.

> Genau, es gibt noch viele ander schöne OOP Sprachen - Scala, ruby,
> python ;-D

Ja, Python ist schön - und sooo unperformant isses auch wieder nicht. 
Auf meinem Raspberry frag ich mich ehrlich gesagt schon, warum man unter 
Raspian überhaupt C++ schreiben sollte...

>> 9. Nochmal Stichwort Objective-C: Garbage Collection für dynamische
>> Allokierungen, bessere Lesbarkeit gegenüber C++, usw. usf.
> Die ist für C++ auch spezifiziert, nutzt nur keiner ;)

Echt? Über spezielle Allokatoren oder wie? Dann aber siehe oben: z.B. 
DLL-Heaps.

Wenn man unter Windows nicht 'ne reine Template-Lib für'n Client hat 
oder Daten mit Nicht-C++-Code austauschen will, bleiben nicht viele 
Optionen übrig:

• COM - dann kann jeder mit jeder Sprache draufrumkaspern.
• ungemangelte C-Exporte mit Interface-Handles (ohne STL)

C++-Code ist immer nur innerhalb des selben Compilers und der selben 
Laufzeitumgebung brauchbar - und unter Linux/MacOS ist das nix anderes. 
Nur dass bei MacOS/iOS seitens Apple die Anzahl Zielkonfigurationen 
überschaubar bleibt.

> Halt Effizienz vs. Kompatibilität...

Na ja, aber schau mal den programmiererischen Overhead an, den du selber 
treiben musst, um portabel zu bleiben. Find das schon krass.

> Wobei das meiste dieser Sachen von C kommt, wie das Integer Promotion
> Zeug. Nur dass es in C weniger ausmacht wegen des einfachen Typsystems.

Jo, genau. Deswegen wäre mir für sowas C lieber als C++.

>> 13. dynamic_cast<>() - ich sag nüscht dazu, wie lahm das ist.

> Wus? Erst sagst du dass du Garbage Collection brauchst, dann meckerst du
> über die Effizienz von dynamic_cast? So selten wie man das (bei
> anständiger Programmierung) braucht sollte das nicht viel ausmachen, und
> die Äquivalente in anderen Sprachen können nicht besser sein.

Na ja, ich seh auch zu, das weitestmöglich zu vermeiden und mir über 
Type-Enums zu behelfen - falls es mal wirklich dynamisch typisiert sein 
muss. Aber sind wir wieder beim Multi-Paradigma-Dilemma: C++ unterstützt 
es und manch einer macht ausgiebig Gebrauch davon.

>> 14. Smart-Pointer - wahrscheinlich erst ab'm 11er Standard zu gebrauchen
> Vorher auch schon, mit 11 noch besser und vor allem sinnvolle
> vordefinierte SmartPointer-Klassen.

Komm: std::auto_ptr<> ist doch 'ne Frechheit. Da sind mir Boost's (bzw. 
C++11's) Smartpointer lieber - und für COM sogar der CComPtr<>.

> Ja, C++ hat eine Unmenge Nachteile, aber wie Stroustrup schon sagte - es
> gibt 2 Typen von Programmiersprachen, die einen über die jeder lästert
> und die anderen, die keiner benutzt...

Wohl wahr.

> Ein Allheilmittel gibts onehin nicht ;)

Hm, kann man drüber diskutieren, ob da der Multi-Paradigmen-Ansatz nicht 
eigentlich genau dieses Ziel verfolgt, eine Allheilmittel-Sprache zu 
sein... :)

> Selber schuld, die neueren VS Versionen können das ;)

Das sind ja mitunter Randbedingungen, die man nicht ändern kann. z.B. 
das Image eines WinCE-Geräts oder ähnliche Sachen. Es ist jetzt nicht 
unbedingt so, dass ich nicht gerne einen C++11-kompatiblen MS-Compiler 
für WinCE5/6 hätte... also ich würd jetzt mich nicht zwangweise dagegen 
wehren... :)

> Was ich nur sagen wollte ist dass man ohne Not OOP wenn schon mit einer
> OOP-Sprache (wie C++) machen sollte, und nicht in einer
> nicht-OOP-Sprache (wie C).

Ich bin immer daran interessiert, wie man mit unterschiedlichen 
Werkzeugen ähnliche Probleme lösen kann - ist manchmal ganz interessant. 
Und hier im Speziellen ging es um softwaretechnische Entkopplung von der 
Hardware hin auf eine eher algorithmische Ebene. Konkret um den Prozess 
dieser Entkopplung auch unter C zu verstehen.

Wenn daraus dann möglicherweise Schemata entstehen, die für mich selber 
oder andere wiederverwendbar werden, denke ich, hat sich der Aufwand 
dann schon gelohnt.

: Bearbeitet durch User
von Dr. Sommer (Gast)


Lesenswert?

> Das heißt, Trennung von Deklaration und Implementierung geht jetzt auch
> so, oder gar nicht?
So wie immer halt, man kann Funktions-Implementationen in seperate 
Header Files packen. export funktionierte ja eh nur in einem einzigen 
Compiler. template Funktions Implementationen binär ausliefern ist 
einfach inpraktikabel und bringt nichts.
> Ich hab kein Problem damit, finde nur, dass viel dieser Komplexität in
> heutigen Projekten nicht mehr unbedingt zweckdienlich ist. Gerade .NET
> oder Java zeigt ja eigentlich relativ gut, wie der Source-Code sauber
> bleiben kann. Ich stell mal so dahin: schlechter Java/.NET-Code ist
> einfacher zu entflechten und refactoren als ganz verkackter C++ Code
> (eben aufgrund dieser Multi-Paradigma-Eigenschaft).
Ja das kann sein. Dafür ist Java aber auch ziemlich beschränkt :-/
> Ja, man kann auch strukturierte (also nicht-OOP) Software-Entwicklung
> mit C++ machen.
Manche Sachen wie ein Sortieralgorithmus machen einfach als free 
function mehr Sinn ;-)
> Mal ehrlich: für 'nen AVR möchte ich kein C++ programmieren, weil ich da
> den Nutzen nicht sehe - selbst bei größeren Softwareprojekten.
Wenn ich mir eine Pin Klasse machen kann die einen Pin abstrahiert, und 
Instanzen dieser als globale Variablen zwecks Konfiguration definieren 
oder als Parameter übergeben kann, hat sich das doch schon gelohnt...
>>> 6. Das Wichtigste: die ABI-Stabilität. Was das betrifft ist C++ eine
>>> Frechheit. Exportier mal C++-Klassen aus 'ner DLL mit MSV
>>> C++ (vielleicht sogar mit Templates...) und binde diese DLL mal im GCC
>>> an... da wirste 'nen Kotzkübel brauchen!
>> Die templates würden eh im Client Code landen ;-)
>
> Nicht zwangsweise. Wie wäre es z.B. siehe Anhang?
Die Implementation von DoSomething würde im Client Code landen. Die 
Implementationen deiner Fill* Funktionen (die ja keine 
template-Funktionen sind) würden normal in der DLL landen.

> Um das in 'ne DLL zu packen, musst du das Template als extern markieren
> und im Client-Code 'nen Import machen (für'n Linker).
Ja, und deswegen muss die Implementation von DoSomething in einen Header 
und in den Client Code, da das eben nur ein Compiler kann (VS gehört 
nicht dazu). Es ist aber onehin sinnlos, da der Client Compiler den 
template Code so oder so lesen muss (unabhängig ob binär oder als 
Source) und daraus neuen Code generieren muss.
> Dann mach das mal für den häßlichen Fall mit STL-Containern und freu
> dich zur Laufzeit über unterschiedliche DLL-Heaps...
Das ist doch alles der easy Fall da nicht-template Funktionen. Das hat 
nun nichts mit templates sondern mit der C++ stdlib zu tun.
> Gerade wenn vor 'nem Release irgendein Heisenbug auftritt, der durch
> unpassende ABI zwischen den Komponenten aufgerufen wird, kannste paar
> graue Haare kriegen.
Besteht nicht unter Windows die Philosophie dass man alle 
Komponenten/DLL's mit ausliefert s.d. Binärkompatibilität gewährleistet 
ist?
> Und gerade weil C++ bei diesen softwaretechnischen Anforderungen an
> Wartbarkeit, Portierbarkeit, usw. usf. gegenüber Java/.NET ins
> Hintertreffen geraten ist, sehe ich das Performance-Argument nur
> begrenzt als gültig. Guck mal die ARM-Prozessoren mit Jazelle, da lohnt
> sich's aus Performance-Sicht doch praktisch kaum noch, überhaupt C++ zu
> schreiben.
Das sind dann aber schon die ganz dicken.
> Ist halt nur dann schlecht, wenn du von 'ner Jazelle auf 'ne
> Nicht-Jazelle-Plattform umziehst...
Son kleiner Cortex-M0 mit 8KB SRAM freut sich total über Java Code ;-D

>>> 9. Nochmal Stichwort Objective-C: Garbage Collection für dynamische
>>> Allokierungen, bessere Lesbarkeit gegenüber C++, usw. usf.
>> Die ist für C++ auch spezifiziert, nutzt nur keiner ;)
>
> Echt? Über spezielle Allokatoren oder wie? Dann aber siehe oben: z.B.
> DLL-Heaps.
Keine Ahnung, Implementatio-Defined. Macht aber keiner weil man dann 
auch gleich Java verwenden kann...
> C++-Code ist immer nur innerhalb des selben Compilers und der selben
> Laufzeitumgebung brauchbar - und unter Linux/MacOS ist das nix anderes.
Linux hat halt den Vorteil dass man einfach alles mit dem selben 
Compiler compiliert und man somit alles kompatibel halten kann. Ist für 
proprietäre Software aber auch da ein Problem ja...
> Na ja, aber schau mal den programmiererischen Overhead an, den du selber
> treiben musst, um portabel zu bleiben. Find das schon krass.
Tja. Für Sachen wie Spiele scheint sich das ja trotzdem noch zu lohnen, 
da der Programmier-Aufwand für C Code noch viel höher wäre als der 
Kompatibel-Halten-Aufwand für C++.
> Na ja, ich seh auch zu, das weitestmöglich zu vermeiden und mir über
> Type-Enums zu behelfen
Das ist dann wieder sinnlos, denn da kann man genausogut typeid() 
verwenden, was mindestens genauso performant sein sollte.
> - falls es mal wirklich dynamisch typisiert sein
> muss. Aber sind wir wieder beim Multi-Paradigma-Dilemma: C++ unterstützt
> es und manch einer macht ausgiebig Gebrauch davon.
C++ ist halt nicht Java was den Anfänger-Programmierer zu seinem "Glück" 
zwingt...
> Komm: std::auto_ptr<> ist doch 'ne Frechheit. Da sind mir Boost's (bzw.
> C++11's) Smartpointer lieber - und für COM sogar der CComPtr<>.
Ja, auto_ptr ist deprecated, es gibt jetzt unique_ptr und shared_ptr die 
in Kombination mit rvalue references jetzt richtig sinnvoll sind.

> Hm, kann man drüber diskutieren, ob da der Multi-Paradigmen-Ansatz nicht
> eigentlich genau dieses Ziel verfolgt, eine Allheilmittel-Sprache zu
> sein... :)
In den 80ern war das so gedacht :D
> Das sind ja mitunter Randbedingungen, die man nicht ändern kann. z.B.
> das Image eines WinCE-Geräts oder ähnliche Sachen. Es ist jetzt nicht
> unbedingt so, dass ich nicht gerne einen C++11-kompatiblen MS-Compiler
> für WinCE5/6 hätte... also ich würd jetzt mich nicht zwangweise dagegen
> wehren... :)
Da haste jetzt das Vendor Lockin Problem... Das Frontend des Compilers 
hat ja eigentlich nichts mit der Ziel Plattform zu tun; die neuren GCC 
Versionen zB die C++11 können, können das automatisch für alle 
Plattformen wie AVR, ARM, win32, ...
> Ich bin immer daran interessiert, wie man mit unterschiedlichen
> Werkzeugen ähnliche Probleme lösen kann - ist manchmal ganz interessant.
Lernen ja, aber das für "richtige" Projekte immer komplett 
durchzuziehen...
> Und hier im Speziellen ging es um softwaretechnische Entkopplung von der
> Hardware hin auf eine eher algorithmische Ebene. Konkret um den Prozess
> dieser Entkopplung auch unter C zu verstehen.
Genau dafür ist C nicht gedacht (C ist ein Byte processor ...), aber 
C++, Java, Python...

von Falk S. (falkschilling)


Lesenswert?

Dr. Sommer schrieb:
> So wie immer halt, man kann Funktions-Implementationen in seperate
> Header Files packen. export funktionierte ja eh nur in einem einzigen
> Compiler. template Funktions Implementationen binär ausliefern ist
> einfach inpraktikabel und bringt nichts.

Lässt sich aber praktisch nicht immer vermeiden.

Klar: ich hätte auch gerne eine template-Framework auf Arbeit, was ich 
einfach überall einbinden kann und was dann nur binär im Code landet. 
Ich kann aber nicht anfangen, alles als template zu bauen, einfach weil 
zu viel Code drumrum ist. Und nur refactoren bis ich reine templates 
habe, finde ich gewagt.

> Manche Sachen wie ein Sortieralgorithmus machen einfach als free
> function mehr Sinn ;-)

Zweifellos.

> Wenn ich mir eine Pin Klasse machen kann die einen Pin abstrahiert, und
> Instanzen dieser als globale Variablen zwecks Konfiguration definieren
> oder als Parameter übergeben kann, hat sich das doch schon gelohnt...

Ansichtssache. Aber wenn man den Aufwand betreiben kann, dann darf man 
den in C auch betreiben. Ist für mich nicht unbedingt das Argument Pro 
C++ auf AVR.

>> Nicht zwangsweise. Wie wäre es z.B. siehe Anhang?
> Die Implementation von DoSomething würde im Client Code landen. Die
> Implementationen deiner Fill* Funktionen (die ja keine
> template-Funktionen sind) würden normal in der DLL landen.

Schon klar. Da die STL, wie es der Name schon sagt, eine 
template-Library ist, verkompliziert das den Datenaustausch zwischen 
Binärkomponenten. Insbesondere weil man dann aufpassen muss, in welcher 
Komponente Speicher allokiert wird.

>> Dann mach das mal für den häßlichen Fall mit STL-Containern und freu
>> dich zur Laufzeit über unterschiedliche DLL-Heaps...
> Das ist doch alles der easy Fall da nicht-template Funktionen. Das hat
> nun nichts mit templates sondern mit der C++ stdlib zu tun.

Die du aber immer dazu binden musst, da viele STL-Implementierungen da 
drinne liegen. Und nein, das ist nicht der Easy-Fall. Rufe im Client ein 
.push_back() auf den std::vector<> auf, rufe dann FillObjectList() auf 
und füge dort ein CTest-Objekt hinzu.

>> Gerade wenn vor 'nem Release irgendein Heisenbug auftritt, der durch
>> unpassende ABI zwischen den Komponenten aufgerufen wird, kannste paar
>> graue Haare kriegen.
> Besteht nicht unter Windows die Philosophie dass man alle
> Komponenten/DLL's mit ausliefert s.d. Binärkompatibilität gewährleistet
> ist?

Warum denkst du, gibt es COM? Unter anderem um in die DLL-Hölle mit 
nicht passenden Headern zu DLLs eine Abwärtskompatibilität für 
Interfaces einzuführen.

Und wenn deine DLL ihren eigenen Heap für Allokationen hat, dein Client, 
der die DLL in seinen Prozessraum lädt, ebenso - dann gibt es zwei 
Abschnitte im RAM, in denen Heap-Allokationen gemacht werden. Wenn du da 
kein GlobalAlloc machst - was die STL standardmäßig nicht macht, kannst 
kriegst du Probleme kriegen.

> Das sind dann aber schon die ganz dicken.

...die mittlerweile in den meisten Handys verbaut sind und deren 
Prozessorleistung perspektivisch auch für die Low-End-Chips zur 
Verfügung stehen wird. Nachdem Herrn Moore sein Gesetz auch bei den 
Embedded Prozessoren so bitter zuschlägt, ist das wohl nur ne Frage der 
Zeit

>> Ist halt nur dann schlecht, wenn du von 'ner Jazelle auf 'ne
>> Nicht-Jazelle-Plattform umziehst...
> Son kleiner Cortex-M0 mit 8KB SRAM freut sich total über Java Code ;-D

Jo, der dreht bestimmt ab vor Freude... :)

>> Echt? Über spezielle Allokatoren oder wie? Dann aber siehe oben: z.B.
>> DLL-Heaps.
> Keine Ahnung, Implementatio-Defined. Macht aber keiner weil man dann
> auch gleich Java verwenden kann...

Na so viel Overhead ist das och wieder nicht. Guck mal 
DirectX/DirectShow: trotz Referenzzählen ist es ziemlich performant.

> Linux hat halt den Vorteil dass man einfach alles mit dem selben
> Compiler compiliert und man somit alles kompatibel halten kann. Ist für
> proprietäre Software aber auch da ein Problem ja...

Jo, da kommt Hardwarehersteller A., liefert sein Framework mit VS2005 
aus - du selber hast deine Projekte bereits für Hersteller B. im 
VS2008er Studio. Bastelst dir 'n neues Projekt/Toolchain, passt alles 
drauf an - Gott, was haben die .NET/Java-Leute für'n Leben.

> Tja. Für Sachen wie Spiele scheint sich das ja trotzdem noch zu lohnen,
> da der Programmier-Aufwand für C Code noch viel höher wäre als der
> Kompatibel-Halten-Aufwand für C++.

Auch da denke ich, gibt es so'ne und solche. Ein Softwarehersteller, der 
sich in C eine Hardwareabstraktion gebaut hat, wird auch bei 
Portierungen weniger Aufwand treiben müssen. Guck dir mal die 
Enlightenment Foundation Libraries an: alles Hohes-C, ohne Inkrement 
dahinter. Und trotzdem softwaretechnisch sauber gelöst.

>> Na ja, ich seh auch zu, das weitestmöglich zu vermeiden und mir über
>> Type-Enums zu behelfen
> Das ist dann wieder sinnlos, denn da kann man genausogut typeid()
> verwenden, was mindestens genauso performant sein sollte.

Nö, dafür brauch ich eingeschaltete RTTI. Was bei proprietärem Code 
nicht unbedingt die cleverste Compilereinstellung ist.

> Ja, auto_ptr ist deprecated, es gibt jetzt unique_ptr und shared_ptr die
> in Kombination mit rvalue references jetzt richtig sinnvoll sind.

Ok, das sind die Boost, die in den Standard gewandert sind.

>> Hm, kann man drüber diskutieren, ob da der Multi-Paradigmen-Ansatz nicht
>> eigentlich genau dieses Ziel verfolgt, eine Allheilmittel-Sprache zu
>> sein... :)
> In den 80ern war das so gedacht :D

:) Damals sind 'se auch im Jogging-Anzug inne Disse gegangen... ^^

> Da haste jetzt das Vendor Lockin Problem... Das Frontend des Compilers
> hat ja eigentlich nichts mit der Ziel Plattform zu tun; die neuren GCC
> Versionen zB die C++11 können, können das automatisch für alle
> Plattformen wie AVR, ARM, win32, ...

Ist schon richtig, aber erzähl das mal M$.

> Lernen ja, aber das für "richtige" Projekte immer komplett
> durchzuziehen...

Hast schon recht, es ist mehr Code für den Anfang. Möchte ich in diesem 
Mini-Framework in ANSI-C jetzt eine neue Anzeigemöglichkeit schaffen, 
habe ich durch diese Strukturierung eine Art räumliche Lokalität für das 
Behandeln von Werten geschaffen.

> Genau dafür ist C nicht gedacht (C ist ein Byte processor ...), aber
> C++, Java, Python...

Verstehe ich das richtig, dass dein Argument impliziert, dass es nicht 
sinnvoll ist, lose gekoppelten Code in C zu entwickeln bzw. das 
anzustreben - bloß weil die Sprache dafür nicht designed wurde?

Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.