www.mikrocontroller.net

Forum: Compiler & IDEs C++?!?


Autor: C++'lerin (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hallo!

Ich habe vor 2 Jahren mit den AVRs angefangen. Da ich eigentlich C++ 
Programmiererin bin, wollte ich meine schicke dynamische Menu-Klasse 
verwenden, wurde aber von dem C++-Support von avr-g++ derbst enttäuscht: 
keine new, kein delete. (Von exceptions will ich gar nicht erst 
sprechen). Also habe ich erstmal alles umständlich in C umgeschrieben. 
Ca. 1 Jahr später bin ich dann auf MSP430 umgestiegen, weil mit diese 
saubere von Neumann Architektur sehr gefiel. Aber der C++-Support von 
msp430-g++  war auch nicht besser. Demnächst plane ich auf ARM 
umzusteigen. Wie sieht's da aus? Kann arm-g++ z.B. sowas compilieren:
class something
{
};

int main()
{
  something *a = new something();
  return 0;
}
Oder scheitert der auch mit sowas:
/tmp/ccEqo0Mb.o: In function `main':
test.cpp:(.text+0xa): undefined reference to `operator new(unsigned int)'
test.cpp:(.text+0x22): undefined reference to `operator delete(void*)'
test.cpp:(.text+0x28): undefined reference to `__cxa_allocate_exception'
test.cpp:(.text+0x36): undefined reference to `__cxa_throw'
test.cpp:(.text+0x3e): undefined reference to `vtable for __cxxabiv1::__pointer_type_info'
test.cpp:(.text+0x52): undefined reference to `vtable for __cxxabiv1::__class_type_info'

  

Autor: Jörg Wunsch (dl8dtl) (Moderator) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht lesenswert
"Da ich eigentlich Formel-1-Pilotin bin, habe ich neulich mal
versucht, das Rennrad bis zum Anschlag zu bringen.  Ich bin derb
enttäuscht worden.  Immer, wenn ich eine richtig freie Strecke
vor mir hatte, trottelte das Fahrzeug so allmählich vor sich
hin.  Jetzt möchte ich mir ein Mofa zulegen.  Funktioniert dort
eigentlich der Nachbrenner richtig?"

Autor: C++'lerin (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
???

Autor: lachender Dritter (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Der Herr Wunsch hat manchmal so "Anwandlungen"...

Liebe Grüße

Autor: Patrick Dohmen (oldbug) (Moderator) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Wieso "Anwandlungen"?
C++ auf dem AVR mit der GCC wird schon in der FAQ der Doku zur avr-libc 
behandelt. Es fehlt einfach die STL.
Auf dem ARM sieht das - WIMRE - besser aus. Aber wenn man's nicht weiss: 
einfach ausprobieren.

Btw.: einen Wrapper um new und delete wird unsere C++-F1-Pilotin wohl 
doch noch hinbekommen!?

Autor: Fabian Scheler (rosepeter)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
class something
{
};
 
int main()
{
  something *a = new something();
  return 0;
}

mal abgesehen davon, was der AVR-GCC jetzt für die C++-Welt unterstützt 
oder nicht bzw. ob es die STL gibt oder nicht - man kann mit C++ auch 
ganz wunderbar Programme schreiben, ohne gleich eine dynamische 
Speicherverwaltung, Exceptions oder RTTI zu verwenden. Diese Konzepte 
sind für komplexe Softwarearchitekturen vielleicht wirklich hilfreich, 
aber auf einem AVR zum Teil einfach vollkommen deplatziert, weil sie 
halt auch einen Batzen Ressource kosten. Wozu braucht man in obigem 
Beispiel eigentlich ein new()? Die Variable kommt auf den Stack - 
fertig, dann spart man sich auch gleich noch ein paar Speicherlöcher!

Ciao, Fabian

Autor: Embedded Windows CE User (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Versuchs doch mal mit einem Windows CE auf Atmel Basis. Ist nur so'n 
Vorschlag. Ich glaub Herr Wunsch hat's voll getroffen.

;-)

Autor: Hobbyprogger (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Ähem,
also echtes C++ mit Objektorientierung und dem ganzen schönen 
Exceptiongedöhns usw. gibt es nicht beim AVR-GCC !
Also alles schön in C proggen und gut ist ;-)

Autor: Ingo Elsen (ogni42)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Es geht ein subset des C++-Standards.

Was es nicht geht:
- Exceptions (und das ist nach meinem Empfinden auch nicht nötig, 
vielleicht erklärt mir mal jemand wozu man bei einer embedded 
Applikation exceptions benötigt)
- new/delete Das kann man sich über wrapper so man nicht ohne auskommt, 
selbst schreiben. Oder man nutzt malloc/free und Konstruktionsmethoden.
- Standard-Bibliothek (und damit keine IO-streams, sowie STL). Aber: Man 
kann bei Bedarf einen STL-Port integrieren.

s. auch die FAQ zur libc

An einer Stelle möchte ich Jörg widersprechen (und im selben Atemzug für 
die libc loben): C++ hat nichts mit Formel 1 zu tun und mit der 
aktuellen Version des avr-gcc sowie den von der libc bereit gestellten 
Funktionen kann man wunderbar mit C++ OO-Entwicklung auf den AVRs 
betreiben. Der Code ist genauso kompakt wie in C geschriebener - was 
beim Einsatz von Exceptions schon nicht mehr der Fall wäre und 
insbesondere den RAM-Verbrauch extrem in die Höhe treiben würde.

Autor: C++'lerin (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
War das 'Was es nicht geht:' jetzt auf avr-g++ oder arm-g++ bezogen?

BTW: Weiß jemand, ob und wie ich mit crossdev einen embedded arm 
toolchain für die ARM7 von NXP emergen kann?

Autor: Jörg Wunsch (dl8dtl) (Moderator) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Ingo Elsen wrote:

> An einer Stelle möchte ich Jörg widersprechen (und im selben Atemzug für
> die libc loben): C++ hat nichts mit Formel 1 zu tun ...

Das, was aber C++'lerin gewohnt war und gern hier tun wollte schon.

Mir ist schon klar, dass und warum man auch auf kleinen Controllern
C++ machen kann und will.  Mir ist aber auch einigermaßen (mit meinen
beschränkten C++-Kenntnissen) klar, was man dabei tun und lassen
sollte.

Autor: C++'lerin (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Jörg Wunsch wrote:
> Das, was aber C++'lerin gewohnt war und gern hier tun wollte schon.

Völliger Unsinn.

> Mir ist schon klar, dass und warum man auch auf kleinen Controllern
> C++ machen kann und will.  Mir ist aber auch einigermaßen (mit meinen
> beschränkten C++-Kenntnissen) klar, was man dabei tun und lassen
> sollte.

Mir auch. Glaub mir, ich weiß was ich tue.

Kann es sein, dass in diesem Forum ein C vs. C++ Glaubenskrieg herrscht? 
Denn in keinem Beitrag hat bis jetzt jemand meine Frage richtig 
beantwortet. Man hat nur C++ auf µCs niedergemacht.

Autor: Patrick Dohmen (oldbug) (Moderator) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht lesenswert
C++'lerin wrote:

> Kann es sein, dass in diesem Forum ein C vs. C++ Glaubenskrieg herrscht?

In keinster Weise!

Autor: Fabian Scheler (rosepeter)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
> beantwortet. Man hat nur C++ auf µCs niedergemacht.

auch das ist aus der Luft gegriffen

Ciao, Fabian

Autor: Karl Heinz (kbuchegg) (Moderator)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
C++'lerin wrote:
> Kann es sein, dass in diesem Forum ein
> C vs. C++ Glaubenskrieg herrscht?

Nein.
Viele Leute würden AVRs gerne mit C++ programmieren.
Allerdings kann C++ auf einem µC in der Größenordnung
eines Mega8/16/32 seine Vorteile nicht wirklich ausspielen.
Zudem ist die typische Art und Weise wie ein µC programmiert
wird, nicht sehr C++ freundlich, sodass der Vorteil von
C++ im Vergleich zu C schnell dahinschmilzt.

Summa summarum: mit C++ gewinnt man in diesem speziellen
Umfeld nicht soviel, dass es sich lohnen wuerde.

Autor: Stefan (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
> BTW: Weiß jemand, ob und wie ich mit crossdev einen embedded arm
> toolchain für die ARM7 von NXP emergen kann?

Grundsätzlich geht das (1). Allerdings wird eine generelle 
ARM-ELF-Toolchain erzeugt und keine spezielle für die NXP Targets. Als C 
Library bietet sich die Newlib (2) an.

Du müsstest dafür noch die Linkercontrolskripts mit dem Speicherlayout 
und an spezifische Initialisierungen angepasste Startup-Quellen 
beibringen. Für einige NXP Targets gibt diese Dateien schon z.B. bei den 
Examples im WinARM Paket (3). Auch bei den üblichen Verdächtigen z.B. 
der LPC... Group von Yahoo dürfte es auch Beispiele für die gängigen 
Targets geben.

(1) http://www.gentoo.org/proj/en/base/embedded/cross-...
(2) http://sourceware.org/newlib/
(3) http://www.siwawi.arubi.uni-kl.de/avr_projects/arm_projects/


Autor: Ingo Elsen (ogni42)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Also Glaubenskrieg ganz bestimmt nicht. Ich bin absoluter C++ Fan 
programmiere die AVRs aber in C aus einem einzigen Grund (denn 
new/delete, Exceptions und die Stdlib vermisse ich nicht):

Das Source Level Debugging im AVR Studio funktioniert nicht. Falls das 
jemand Abhilfe (oder eine Alternative) kennt: Bitte sagt sie mir.

Ansonsten würde ich sofort auf C++ umschwenken, da ich in C++ besseren 
Code schreibe als in C (was mehr an mir liegt als an den beiden 
Sprachen).

Aber nochmal: Wozu braucht man auf einem uC wie dem AVR exceptions und 
das new/delete der Standard-Bibliothek?

Autor: Jörg Wunsch (dl8dtl) (Moderator) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht lesenswert
C++'lerin wrote:

>> Mir ist schon klar, dass und warum man auch auf kleinen Controllern
>> C++ machen kann und will.  Mir ist aber auch einigermaßen (mit meinen
>> beschränkten C++-Kenntnissen) klar, was man dabei tun und lassen
>> sollte.

> Mir auch. Glaub mir, ich weiß was ich tue.

Hmm, exceptions, new/delete, late binding (vtables) -- bist du dir da
so sicher?  Klar, wenn man das alles wirklich braucht, ist es in C++
effektiver programmiert als in C.  Just, ich habe bislang noch nicht
so viele Controller-Applikationen erlebt, die das brauchen, und auch
die Leute, die hier am meistens in C++-Horn tuten (wie Rolf Magnus)
tun das eher wegen anderer Eigenschaften der Sprache als den von dir
benutzten/gewünschten.

Ich hätte übrigens liebend gern einen C++-Maintainer für die avr-libc
bzw. alles, was dazu gehört, aber selbst Rolf scheint wohl eher keine
Zeit dafür zu haben. :-(  (Dann hätten wir auch auf dem AVR zumindest
die Möglichkeit für all die genannten Dinge, wenngleich gerade
exceptions nach meiner ersten Erfahrung heftig ins Kontor schießen,
was den ROM-Verbrauch betrifft.)

Autor: Ingo Elsen (ogni42)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Exceptions schießen nicht nur was den ROM Verbrauch angeht ins Kontor, 
sondern auch was den Stack-Verbrauch (RAM) und die Performance angeht. 
Das ist den meisten Menschen, die C++ programmieren, leider nicht klar.

Hinzu kommt, dass die wenigsten die Exceptions als das sehen, was sie 
eigentlich sind: Die Entsprechung zu setjmp und longjmp in C. Wer das in 
seinen C-Apps für uC nicht vermisst, wird auch exceptions nicht 
vermissen. Wer es in seinen C++-Apps für uC braucht, kann setjmp und 
longjmp als Ersatz verwenden.

Die vtables tun nicht ganz so weh, weil die pro Klasse verwaltet werden 
(im ROM) und jedes Objekt nur einen zusätzlichen Pointer auf die aktuell 
gültige vtable mitbekommt. Hier sehe ich durchaus Anwendungspotenzial in 
uC Applikationen (insbesondere bei den großen AVRs mit 128 und 256kByte 
Flash.

Autor: Fabian Scheler (rosepeter)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
> Die vtables tun nicht ganz so weh, weil die pro Klasse verwaltet werden
> (im ROM) und jedes Objekt nur einen zusätzlichen Pointer auf die aktuell
> gültige vtable mitbekommt. Hier sehe ich durchaus Anwendungspotenzial in
> uC Applikationen (insbesondere bei den großen AVRs mit 128 und 256kByte
> Flash.

dazu möchte ich einfach mal auf den Artikel:

Lean and Efficient System Software Product Lines - Where Aspects Beat 
Objects

verweisen (einfach mal googeln). Ist übrigens sogar alles auf einem 
ATMega implementiert.

Ciao, Fabian

Autor: Ingo Elsen (ogni42)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Interessantes Paper. Allerdings ist mir nicht klar, wie man es hin 
bekommt, den doppelten Speicherverbrauch im Vergleich zur C-Applikation 
zu haben. Meines Erachtens geht das nur, wenn man viel zusätzliche 
Funktionalität mit einbringt. Das ist in dem Beispiel auch 
offensichtlich: Währen die C und AO Implementierung die Konfiguration 
statisch vornehmen, wird es in der OO Version dynamisch gemacht. Das ist 
dann in meinen Augen ein bisschen Äpfel mit Birnen verglichen.

Autor: Jörg Wunsch (dl8dtl) (Moderator) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Ingo Elsen wrote:

> Die vtables tun nicht ganz so weh, weil die pro Klasse verwaltet werden
> (im ROM) ...

Nein, leider im Moment (zumindest bei AVR-GCC) im RAM.  Das wäre einer
der Punkte für einen potenziellen AVR-G++-Maintainer rauszufinden,
wie man die in den ROM bringen kann (und dann mit LPM drauf zugreift).

Autor: Ingo Elsen (ogni42)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hm, da musst Du mir jetzt etwas auf die Sprünge helfen:
class A 
{
public:
  virtual void print( void )
  {
    volatile int i = 0;
  }

  virtual void read( void )
  {
    volatile int i = 42;
  }
};

class B : public A
{
public:
  virtual void print( void )
  {
    volatile int j = 1;
  }
};

int main(void)
{
  volatile A a;
  volatile B b;

  return 0;
}

assembliert bei mir zu (gekürzt):
  .file  "scratch.c"
  .arch attiny13
__SREG__ = 0x3f
__SP_H__ = 0x3e
__SP_L__ = 0x3d
__tmp_reg__ = 0
__zero_reg__ = 1
  .global __do_copy_data
  .global __do_clear_bss
  .section  .debug_abbrev,"",@progbits
.Ldebug_abbrev0:
  .section  .debug_info,"",@progbits
.Ldebug_info0:
  .section  .debug_line,"",@progbits
.Ldebug_line0:
  .text
.Ltext0:
  .weak  _ZTV1A
  .data
  .type  _ZTV1A, @object
  .size  _ZTV1A, 8
_ZTV1A:
  .word  0
  .word  0
  .word  pm(_ZN1A5printEv)
  .word  pm(_ZN1A4readEv)
  .weak  _ZTV1B
  .type  _ZTV1B, @object
  .size  _ZTV1B, 8
_ZTV1B:
  .word  0
  .word  0
  .word  pm(_ZN1B5printEv)
  .word  pm(_ZN1A4readEv)
  .text
  .weak  _ZN1A5printEv
  .type  _ZN1A5printEv, @function
_ZN1A5printEv:
.LFB2:
.LM1:
/* prologue: frame size=2 */
  ldi r26,lo8(2)
  ldi r27,hi8(2)
  ldi r30,pm_lo8(.L_virtual void A::print()_body)
  ldi r31,pm_hi8(.L_virtual void A::print()_body)
  rjmp __prologue_saves__+32
.L_virtual void A::print()_body:
/* prologue end (size=5) */
.LBB2:
.LBB3:
.LM2:
  std Y+1,__zero_reg__
  std Y+2,__zero_reg__
.LBE3:
.LBE2:
/* epilogue: frame size=2 */
  ldi r30,2
  adiw r28,2
  rjmp __epilogue_restores__+32
/* epilogue end (size=3) */
/* function virtual void A::print() size 10 (2) */
.LFE2:
  .size  _ZN1A5printEv, .-_ZN1A5printEv
  .weak  _ZN1A4readEv
  .type  _ZN1A4readEv, @function
_ZN1A4readEv:
.LFB3:
.LM3:
/* prologue: frame size=2 */
  ldi r26,lo8(2)
  ldi r27,hi8(2)
  ldi r30,pm_lo8(.L_virtual void A::read()_body)
  ldi r31,pm_hi8(.L_virtual void A::read()_body)
  rjmp __prologue_saves__+32
.L_virtual void A::read()_body:
/* prologue end (size=5) */
.LBB4:
.LBB5:
.LM4:
  ldi r24,lo8(42)
  ldi r25,hi8(42)
  std Y+1,r24
  std Y+2,r25
.LBE5:
.LBE4:
/* epilogue: frame size=2 */
  ldi r30,2
  adiw r28,2
  rjmp __epilogue_restores__+32
/* epilogue end (size=3) */
/* function virtual void A::read() size 12 (4) */
.LFE3:
  .size  _ZN1A4readEv, .-_ZN1A4readEv
  .weak  _ZN1B5printEv
  .type  _ZN1B5printEv, @function
_ZN1B5printEv:
.LFB4:
.LM5:
/* prologue: frame size=2 */
  ldi r26,lo8(2)
  ldi r27,hi8(2)
  ldi r30,pm_lo8(.L_virtual void B::print()_body)
  ldi r31,pm_hi8(.L_virtual void B::print()_body)
  rjmp __prologue_saves__+32
.L_virtual void B::print()_body:
/* prologue end (size=5) */
.LBB6:
.LBB7:
.LM6:
  ldi r24,lo8(1)
  ldi r25,hi8(1)
  std Y+1,r24
  std Y+2,r25
.LBE7:
.LBE6:
/* epilogue: frame size=2 */
  ldi r30,2
  adiw r28,2
  rjmp __epilogue_restores__+32
/* epilogue end (size=3) */
/* function virtual void B::print() size 12 (4) */
.LFE4:
  .size  _ZN1B5printEv, .-_ZN1B5printEv
.global  main
  .type  main, @function
main:
.LFB5:
.LM7:
/* prologue: frame size=4 */
  ldi r28,lo8(__stack - 4)
  ldi r29,hi8(__stack - 4)
  out __SP_H__,r29
  out __SP_L__,r28
/* prologue end (size=4) */
.LM8:
  ldi r24,lo8(0)
  ldi r25,hi8(0)
/* epilogue: frame size=4 */
  rjmp exit
/* epilogue end (size=1) */
/* function int main() size 7 (2) */
.LFE5:
  .size  main, .-main
.Letext0:
  .section  .debug_line
  .long  .LELT0-.LSLT0

.LSLT0:
  .word  2

  .long  .LELTP0-.LASLTP0


Jetzt bin ich in AVR Assembler nicht so fit, aber liegt die vtable 
_ZTV1A nicht per .word die Funktionszeiger im Textsegment an?

EDIT: Hat sich erledigt. Ich hatte das .data überlesen.

Autor: Gast (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
@C++'lerin:

Auf ARM7 geht vieles von c++ ohne Probleme (new, delete, ...). Aber 
nicht ohne dass man einen ganzen Tag am Makefile rumspielen darf. 
Erstaunlicherweise ist auch hier die Akzeptanz von c++ nicht so 
besonders gut.

Vor einiger Zeit hab ich es dann doch hingekriegt einen FAT16/32 
Filesystem-Driver für SD-Card zu schreiben der Objekte und Vererbung und 
etc nutzt. Der code ist mit minimalen Änderungen von MSVC++ portiert 
worden und dort wurde anstatt der SD-Card ein 128MB Image-File 
verwendet. Es lebe c++ :-)

Liest du überhaupt noch mit?

Mfg
Gast

Autor: C++'lerin (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
> Auf ARM7 geht vieles von c++ ohne Probleme (new, delete, ...).
Schön, dass endlich jemand meine Frage beantwortet. ;) Vielen Dank. :) 
Und gut zu wissen, das new/delete funktioniert. Auf Exceptions kann ich 
verzichten. Da tun's zur Not auch longjumps.

> Aber nicht ohne dass man einen ganzen Tag am Makefile rumspielen darf.
Was muss man denn beachten? Kannst du mal ein Beispiel-Makefile 
hochladen?

> Vor einiger Zeit hab ich es dann doch hingekriegt einen FAT16/32
> Filesystem-Driver für SD-Card zu schreiben der Objekte und Vererbung und
> etc nutzt. Der code ist mit minimalen Änderungen von MSVC++ portiert
> worden und dort wurde anstatt der SD-Card ein 128MB Image-File
> verwendet. Es lebe c++ :-)
Respekt. Würdest du den Treiber mit uns teilen (Codesammlung)?

> Liest du überhaupt noch mit?
Ja, ich lese noch mit.

Autor: Hans Wilhelm (hans-)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
mit new/delete oder malloc/free würd ich bei embedded zeug aber 
unheimlich aufpassen.. dein ram fragmentiert einfach zu schnell wenn du 
da massiv gebrauch davon machst und dann steht deine applikation... ist 
mir schon ein paar mal passiert...

73

Autor: C++'lerin (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Ja, das kenne ich. Bei malloc/free kann man dem etwas entgegenwirken, 
wenn man einheitliche Blockgrößen verwendet (z.B. 16 oder 32 Byte) und 
keine sehr großen Blöcke (mehr als 128 oder 256 Byte) mallociert. Für 
ein dynamisches Array nimmt mann dann z.B. nicht ein großen Block (macht 
Probleme beim realloc), sondern meherere keline (Stichwort: linked 
list). Außerdem sollte man nach jedem malloc/realloc den Pointer checken 
und gegebenenfalls Eine Fehlermeldung über LCD/UART/etc. ausgeben. Dann 
weiß man wenigstens wo der Fehler liegt, und sas Programm hält nicht 
einfach an.

Auf dem ARM werde ich aber mehr als genug Speicher haben, so dass ich 
wohl keine Probleme mit new/delete bekommen werde.

Autor: Patrick Dohmen (oldbug) (Moderator) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht lesenswert
C++'lerin wrote:

> Auf dem ARM werde ich aber mehr als genug Speicher haben, so dass ich
> wohl keine Probleme mit new/delete bekommen werde.

Da hast Du schon Dein erstes!

Autor: C++'lerin (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Ich sehe da kein Problem.

Autor: Rufus Τ. Firefly (rufus) (Moderator) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Wenn Dein Programm häufig Datenblöcke unterschiedlicher Größe 
anfordert/freigibt, kann es passieren, daß der Speicher "fragmentiert".

Das ist ein grundlegendes Problem aller Systeme, die mit dynamischer 
Speicherverwaltung und ohne MMU arbeiten.

Autor: C++'lerin (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Das ist mir bekannt! (s.o.)

Auf dem ARM habe ich aber wie gesagt genug Speicher, so dass das kein 
Problem sein sollte.

Autor: Fabian Scheler (rosepeter)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
> Auf dem ARM habe ich aber wie gesagt genug Speicher, so dass das kein
> Problem sein sollte.

Warum gehst du davon aus, dass du auf dem ARM genug Speicher hast? Nicht 
jeder ARM ist so ein Dickschiff-ARM, wie er in PDAs vor sich hin 
werkelt. Nur weil das ein 32-Bit Core ist, heißt das noch lange nicht, 
dass da auch richtig viel Speicher dran ist. Nimmt man z.B. mal die LPCs 
von NXP oder die SAM von Atmel, dann haben die auf dem Chip oft auch nur 
8 KB Speicher. Solltest du dich als Hobby-Bastlerin mit ARMs 
beschäftigen, wirst du mit sehr großer Wahrscheinlichkeit bei solchen 
eher kleinen ARMs heraus kommen, weil die Entwicklungssystem für die 
Dickschiffe kaum erschwinglich sind.

Ciao, Fabian

Autor: Rufus Τ. Firefly (rufus) (Moderator) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Äh, das kann auch bei "genug" Speicher ein Problem sein, das ist ja das 
heimtückische daran.

Autor: Peter Dannegger (peda)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Rufus t. Firefly wrote:
> Äh, das kann auch bei "genug" Speicher ein Problem sein, das ist ja das
> heimtückische daran.

Dann nimm halt noch nen Garbage-Collector dazu ;-)

Irgendwie muß man doch die Rechenleistung verpulvern.


Peter

Autor: Rufus Τ. Firefly (rufus) (Moderator) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Super. Dann kann man ja gleich mit C# und dem ganzen supercoolen 
.Net-Geraffel programmieren.

Autor: Patrick Dohmen (oldbug) (Moderator) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Windows CE!

Autor: Rufus Τ. Firefly (rufus) (Moderator) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Quatsch. Windows XP Embedded.


Wobei das noch die angenehmste Windows-Version überhaupt ist, denn die 
kann auch ohne Internet Explorer, Media Player betrieben werden. Und 
"aktivieren" muss/kann man die auch nicht. Dank des im Feature Pack 2007 
gelieferten FBWF (file based write filter) kann man auch sehr schön mit 
CF-Karten anstelle von Festplatten arbeiten. Ach, und mit 
USB-Massenspeichern anstelle von Festplatten übrigens auch.

Autor: C++'lerin (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
@Fabian Scheler:
Ich steige nicht auf ARM um, um wieder mit ein paar KB RAM auskommen zu 
müssen. Kennst du die LPC22XX? Da kann man soviel SRAM ranhängen, wie 
man will.

@rufus:
Natürlich fragmentiert der Speicher unabhängig von dessen Größe, aber 
man kann trotzdem immer noch einen passenden freien Speicherblock 
finden. Verstehst du? Deshalb sollte es kein Problem sein.

@peda, rufus, odblug:
Garbage-Collector, C#, Windows CE, Windows XP Embedded... werdet nicht 
albern, Leute.

Autor: Rufus Τ. Firefly (rufus) (Moderator) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht lesenswert
> Natürlich fragmentiert der Speicher unabhängig von dessen Größe, aber
> man kann trotzdem immer noch einen passenden freien Speicherblock
> finden.

Nein. Das bestreite ich. Sicher, es wird länger dauern, und sicher, je 
nach Anwendung muss das Problem auch nicht auftreten, aber 
ausgeschlossen ist es eben nicht.

Angenommen, Du hast 10 MByte Speicher zur Verfügung und füllst den mit 
90 kByte großen Objekten. Dann wird jedes zweite davon wieder 
freigegegeben (so daß also in Summe 5 MByte frei zu sein scheinen) und 
der Versuch, auch nur einen 100 kByte-Block anzufordern, schlägt fehl.

Vereinfachte Darstellung mit einem Extremfall, zugegeben.

Autor: Gast (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
@C++'lerin:

Der Treiber ist nie wirklich fertiggeworden - wenn ich mich richtig 
erinnere, ging zuletzt aber sogar das Erstellen von Verzeichnissen und 
Dateien mit langen Dateinamen. Aber fertig ist der nie geworden leider 
...

Der Treiber war für ein Projekt, das momentan "discontinued" ist:
http://home.in.tum.de/~pototsch/mp3neu/mp3_1.JPG
und
http://home.in.tum.de/~pototsch/mp3neu/mp3_2.JPG

Schreib mir doch mal eine mail, dann kriegst alles was du willst :-)
thomas.pototschnig@gmx.de

Mfg
Thomas

Autor: Rolf Magnus (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
> Ich hätte übrigens liebend gern einen C++-Maintainer für die avr-libc
> bzw. alles, was dazu gehört, aber selbst Rolf scheint wohl eher keine
> Zeit dafür zu haben. :-(

Ich hab mich in letzter Zeit nicht so mit den AVRs beschäftigt. Jetzt 
ist auch noch mein Programmer kaputt (ok, nicht soo ein Problem ;-) ). 
Allerdings fange ich demnächst einen neuen Job an, und da wird mir 
vermutlich nicht soviel Zeit bleiben. Da muß ich erstmal sehen, wie's da 
wird.

> Das wäre einer der Punkte für einen potenziellen AVR-G++-Maintainer
> rauszufinden, wie man die [vtables] in den ROM bringen kann (und dann
> mit LPM drauf zugreift).

Es ist nicht so einfach, das zum beheben, da GCC bekanntlich nicht für 
Harvard-Architekturen gedacht ist. vtables sind letztlich auch nichts 
anderes als globale Variablen. Man kann nicht verschiedene Speicher 
definieren, auf die mit verschiedenen Assembler-Instruktionen 
zugegriffen werden kann.
Ich hatte mir mal einen Hack überlegt, mit dem's vielleicht gehen 
könnte, aber ich bin im GCC-Quellcode nicht weit genug durchgestiegen, 
um das mal auszuprobieren.

Autor: Jörg Wunsch (dl8dtl) (Moderator) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Rolf Magnus wrote:

> Allerdings fange ich demnächst einen neuen Job an, und da wird mir
> vermutlich nicht soviel Zeit bleiben. Da muß ich erstmal sehen,
> wie's da wird.

Schade.  Für uns jedenfalls ;-), ich hoffe, dass du dich damit
verbesserst.

>> ..., wie man die [vtables] in den ROM bringen kann (und dann mit
>> LPM drauf zugreift).

> Ich hatte mir mal einen Hack überlegt, mit dem's vielleicht gehen
> könnte, aber ich bin im GCC-Quellcode nicht weit genug
> durchgestiegen, um das mal auszuprobieren.

Könnte man mit Björn Haase mal durchkauen, wenn du da Interesse hast.

Autor: Marco S (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Habe mal versucht meinen Reflexlader auf Mega8 von C nach C++ zu 
portieren. Vom Quelltext her sieht C++ wesentlich ordentlicher aus.

Größen gemessen mit avr-size *.o <elfdatei>

Programm in C:
   text    data     bss     dec     hex filename
     28       0       0      28      1c asmfkt.o
   1093      38       2    1133     46d avrreflex1.o
    961     121       0    1082     43a discharge.o
    608       3       0     611     263 display.o
   2037     147       1    2185     889 reflex1.o
    100       0       0     100      64 uuprintf.o
   6744     310      90    7144    1be8 avrreflex1


Programm in C++:
   text    data     bss     dec     hex filename
    436      13      54     503     1f7 avrreflex2.o
     20       0       0      20      14 common.o
    282       0       0     282     11a display.o
   1608      72      12    1692     69c timer.o
    188       3       0     191      bf usart.o
    100       0       0     100      64 uuprintf.o
   7884      96      66    8046    1f6e avrreflex2

Betrachtet man das C Programm, dann fügt der Linker ca. 2 kBytes hinzu. 
Unter C++ haben alle Funktionen des C Programms nicht in den Flash des 
M8 gepasst. Deshalb habe ich solange Funkionen weggestrichen, bis es 
gepasst hat. Aufblähung durch C++-Linker: Ca. 5,2 kBytes für weniger 
Funktionalität.

Dazu noch eine Frage: Schreibe ich die Konstruktoren der Klassen nicht 
direkt in die Klassendeklaration (Dateiendung .h), sondern in die 
Dateien mit der Endung .cpp, dann legt mir avr-g++ den Konstruktor 
doppelt in den Speicher bei gleichem Assembler-Code. Ist das normal, 
oder ist avr-g++ noch nicht so weit, als das er das abkann.

Marco


Autor: Jörg Wunsch (dl8dtl) (Moderator) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Marco S wrote:

> Aufblähung durch C++-Linker: Ca. 5,2 kBytes für weniger
> Funktionalität.

Was macht dich glauben, dass das vom Linker kommt?  Es könnte genauso
gut vom Compiler sein.

Außerdem sollte man nachsehen, was genau dazu geführt hat, sicher
lässt sich das auch abändern.

> Dazu noch eine Frage: Schreibe ich die Konstruktoren der Klassen nicht
> direkt in die Klassendeklaration (Dateiendung .h), sondern in die
> Dateien mit der Endung .cpp, dann legt mir avr-g++ den Konstruktor
> doppelt in den Speicher bei gleichem Assembler-Code. Ist das normal,
> oder ist avr-g++ noch nicht so weit, als das er das abkann.

Meiner Erinnerung nach ist das normal (beide Konstruktoren sind
für verschiedene Dinge), aber ich stecke nicht genug drin um genau
zu wissen, warum das so ist.  (OK, Optimiersungspotenzial wäre sicher,
die beiden zu einem zusammenzufassen, wenn sie identisch sind.)

Autor: Peter Dannegger (peda)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Marco S wrote:
> Vom Quelltext her sieht C++ wesentlich ordentlicher aus.

Könntest Du dann mal beide Quelltexte hier rein stellen, damit man sie 
vergleichen kann ?

Ich hab immer noch nicht kapiert, was bei C++ besser sein soll.

Wenn ich mir C++ Programme so ansehe, wird mir immer ganz schwummrig und 
ich verstehe nur Bahnhof.

Da sind immer erstmal 100 Seiten Deklarationen, bevor der eigentliche 
Programmcode beginnt.

Vor allem das mit der Vererbung sieht immer höllisch kompliziert aus.
Wenn ich also eine Funktion verstehen will, muß ich erstmal sämtliche 
anderen Funktionen kennen, die dieser irgendwas vererbt haben. Das ist 
dann ein riesen Kleister und ich kann die Funktionen nicht separat 
betrachten, verstehen und debuggen.

Ich mag es aber, wenn die einzelnen Funktionen möglichst universell 
sind, d.h. möglichst wenig von anderen Funktionen abhängen (wenig 
Vererbung ?).


Peter

Autor: Jörg Wunsch (dl8dtl) (Moderator) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht lesenswert
> Ich hab immer noch nicht kapiert, was bei C++ besser sein soll.

Wenn du die Sprache nicht kennst, kannst du das vermutlich auch nicht
verstehen.

Man kann mit jeder Programmiersprache natürlich Mist verzapfen, mit
manchen einfacher als mit anderen.

Autor: pumpkin (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
imho ist C++ für eingefleischte elektroniker, die vorher in C/ASM/... 
programmiert haben, schwieriger zu verstehen als für 'reine' 
informatiker. der höhere abstraktionsgrad (bei typischen C++ 
geschichten) verwirrt am anfang und die teilweise kryptische syntax 
(siehe [mehrfach]vererbung) tut ein übriges. trotzdem sollte man sich 
meiner meinung nach langsam mit C++ anfreunden, denn in garnicht so 
ferner zukunft wird mit sicherheit vorrangig damit programmiert; fragen 
nach hardware-ressourcen werden immer unwesentlicher (ich denke hierbei 
nicht unbedingt an µC's).

pumpkin

Autor: Falk (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
@pumpkin


>meiner meinung nach langsam mit C++ anfreunden, denn in garnicht so
>ferner zukunft wird mit sicherheit vorrangig damit programmiert; fragen
>nach hardware-ressourcen werden immer unwesentlicher (ich denke hierbei
>nicht unbedingt an µC's).

Damit hast du wohl leider Recht. :-( Und damit wird dem 
Softwareoverhead, der so schon ist wie er ist nochmehr Vorschub 
geleistet. Was früher (tm) aus nem P100 mit solider Programmierung lief 
braucht heute "Dank" Vista, Java und Konsorten, gepaart mit 
diletantischer Programmierungn nen Quadcore mit 2 GHz. Ohje.

MFG
Falk

P.S. Aber irgendwann wird es mal wieder "Back to the roots" gehen! ;-)

Autor: pumpkin (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
>> [...]diletantischer Programmierungn nen Quadcore mit 2 GHz.

naja, grafische oberflächen mit dem ganzen gebamsel hintendran frisst 
halt ordentlich...

>> P.S. Aber irgendwann wird es mal wieder "Back to the roots" gehen! ;-)

wenn sich bei dem ganzen JAVA/C#/...-gedöhns dann überhaupt noch jemand 
daran erinnert wie ein rechner wirklich funktioniert.  ; )
mal im ernst, die hochsprachen haben imho ihre berechtigungen, moderne 
anwendungen wären ohne sie schlicht undenkbar. und soooo weit weg wäre 
C++ doch garnicht von den 'roots' entfernt.


pumpkin

Autor: Peter Dannegger (peda)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Jörg Wunsch wrote:
>> Ich hab immer noch nicht kapiert, was bei C++ besser sein soll.
>
> Wenn du die Sprache nicht kennst, kannst du das vermutlich auch nicht
> verstehen.

Genau deshalb wäre ja eine echte praktische Anwendung mit direkter 
Vergleichsmöglichkeit äußerst lehrreich.

Die Beispiele in den C++ Lehrbüchern sind immer nur theoretisch und 
total praxisfern. Daran kann man einfach nichts lernen.


Peter

Autor: Falk (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
@pumpkin

>mal im ernst, die hochsprachen haben imho ihre berechtigungen, moderne
>anwendungen wären ohne sie schlicht undenkbar.

Auf jeden Fall! Aber so ganz koscher erscheint mir das nicht immer. 
Siehe Maustreiber mit 20 MB.

> und soooo weit weg wäre
>C++ doch garnicht von den 'roots' entfernt.

Kann ich nicht beurteilen.

MFG
Falk

Autor: Andreas Schwarz (andreas) (Admin) Benutzerseite Flattr this
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Muss ich wirklich zum 3. Mal das Maustreiber-mit-20MB-Argument 
widerlegen?

Autor: pumpkin (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
@Falk:

wäre mir auch nicht ganz koscher. aber das hat mit sicherheit teilweise 
seine berechtigung:
@Andreas:
ja, bitte! oder gib link wenn du's schonmal ausführlich gemacht hast. 
danke!


@Peter:

ich denke bei embedded-geschichten an dynamische benutzeroberflächen 
(z.b. menü's mit tiefe) oder modulare systeme. etwas praxisfern/selten, 
meinetwegen, aber brauchbar...


pumpkin

Autor: Andreas Schwarz (andreas) (Admin) Benutzerseite Flattr this
Datum:

Bewertung
0 lesenswert
nicht lesenswert

Autor: Marco S (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
@ Jörg

Shame on me, du hattest recht. Ich Dummerchen habe für den C++-Quellcode 
den avr-g++ direkt verwendet. Warum ich das gemacht habe, keine Ahnung. 
Verwende ich den avr-gcc passt das Ergebnis auch größenmäßig.

Wo liegen da eigentlich die Unterschiede zwischen avr-gcc und avr-g++? 
Wenn der avr-gcc sowieso c++ schluckt, wofür gibt es dann den avr-g++?

Autor: Ingo Elsen (ogni42)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Die Aufrufe der einzelnen Teile der gcc suite sind ein bisschen 
unterschiedlich, siehe

http://gcc.gnu.org/onlinedocs/gcc/Invoking-G_002b_...

Vielleicht liegt das daran.

Autor: Uhu Uhuhu (uhu)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Vielleicht bin ich ein bischen spät dran, aber das Thema hat einen 
Aspekt, der bisher nicht vorkam:

Den operator new kann man auch überladen. Damit läßt sich recht elegant 
das Problem mit der Speicherfragmentierung umgehen, wenn man dabei auf 
Speicherpools zurückgreift, aus denen Blocks mit ähnlicher Größe 
allokiert werden. Man muß dabei nicht unbedingt auf die 
Standard-Heap-Implementierung von C zurückgreifen.

Zum Speicherverbrauch: Es lohnt sich, die Maplistings des Linkers näher 
anzusehen, um herauszubekommen, welche Funktionen der C++ - RTL 
gegenüber C dazu kommen. Dann kann man sich überlegen, ob und wie man 
eigentlich nicht benötigtigte RTL-Module durch Dummies oder einfachere - 
µC angepaßte - Implementierungen ersetzen kann.

Daß ganze Geschwätz über den per se unstillbaren Resourcenhunger von C++ 
ist jedenfalls ziemlicher Unsinn. Man kann auch so stümperhaft mit C 
hantieren, daß aus einem Miniproblem ein Riesenbrocken von Programm 
entsteht.

Wenn man nur C++ nach Kochbuch für Großrechner auf einem µC abgeigen 
will, wirds halt nichts.

Autor: Marvin (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Wäre das hier eine Lösung?

http://sun.systemnews.com/articles/58/2/opt-dev/8387

Ist ein C++ -> C Transpiler.

Da ich des C++ nicht mächtig bin, habe ich keine Ahnung, ob das etwas 
taugt, würde mich aber mal interessieren. Vielleicht tu ich mir dann 
doch mal C++ in den Kopp...

Autor: Uhu Uhuhu (uhu)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Das ist das Konzept, nach dem die ganz frühen C++ - Compiler 
funktionierten. Es ist ein Umweg, den man beim heutigen Angebot an 
C++-Compilern nicht mehr gehen muß.

Der C-Code, der hinten raus kommt, ist sicher nicht der reine Genuß.

Ich würde abraten.

Autor: Marvin (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Der C-Code, der hinterher rauskommt, interessiert ja niemanden. Es geht 
nur darum, ob man so C++ mit einem Compiler, der keine volle C++ 
Unterstützung hat, verwenden kann.
Ich schau mir den Assembler-Code, der bei einem C-Compilat hinten 
rauskommt, eigentlich auch nur noch sehr selten an ;)

Autor: Karl Heinz (kbuchegg) (Moderator)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Uhu Uhuhu wrote:
> Das ist das Konzept, nach dem die ganz frühen C++ - Compiler
> funktionierten. Es ist ein Umweg, den man beim heutigen Angebot an
> C++-Compilern nicht mehr gehen muß.
>
> Der C-Code, der hinten raus kommt, ist sicher nicht der reine Genuß.
>
> Ich würde abraten.

Seh ich auch so.
Ein 'richtiger' C++ Compiler kann dann auch noch ein paar
Optimierungen machen (zb. named return value optimization)
die bei einer vorhergehenden Übersetzung nach C wahrscheinlich
auf der Strecke bleiben würden. Vor allem mit dem Referenz
Konzept sind da noch ein paar Optimierungen möglich.

Die meisten Tests auf Desktop Ebene haben (hatten) zum
Ergebnis dass in C++ geschriebene Programme meistens nicht größer
oder zumindest nicht viel größer sind als gleichwertige C Programme,
aber oft etwas schneller ablaufen. Die grosse Ausnahme ist meist,
wenn die I/O streams benutzt werden. Soll aber auch schon besser
werden.

Ein Beispiel:
Ihr kennt doch alle die Funktion qsort():
Quicksort der man einen Callback übergibt, der für das Vergleichen
von 2 Items zuständig ist.
Macht man das in C++ Manier, dann benutzt man das std::sort()
aus algorithm.h. Der braucht natürlich auch eine Vergleichs-
funktionalität. Da std::sort aber ein Template ist, kann der
Compiler den Vergleich direkt in den Sortieralgorithmus einbauen
und spart sich so den Call-Overhead einer Vergleichsfunktion.

Was auch oft übersehen wird: C++ Code ist meist robuster, da das
Fehlerhandling konsequenter durchgezogen wird (RAII lässt grüßen).
C Programmierer sind da oft notorisch faul und schon vergleicht
man Äpfel mit Birnen: Ein C++ Programm, dass auch mit Problemen
noch gut zurecht kommt mit einem C Programm das bei der geringsten
Kleinigkeit nur noch Unsinn macht. Und wir alle wissen:
Es ist nicht ungewöhnlich, dass Fehlerbehandlung mehr Code braucht
als der reine 'Arbeitscode'.

Autor: Uhu Uhuhu (uhu)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Der C++ -> C Precompiler ist eigentlich nur dann sinnvoll, wenn man 
bestehenden C++ - Code in eine Umgebung portieren will, für die es 
keinen (brauchbaren) C++ - Compiler gibt, aber ein C-Compiler zur 
Verfügung steht.

Ich würde das Teil sofort verwenden, um C++ - Programme auf meinem 
Taschenrechner zum Laufen zu bringen - nur leider habe ich für den noch 
keinen C-Compiler gefunden. Aber das kann ja noch werden...

Autor: Christoph __ (chris)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
> Macht man das in C++ Manier, dann benutzt man das
> std::sort() aus algorithm.h.

Kleine Korrektur: Du meinst den header algorithm.

Mit .h gibt es den laut Standard nicht.

Autor: Felix (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Wie kann man die Operatoren 'new' und 'delete' selber implementieren?

Ich habe folgendes versucht:
void *operator new(size_t size)
{
  return malloc(size);
}

void operator delete(void* ptr)
{
  free(ptr);
}
Das gibt aber:
undefined reference to `__gxx_personality_v0'

