Herzlich Willkommen, lieber Gast!
  Sie befinden sich hier:

  Forum » C / C++ (ANSI-Standard) » dynamische Arrays

Forum | Hilfe | Team | Links | Impressum | > Suche < | Mitglieder | Registrieren | Einloggen
  Quicklinks: MSDN-Online || STL || clib Reference Grundlagen || Literatur || E-Books || Zubehör || > F.A.Q. < || Downloads   

Autor Thread - Seiten: > 1 <
000
23.05.2011, 00:32 Uhr
Hans
Library Walker
(Operator)


Hi,

in diesem Thread findet sich im Programm folgender Code:

C++:
  int anz;

  cout << "Gebe Anzahl an: ";
  cin >> anz;
  cout << endl;

  int code[anz];


Dazu meinen der OpenWatcom C++ 1.9 und der Borland C++ 5.5 Compiler, dass da in der letzten Zeile in der eckigen Klammer eine Konstante zu stehen hat. So sehe ich das auch, oder hat sich in den aktuelleren Standards, wie C99 was daran geändert?

Hans,
gerade etwa ratlos...
--
Man muss nicht alles wissen, aber man sollte wissen, wo es steht. Zum Beispiel hier: Nachdenkseiten oder Infoportal Globalisierung.
 
Profil || Private Message || Suche Download || Zitatantwort || Editieren || Löschen || IP
001
23.05.2011, 00:46 Uhr
0xdeadbeef
Gott
(Operator)


C99 kennt solche Arrays (nennt sie variable-length arrays oder VLAs). Der Code, den du zitierst, ist allerdings C++; darin sind sie nicht enthalten (und auch für C++11 nicht geplant).

Es kann sein, dass bestimmte Compiler dafür Erweiterungen haben (ich kucke in deine Richtung, gcc!), aber standardkonform ist das so nicht.
--
Einfachheit ist Voraussetzung für Zuverlässigkeit.
-- Edsger Wybe Dijkstra
 
Profil || Private Message || Suche Download || Zitatantwort || Editieren || Löschen || IP
002
23.05.2011, 19:24 Uhr
~f.-th.
Gast


Hab mal eben per Suchmaschine versucht Infos zu bekommen, da der
gcc 4.4.? hinweist das das nicht ISO-konform ist, der
digital mars das aber übersetzt.

Ein Treffer der Suche sagt: in C++ sind Container ähnlich realisiert.

Wenn das so ist und, wenn es Ziel von C++0x oder C++11 war, C wieder zur Untermenge von C++ werden zu lassen, warum sieht das so aus als würde es nicht in die neue C++ "Norm" aufgenommen?

MfG f.-th.
 
Profil || Private Message || Suche Download || Zitatantwort || Editieren || Löschen || IP
003
23.05.2011, 20:15 Uhr
0xdeadbeef
Gott
(Operator)


C ist nie ein genaues Subset von C++ gewesen, und es war kein Ziel von C++11, C zur Untermenge von C++ zu machen. Der Grund, dass VLAs keinen Platz in C++ haben, hängt höchstwahrscheinlich mit Template-Metaprogrammierung zusammen, die in den letzten Jahren immer bedeutender geworden ist.

Container in C++ sind nicht ähnlich wie VLAs in C realisiert. Der einzige Container, der überhaupt mit C-Arrays verglichen werden kann, ist std::vector (bzw. in C++11 zusätzlich auch std::array, aber der hat eine feste Länge), und std::vector ist (idR) mit dynamischem Speicher und placement-new realisiert. Man könnte es mit malloc/realloc/free vergleichen, aber auch nur, weil es in C keine Konstruktoren gibt.
--
Einfachheit ist Voraussetzung für Zuverlässigkeit.
-- Edsger Wybe Dijkstra
 
Profil || Private Message || Suche Download || Zitatantwort || Editieren || Löschen || IP
004
23.05.2011, 20:57 Uhr
Hans
Library Walker
(Operator)


Hi,

danke für die Info's. Dann bin ich ja doch nicht so Fehlinformiert, wie befürchtet.
Ansonsten finde ich die Idee der VLAs gar nicht mal schlecht und auch auch schon mal auf die Idee, sowas zu schreiben. Musste dann aber lernen, das es nicht geht. Inzwischen nehme ich an, das man in C++ mit std::vector oder ähnlichen Konstruktionen besser bedient ist.
In C kann man ja mit malloc & Co. sowas hier machen:

C++:
int *a;
a = malloc(...);
a[i] = ...;


Aber vermutlich gehört das in die Kategorie der dreckigen Hacks, die man sich besser gar nicht erst angewöhnen sollte, weil sie in grösseren Projekten zu schwer identifizierbaren Fehlern führen...

Hans
--
Man muss nicht alles wissen, aber man sollte wissen, wo es steht. Zum Beispiel hier: Nachdenkseiten oder Infoportal Globalisierung.

Dieser Post wurde am 23.05.2011 um 21:16 Uhr von Hans editiert.
 
Profil || Private Message || Suche Download || Zitatantwort || Editieren || Löschen || IP
005
23.05.2011, 21:34 Uhr
0xdeadbeef
Gott
(Operator)


Wenn es nur um Arrays geht, sollte man in C99 VLAs benutzen. Unglücklicherweise beherrschen nicht alle gängigen C-Compiler C99 - insbesondere MSVC tanzt hier aus der Reihe. Microsoft hat bislang auch keine Pläne, C99 zu implementieren.

Dynamischer Speicher ist nicht als solches eine Schlechte Sache™, aber man muss vorsichtig sein, dass man keinen Speicher leckt. In C++ gilt RAII, in C muss man halt höllisch aufpassen. Generell sollte man mit dynamischem Speicher aber sparsam umgehen - die Allokation ist wesentlich teurer, als einfach etwas auf den Stack zu klatschen, gleiches gilt für die Deallokation, und in stark nebenläufigen Szenarien kann Heap-Contention leicht zu einem echten Performance-Problem werden.

Gleichwohl: Ein Stack hat begrenzte Größe, und viele Sachverhalte lassen sich davon unabhängig nicht (oder nur sehr umständlich) auf dem Stack erschlagen. Ich denke da in Richtung Laufzeitpolymorphie, Bäume, Graphen etc. Es kann in speziellen Zusammenhängen (beispielsweise stark nebenläufigen) Sinn machen, den Extraaufwand zu betreiben, und ich habe derartige Dinge auch schon getan, aber es ist eine Scheißarbeit, und es will sehr gründlich getestet werden. Wenn man keine guten Gründe dafür hat, sollte man sich das sparen.

Um zu verdeutlichen, worüber ich rede, ein Beispiel für Laufzeitpolymorphie auf dem Stack:

C++:
/////////////////////////////////////////////////////////
#include <iostream>
#include <stdexcept>

#include <boost/aligned_storage.hpp>
#include <boost/mpl/max_element.hpp>
#include <boost/mpl/sizeof.hpp>
#include <boost/mpl/transform_view.hpp>
#include <boost/mpl/vector.hpp>

struct foo_base {
  virtual void foo() const = 0;
  virtual ~foo_base() { }
};

struct foo_1 : foo_base {
  virtual void foo() const { std::cout << "foo_1" << std::endl; }
};

struct foo_2 : foo_base {
  virtual void foo() const { std::cout << "foo_2" << std::endl; }
};

class foo_factory : public foo_base {
public:
  foo_factory(int foo_number) : be_(0) {
    switch(foo_number) {
    case 1:
      new (storage()) foo_1();
      be_ = static_cast<foo_1*>(storage());
      break;
    case 2:
      new (storage()) foo_2();
      be_ = static_cast<foo_1*>(storage());
      break;
    default:
      throw std::invalid_argument("Foo-Typ unbekannt");
    }
  }

  ~foo_factory() {
    be_->~foo_base();
  }