Autor: Felitas (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
-fno-exceptions

Autor: Felizitas (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert

Autor: arc (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
> Macht man das in C++ Manier, dann benutzt man das std::sort()
> aus algorithm.h. Der braucht natürlich auch eine Vergleichs-
> funktionalität. Da std::sort aber ein Template ist, kann der
> Compiler den Vergleich direkt in den Sortieralgorithmus einbauen
> und spart sich so den Call-Overhead einer Vergleichsfunktion.

Das hat allerdings immernoch den Nachteil, das sort nur O(n)=n log n 
Algorithmen implementieren kann.

Autor: Karl Heinz (kbuchegg) (Moderator)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
arc wrote:
>> Macht man das in C++ Manier, dann benutzt man das std::sort()
>> aus algorithm.h. Der braucht natürlich auch eine Vergleichs-
>> funktionalität. Da std::sort aber ein Template ist, kann der
>> Compiler den Vergleich direkt in den Sortieralgorithmus einbauen
>> und spart sich so den Call-Overhead einer Vergleichsfunktion.
>
> Das hat allerdings immernoch den Nachteil, das sort nur O(n)=n log n
> Algorithmen implementieren kann.

Hast du den Rest gelesen?
Darum geht es doch gar nicht. Es geht darum welche Möglichkeiten
der Optimierung ein C++ Compiler im Vergleich zu einem C Compiler hat.
Bleib doch bitte ein bischen beim Thema.

Autor: arc (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
> Hast du den Rest gelesen?
> Darum geht es doch gar nicht. Es geht darum welche Möglichkeiten
> der Optimierung ein C++ Compiler im Vergleich zu einem C Compiler hat.
> Bleib doch bitte ein bischen beim Thema.

Ist denn sichergestellt bzw. kann sichergestellt werden, daß die 
Vergleichsoperation inline ausgeführt wird und nicht doch als normaler 
Funktionsaufruf übersetzt wird? Erzeugt jeder Compiler/Linker nur die 
erforderlichen Spezialisierungen?
Der beste Optimierer sitzt (z.Z.) immernoch vor dem Rechner.

Autor: chippy (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
> Der beste Optimierer sitzt (z.Z.) immernoch vor dem Rechner.
Nicht immer! ;)

Autor: Uhu Uhuhu (uhu)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Die Aufgabe eines Optimierers ist nicht, aus einem vergurkten 
Algorithmus den bestmöglichen zu machen.

Die Idiotie, auf einem reinen Integer-µC Sensorwerte mit 
Fließkommaarithmetik zu behandeln, kann er auf keinen Fall glatt 
bügeln...

Autor: Andreas Schwarz (andreas) (Admin) Benutzerseite Flattr this
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Uhu Uhuhu wrote:
> Die Idiotie, auf einem reinen Integer-µC Sensorwerte mit
> Fließkommaarithmetik zu behandeln, kann er auf keinen Fall glatt
> bügeln...

Wenn relativ komplizierte Berechnungen notwendig sind, aber die 
Geschwindigkeit keine Rolle spielt, dann ist es Idiotie KEINE 
Fließkommaarithmetik zu verwenden.

Autor: Uhu Uhuhu (uhu)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Andreas Schwarz wrote:
> Wenn relativ komplizierte Berechnungen notwendig sind, aber die
> Geschwindigkeit keine Rolle spielt, dann ist es Idiotie KEINE
> Fließkommaarithmetik zu verwenden.

Vergleicht man Auflösung und Wertebereich gängiger Sensoren mit denen 
der Datentypen float oder double, fällt auf, daß da ein ziemliches 
Mißverhältnis besteht.

Rechnet man den Sensorwert in ein Fließkommaformat um, gewinnt man nicht 
Genauigkeit, sonden Rauschen.

Dieses Rauschen bezahlt man auch noch mit einem um Größenordnungen 
erhöhten Bedarf an Rechenleistung - m.a.W.: Man heizt, nur weil man 
vorher nicht gedacht hat.

Mit etwas Überlegung lassen sich alle derartigen Probleme mit 
Integer-Datentypen berechnen.

Die Mathematik nicht zu berherrschen, um eine Problemlösung per 
int-Artihmentik zu realisieren, ist jedenfalls das allerletzte Argument 
für den Einsatz von Fließkomma.

Autor: Andreas Schwarz (andreas) (Admin) Benutzerseite Flattr this
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Grundregel beim Programmieren: optimiert wird dann, wenn es nötig ist. 
Also schreibt man eine komplizierte Rechnung einfach erst mal in Float 
hin, statt Zeit in eine Integerimplementierung zu stecken. Wenn sich 
dann herausstellt dass das zu groß oder zu langsam ist kann man immer 
noch umsteigen. Wenn die Berechnung aber nur einmal pro Sekunde benötigt 
wird ist es völlig irrelevant ob sie 10 µs oder 1 ms dauert; wichtiger 
ist, dass man mit einem Blick sehen kann was gerechnet wird, und auch 
einfach Änderungen vornehmen kann, statt sich durch einen unnötigen Wust 
von Bitschiebereien und ähnlichem kämpfen zu müssen.

Wenn der Programmspeicher kleiner als die Float-Bibliothek ist verbietet 
sich Float natürlich von vornherein; aber bei einem Controller mit zig 
kB Flash spielt ein konstanter Overhead von 2-4 kB meistens keine Rolle.

Autor: Karl Heinz (kbuchegg) (Moderator)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Andreas Schwarz wrote:
> Grundregel beim Programmieren: optimiert wird dann, wenn es nötig ist.
> Also schreibt man eine komplizierte Rechnung einfach erst mal in Float
> hin,

Das kommt drauf an wie kompliziert die Berechnung tatsächlich ist.
Ist sie nur kompliziert genug, dann öffnet sich mit der Verwendung
von float (anstatt double, dass es leider in WinAVR nicht gibt)
ein ganzer Sack neuer Probleme.

Und um keine Missverständnisse aufkommen zu lassen: Ein richtiger
double behebt diese Probleme nicht. double macht sie nur etwas
kleiner.

Wer noch nie in einer komplexen Berechnung nach Rundungsfehlern
gesucht und nach Wegen geforscht hat, sie zu umgehen, möge sein
Glück preisen. Die anderen wissen wovon ich rede.

http://docs.sun.com/source/806-3568/ncg_goldberg.html

Ungefähr in der Mitte des Textes ist ein Kapitel 'Optimizers'.
Wenn auch der Rest eher theoretischer Natur ist, (nichts desto
trotz ist der aber wichtig), so zeigt dieses Kapitel was bei
naiver Hintipperei von floating point Ausdrücken so alles passieren
kann.

Autor: Uhu Uhuhu (uhu)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
> Grundregel beim Programmieren: optimiert wird dann, wenn es nötig ist.

Die kann aber nicht gründliche Systemanalyse und Planung vor der 
Implementierung ersetzen.

Der unüberlegte Einsatz von Fließkommaformaten dürfte einer der 
verbreitetsten Anfängerfehler sein.

Autor: Uhu Uhuhu (uhu)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Das Problem der Fließkommaformate ist, daß Programmierer sie gerne für 
eine technische Realisierung Reeller Zahlen halten.

In Wirklichkeit verhalten sie sich ganz und garnicht so und Numeriker 
können die tollsten Beispiele dafür vorführen - siehe obigen Link von 
Karl heinz Buchegger.

Zudem sind die Vorgänge in einem float/double-Emulator für Programmierer 
ziemlich undurchsichtig und folglich das Resultat zumindest unsicher.

Das Gegenmodell: Mathematische Analyse des Problems und Approximation 
der benötigten Berechnungen mit int-Typen, incl. einer 
Fehlerabschätzung.

Packt man diese int-Approximation in den µC, weiß man genau, was man von 
den Daten, die hinten heraus kommen, zu halten hat.

Die Vorgehensweise läßt sich sicherlich systematisieren und sogar 
automatisieren - vielleicht gibt es ja schon solche Generatoren...

Die float/double-Rechnung liefert jedenfalls keine Fehlerabschätzung. 
Eine Fehlerrechnug dafür zu erstellen, wird beliebig kompliziert.

Autor: Andreas Schwarz (andreas) (Admin) Benutzerseite Flattr this
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Dass Fließkomma ein Allheilmittel ist hat niemand behauptet. Aber nehmen 
wir doch mal ein konkretes Beispiel: Taupunktberechnung. Mit Float 
(double oder single spielt erst in der 5. Nachkommastelle eine Rolle) 
sind das ein paar Zeilen Code, in Festkomma darf man sich erst mal 
Gedanken machen wie man den Logarithmus implementiert - wenn man noch 
genug Platz im Flash hat ist das einfach nur Zeitverschwendung.

Autor: Karl Heinz (kbuchegg) (Moderator)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Andreas Schwarz wrote:
> Dass Fließkomma ein Allheilmittel ist hat niemand behauptet.

Das haben wir dir auch nicht unterstellt.

Nur halte ich die Aussage

> Also schreibt man eine komplizierte Rechnung einfach erst mal
> in Float hin,

für eine gewagte Aussage, die ich so einem Newbie nicht unterbreiten
würde. Vor allem das Wort 'einfach' im Zusammenhang mit
'komplizierter Berechnung' stört mich da drinnen.

Autor: Andreas Schwarz (andreas) (Admin) Benutzerseite Flattr this
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Karl heinz Buchegger wrote:
> Andreas Schwarz wrote:
>> Also schreibt man eine komplizierte Rechnung einfach erst mal
>> in Float hin,
>
> für eine gewagte Aussage, die ich so einem Newbie nicht unterbreiten
> würde. Vor allem das Wort 'einfach' im Zusammenhang mit
> 'komplizierter Berechnung' stört mich da drinnen.

Mit "komplizierte Berechnung" meine ich: alles was über ein paar 
Multiplikationen und Additionen hinausgeht. Mit "einfach hinschreiben" 
meine ich: man kann die Formeln aus der Mathematik/Physik einfach 
runterschreiben und es funktioniert.

Autor: Karl Heinz (kbuchegg) (Moderator)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Andreas Schwarz wrote:
> Aber nehmen
> wir doch mal ein konkretes Beispiel: Taupunktberechnung. Mit Float
> (double oder single spielt erst in der 5. Nachkommastelle eine Rolle)
> sind das ein paar Zeilen Code, in Festkomma darf man sich erst mal
> Gedanken machen wie man den Logarithmus implementiert - wenn man noch
> genug Platz im Flash hat ist das einfach nur Zeitverschwendung.

Natürlich hat floating point seinen Stellenwert und bei der
von dir genannten Aufgabenstellung macht es wahrscheinlich
auch keinen Sinn da was anderes zu bemühen. Oder doch?
Ich kenne die Formel nicht und weis nicht wie sich ein Taupunkt
berechnet.
Das ist ja die Krux an floating point Problemen: Jedes Problem
ist anders und jedes Problem muss für sich alleine analysiert
werden ob Rundungsfehler sich auswirken oder nicht.

Damit haben aber gerade Neulinge ein riesiges Verständnisproblem
(mal ganz abgesehen von der "Die Zahl kommt aus dem Computer, die
 muss stimmen!" - Mentalität)

Autor: Karl Heinz (kbuchegg) (Moderator)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Andreas Schwarz wrote:
> Karl heinz Buchegger wrote:
>> Andreas Schwarz wrote:
>>> Also schreibt man eine komplizierte Rechnung einfach erst mal
>>> in Float hin,
>>
>> für eine gewagte Aussage, die ich so einem Newbie nicht unterbreiten
>> würde. Vor allem das Wort 'einfach' im Zusammenhang mit
>> 'komplizierter Berechnung' stört mich da drinnen.
>
> Mit "komplizierte Berechnung" meine ich: alles was über ein paar
> Multiplikationen und Additionen hinausgeht. Mit "einfach hinschreiben"
> meine ich: man kann die Formeln aus der Mathematik/Physik einfach
> runterschreiben und es funktioniert.

Wenn es nur so einfach wäre:
Wenn in derselben Formel sehr grosse und sehr kleine Zahlen
gleichzeitig vorkommen, hast du ein Problem. Das fängt schon
bei einer einzigen Addition an:

    1234567.890 + 0.01

wird mit float nicht das gewünschte Ergebnis bringen.


Autor: Uhu Uhuhu (uhu)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
> Mit Float (double oder single spielt erst in der 5. Nachkommastelle
> eine Rolle) sind das ein paar Zeilen Code, in Festkomma darf man sich
> erst mal Gedanken machen wie man den Logarithmus implementiert.

Nein. Man muß sich nicht überlegen, wie man in int den Logarithmus 
implementiert und die Tatsache, daß das Problem erst mit der 5. 
Nachkommastelle lebendig wird, ist kein Argument für den Einsatz von 
float & Co.

Wenn man sich eine Lookup Tabelle baut, die die Sensorwerte auf den 
jeweiligen Meßwert abbildet, dann verschindet der Logarithmus dort drin 
und der µC merkt nichts davon.

Das mit der 5. Nachkommastelle ebenso.

Die Größe der LUT ergibt sich dabei aus der Dynamik der zugrunde 
liegenden Funktion, den Genauigkeitsanforderungen an die Approximation 
und dem benutzten Interpolationsverfahren, mit dem Zwischenwerte 
berechnet werden.

Autor: Andreas Schwarz (andreas) (Admin) Benutzerseite Flattr this
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Das Denken ersetzten Float-Zahlen auch nicht, aber wenn er ein paar 
Grundregeln beachtet kann auch der Neuling Float sinnvoll anwenden. Bei 
Integer gibt es genauso Fallstricke: Überläufe in Teilausdrücken, 1/10 * 
100 == 0, signed vs. unsigned, usw.

Wie auch immer, ich wollte nur der Aussage widersprechen, dass die 
Verwendung von Soft-Float auf einem µC "Idiotie" wäre.

Autor: Andreas Schwarz (andreas) (Admin) Benutzerseite Flattr this
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Uhu Uhuhu wrote:
> Das Problem der Fließkommaformate ist, daß Programmierer sie gerne für
> eine technische Realisierung Reeller Zahlen halten.
>
> In Wirklichkeit verhalten sie sich ganz und garnicht so und Numeriker
> können die tollsten Beispiele dafür vorführen - siehe obigen Link von
> Karl heinz Buchegger.

Und trotzdem wirst du keinen Numeriker finden, der Numerikprobleme in 
Integerrechnung löst, wenn es nicht wegen Einschränkungen der Hardware 
nötig ist.

> Die Größe der LUT ergibt sich dabei aus der Dynamik der zugrunde
> liegenden Funktion, den Genauigkeitsanforderungen an die Approximation
> und dem benutzten Interpolationsverfahren, mit dem Zwischenwerte
> berechnet werden.

Und die Bilanz?
- >10-fache Menge an Code
- >10-facher Zeitaufwand
- schlechtere Genauigkeit
- 2 kB Flash gespart.

Autor: Uhu Uhuhu (uhu)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
> Wie auch immer, ich wollte nur der Aussage widersprechen, dass die
> Verwendung von Soft-Float auf einem µC "Idiotie" wäre.

Nun gut, ich gebe gerne zu, daß meine Ausdrucksweise etwas überspitzt 
war und nicht für alle Fälle gilt.

Allerdings sind die fachlich gerechtfertigten praktischen Einsätze davon 
um mehrere Zehnerpotenzen seltener, als man es hier im Forum feststellen 
kann.

Für den Rest gilt: Bestenfalls zu unerfahren...

Autor: Andreas Schwarz (andreas) (Admin) Benutzerseite Flattr this
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Uhu Uhuhu wrote:
> Allerdings sind die fachlich gerechtfertigten praktischen Einsätze davon
> um mehrere Zehnerpotenzen seltener, als man es hier im Forum feststellen
> kann.

Das ist allerdings möglich (es wurde hier auch schon mal in 
Fließkommarechnung implementierte Tastenentprellung gesichtet).

Autor: Uhu Uhuhu (uhu)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
> Und trotzdem wirst du keinen Numeriker finden, der Numerikprobleme in
> Integerrechnung löst, wenn es nicht wegen Einschränkungen der Hardware
> nötig ist.

Numeriker werden sich kaum mit Problemen auseinandersetzten, die grade 
mal lumpige 1-4 k verschiedene Zustände haben - wenn es sich um 
Dimensionen handelte, wäre das was anderes.

Für Massenprodukte spielt es u.U. eine entscheidende Rolle, ob das 
Problem mit einem kleinen, oder einem großen µC gelöst wird; die 
Einschränkungen i.S. Hardware sind also immer gegeben, es sei denn man 
bastelt irgendwas für sich selbst, oder plant den großen 
wirtschaftlichen Flopp.

> - schlechtere Genauigkeit

Das ist blanker Unsinn. Du solltest Dich dringend mit der Materie 
auseinandersetzen.

> (es wurde hier auch schon mal in Fließkommarechnung implementierte
> Tastenentprellung gesichtet).

Ich habe letzhin einen Stackoverflow in einem Dateisystem analysiert. 
Ursache war eine rekursiv programmierte Wait-Funktion...

Autor: Andreas Schwarz (andreas) (Admin) Benutzerseite Flattr this
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Uhu Uhuhu wrote:
>> Und trotzdem wirst du keinen Numeriker finden, der Numerikprobleme in
>> Integerrechnung löst, wenn es nicht wegen Einschränkungen der Hardware
>> nötig ist.
>
> Numeriker werden sich kaum mit Problemen auseinandersetzten, die grade
> mal lumpige 1-4 k verschiedene Zustände haben - wenn es sich um
> Dimensionen handelte, wäre das was anderes.

Andererseits spielt bei diesen 1-4 k verschiedenen Zuständen auch deine 
Fehlerabschätzung keine Rolle.

> Für Massenprodukte spielt es u.U. eine entscheidende Rolle, ob das
> Problem mit einem kleinen, oder einem großen µC gelöst wird; die
> Einschränkungen i.S. Hardware sind also immer gegeben, es sei denn man
> bastelt irgendwas für sich selbst, oder plant den großen
> wirtschaftlichen Flopp.

Wie gesagt: wenn sich herausstellt dass Float zu groß ist, dann kann man 
immer noch auf Integer umsteigen. Wenn sich herausstellt dass am Ende 
noch 10 kB Flash übrig sind, dann hat man mit Integer Zeit verschwendet.

>> - schlechtere Genauigkeit
>
> Das ist blanker Unsinn. Du solltest Dich dringend mit der Materie
> auseinandersetzen.

Du solltest mal von deinem hohen Ross runterkommen.

Autor: arc (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Taupunkt:

Hier würde ich auch keine Klimmzüge machen, um das ohne FPs zu 
berechnen, da sich die Parameter nur (relativ) langsam ändern können, 
die Ausgabe auf einem Display nur selten vorkommt oder man das ganze 
auch bequem nachträglich im PC berechnen kann.

p.s. diesmal ohne \\ oder \newline

Autor: Uhu Uhuhu (uhu)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Die mathematische Beschreibung des Problems gilt mit Sicherheit nicht
für alle reellen Zahlen.

Eine technische Realisierung ist erst dann sinnvoll möglich, wenn die
Randbedingungen klar definiert sind.

Was ist T, rH?
In welchen Wertebereichen fallen sie an?
Welche Auflösung?
Jeweils in Sensorwerten, nicht irgendwelche FP-Zahlen!

Autor: arc (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
T = Temperatur, rH = relative Luftfeuchtigkeit
Wertebereiche: Temperatur z.B. im Bereich -30 °C - 30/50 °C, rH 0..1
Hinzukommen div. Fallunterscheidungen (z.B. über Wasser/Eis).
(U.U. auch andere Eingangsgrößen wie absolute Feuchte statt rH, 
Sättigungsdrücke, Partialdrücke etc.)
Sinnvolle Auflösungen: Temperatur 0.1 °C, rH 0.1% (eher 1%)
Unsicherheit der genannten Formel: +-0.4 °C (0 °C < T < 60 °C und 0 < rH 
< 1)

Damits nicht ganz so einfach wird: Keine digitalen 
Feuchte/Temperatursensoren,
sondern eher PT100/PT1000 oder Thermoelemente und kapazitive 
Feuchtesensoren.

Autor: Michael Stather (kyromaster)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Also um nochmal zur ursprünglichen Frage zurückzukommen, ich wäre auch 
interessiert einen AVR in C++ ohne libc++ o.Ä. zu programmieren, einfach 
nur um die Klassensyntax auszunutzen. Klar geht das alles "im Prinzip" 
auch in C, aber wenn ich nur Klassen verwende (und nur auf Referenzen 
beim Übergeben setze) habe ich IMHO ja keinen Overhead.
Kann man die new() und delete() operatoren einfach selbstdefinieren und 
an malloc() und free() weiterleiten? Eigentlich müsste dies ja gehen.

Autor: I_ H. (i_h)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Klar geht das, das sind einfache Operatoren die du überladen kannst.


Aber ehrlich gesagt halte ich es für ziemlichen Dummfug auf einem uC mit 
C++ loszulegen. Namespaces sind das einzige das man sinnvoll auf einem 
uC einsetzen kann, aber das wars dann schon wieder.

Und nein, ich bin kein C Verfechter, ich programmier sogar recht gern in 
C++ und benutze auch oft Templates und artverwandtes, größere Projekte 
fang ich in reinem C garnet erst an.
Auf einem Mikrocontroller ist reines C aber ganz einfach sinnvoller.

Das ist aber allgemein ein Problem bei der Softwarentwicklung, da werden 
teilweise performancekritische Sachen schön sauber in Klassen verpackt 
damit der Code elegant ausschaut, und ohne Klassen wär die Geschichte 
10mal so schnell.
Dann werden neue Rechner angeschafft, weil der Code in C++ zu langsam 
ist... und Javianer kommen auf die absurde Idee ihre Sprache wär 
schneller.

Autor: Michael Stather (kyromaster)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Naja, wenn ich statt structs Klassen verwende, und nur das von c++, habe 
ich ja IMHO keinen Overhead bezüglich Speicher. Und das Referenzieren 
des this-Zeigers in Methoden sollte ja nicht so schlimm sein.
Ich sehe das Ganze nicht als C++, sondern eher als C++-Light, Klassen, 
eventuell Namespaces und das wars. Klar mit ner stdlib braucht man auf 
sonem yC gar nicht anzufangen.

Antwort schreiben

Die Angabe einer E-Mail-Adresse ist freiwillig. Wenn Sie automatisch per E-Mail über Antworten auf Ihren Beitrag informiert werden möchten, melden Sie sich bitte an.

Wichtige Regeln - erst lesen, dann posten!

  • Groß- und Kleinschreibung verwenden
  • Längeren Sourcecode nicht im Text einfügen, sondern als Dateianhang

Formatierung (mehr Informationen...)

  • [c]C-Code[/c]
  • [avrasm]AVR-Assembler-Code[/avrasm]
  • [code]Code in anderen Sprachen, ASCII-Zeichnungen[/code]
  • [math]Formel in LaTeX-Syntax[/math]
  • [[Titel]] - Link zu Artikel
  • Verweis auf anderen Beitrag einfügen: Rechtsklick auf Beitragstitel,
    "Adresse kopieren", und in den Text einfügen




Bild automatisch verkleinern, falls nötig
Bitte das JPG-Format nur für Fotos und Scans verwenden!
Zeichnungen und Screenshots im PNG- oder
GIF-Format hochladen. Siehe Bildformate.
Hinweis: der ursprüngliche Beitrag ist mehr als 6 Monate alt.
Bitte hier nur auf die ursprüngliche Frage antworten,
für neue Fragen einen neuen Beitrag erstellen.

Mit dem Abschicken bestätigst du, die Nutzungsbedingungen anzuerkennen.