  virtual void foo() const { be_->foo(); }

private:
  typedef boost::mpl::vector<foo_1, foo_2> foo_types_t;
  typedef boost::mpl::max_element<boost::mpl::transform_view<foo_types_t, boost::mpl::sizeof_<boost::mpl::_1> > >::type foo_types_iterator;

  inline void       *storage()       { return static_cast<void       *>(storage_.address()); }
  inline void const *storage() const { return static_cast<void const *>(storage_.address()); }

  boost::aligned_storage<sizeof(boost::mpl::deref<foo_types_iterator::base>::type)> storage_;
  foo_base *be_;
};

int main() {
  foo_factory f1(1);
  foo_factory f2(2);

  f1.foo();
  f2.foo();
}



edit (ao): Tonnen von ///// gelöscht und Layout gerettet
--
Einfachheit ist Voraussetzung für Zuverlässigkeit.
-- Edsger Wybe Dijkstra

Dieser Post wurde am 23.05.2011 um 21:55 Uhr von ao editiert.
 
Profil || Private Message || Suche Download || Zitatantwort || Editieren || Löschen || IP
006
24.05.2011, 08:47 Uhr
~f.-th.
Gast


Wenn die sich in den Normenausschüssen einig wären, sollte die ja die Termine leicht einhalten können
Aber da verstehe ich wahrscheinlich irgend etwas nicht und es geht nicht um die Norm sondern um die Kommunikation

Mir sind noch so Tools bekannt die auf/vor einen C-Compiler gesetzt wurden um C++ Code nach C übersetzen. Zu der Zeit gehe ich also davon aus das C eine Untermenge von C++ war. Gesehen hab ich so was für Mircosoft C-Compiler, als die noch nicht viel von C++ wissen wollten.

In den Normenausschüssen gibt es doch unterschiedliche Interessengruppen mit unterschiedlichen Visionen wo sich z.B. C++ hin entwickeln soll.

MfG f.-th.
 
Profil || Private Message || Suche Download || Zitatantwort || Editieren || Löschen || IP
007
24.05.2011, 13:47 Uhr
0xdeadbeef
Gott
(Operator)


Es gibt auch Compiler, die FORTRAN nach C übersetzen, das macht FORTRAN nicht zu einer Übermenge von C.

Anhang C und D im C++-Standard (Revision von 2003) beschreiben Unterschiede zu ISO-C90. Dazu zählen teilweise sehr einfache und selten benutzte Dinge - etwa ist in C90 (streng genommen)

C++:
a = b //*foo*/ c;


eine Division, in C++ dagegen ist alles nach // ein Kommentar. Ob das allerdings alle C-Compiler richtig machen, wage ich zu bezweifeln. Neue Schlüsselwörter, Zeichen-Literale sind char statt int (in C ist sizeof('x') == sizeof(int)).

C++:
char *p = foo ? "abc" : "def";


ist in C erlaubt, in C++ verboten.

C++:
int i;
int i;


erlaubt in C, verboten in C++.

Dergleichen gibt es noch einige mehr. Die Liste ist nicht überwältigend lang, aber es gibt doch eine Reihe von Unterschieden, die seit Anbeginn von C++ existieren - selbst vor der Standardisierung, obwohl es in dieser Zeit mehr oder weniger Glückssache ist, worauf man sich verlassen kann.
--
Einfachheit ist Voraussetzung für Zuverlässigkeit.
-- Edsger Wybe Dijkstra

Dieser Post wurde am 24.05.2011 um 13:48 Uhr von 0xdeadbeef editiert.
 
Profil || Private Message || Suche Download || Zitatantwort || Editieren || Löschen || IP
Seiten: > 1 <     [ C / C++ (ANSI-Standard) ]  


ThWBoard 2.73 FloSoft-Edition
© by Paul Baecher & Felix Gonschorek (www.thwboard.de)

Anpassungen des Forums
© by Flo-Soft (www.flo-soft.de)

Sie sind Besucher: