MichaelB: Fortsetzung

Beitrag lesen

Allenfalls das besch* Konzept von C macht dies manchmal notwendig (ohne dabei irgendein
Benefit zu liefern).

»»

Das Konzept ist hierbei dasselbe wie bei Pascal. Zeilenweises kompilieren. Wie gesagt, in C
sind es Prototypen und in Pascal waren es forward-Deklarationen. Kein Unterschied.

Das mit dem forward ist in der Tat nicht sehr clever (zum Glück haben das moderne Programmiersprachen überwunden). Ich sage ja auch nicht das ALLES an Pascal besser ist. Manches aber schon.

BTW. ist die Trennung in .c- und .h-Dateien reine Konventions-Sache. Die kannst du auch
nach belieben auflösen.
Das ist allerdings richtig. Nur nützt mir das wenig, wenn ich vorhandenen Code übernehmen
muss. Weil landläufig wird diese Trennung vorgenommen.
Sie ist ja auch durchaus sinnvoll. Das nennt man in der hiesigen Lehrsprache das
'Geheimnisprinzip'.

Nunja. Das Geheimprinzip kommt eher aus der OOP-Ecke. Zumindest wird es dort erst ordentlich umgesetzt.
Wie dem auch sei. Auch dafür brauche ich keine Header-Dateien.

C kennt nicht die häufig benötigten Strings sondern nur nullterminierte Array of Char.
Das war in Pascal übrigens nicht besser. Da war es eine Stufe abstrahierter, aber dafür
konnte ein String maximal 255 Zeichen lang werden.
Stimmt. Das war zumindest unter Turbo Pascal so.
Das war nicht nur unter Turbo Pascal so.

Nullterminierende Speicherbereiche kann man in Pascal genauso nehmen.
Hier hat Pascal eben nur was, was C fehlt. Ist also schwer das als Nachteil für Pascal zu werten. :-)

Das ist fehleranfällig und schon einfache Operationen wie das Feststellen der Länge
eines Strings nötigt mich die Bytes zu zählen
Das war auch in Pascal notwendig. Einziger Unterschied: es musste maximal 255 mal
addiert werden statt, wie in C, maximal unendlich mal.
Falsch. Zumindest die Implementierung in Turbo Pascal war es so, daß die Länge am Anfang
des Strings gespeichert wurde.
Turbo Pascal ist kein Massstab.

Meinens Wissens nach ist es auch unter vielen anderen Pascal-Dialekten so. Bei Turbo Pascal war die Längenangabe eine Byte-Variable. Daher auch nur 255 Zeichen. Manch andere verwenden dafür Integer und dann hat man schon deutlich mehr.

(was auch nicht gerade positiv für die Perforamce ist).
Zähle halt mit.
Brauch ich ja wieder eine extra Variable. Wofür? Wo es mir doch andere Sprachen wesentlich
einfacher machen.
Die machen es genau so: entweder mitzählen oder jedesmal neu zählen. Davon mal ab hält dich
keiner davon ab, einen eigenen String-Baukasten zu schreiben. Das ist ganz einfach. Schau
dir den Source dieses Forums an.

Das mit der Länge war ja nur ein Beispiel. Nullterminierende Zeichenketten haben ja noch andere Nachteile. Beispielsweise Copy&Paste. Was ist wenn ein Paste über die reservierte Länge hinausgeht. Was ist wenn das Ende-null durch irgendwas vorloren geht. Das Konzept ist einfach unsicherer und schwerer zu handhaben.

[... switch ...]
Sorry. Aber das ist ja noch länger. *kopfschüttel*
Die Länge ist unerheblich.

Es ging um Übersichtlichkeit und Lesbarkeit des Programms. Und da spielt die Länge schon eine Rolle.

Das fehlen von Bereichen macht Programme fehleranfällig.
Das ist nun wirklich aus der Luft gegriffen.
Wieso? Ein konkretes Beispiel habe ich gleich mitangegeben:
In Pascal kann ich sagen:
Type jahreszahlen = 1970..2500
In C müsste ich ein int nehmen und müsste sämtliche Bereichsüberprüfungen von Hand machen.
Und wo ist das bitte sehr fehleranfällig?

Man. Du machst es einem aber nicht einfach.
Das zum Beispiel einer Jahreszahl oder auch einer Monatsangabe (das Beispiel ist vielleicht deutlicher) ein Wert zugewiesen werden kann, der logisch gesehen gar nicht gültig ist. So lassen sich Programmfehler leichter finden und das arbeiten mit ungültigen Werten verhindern. In der Datenbankwelt nennt man sowas Constraints. Aber die verwendest Du ja wahrscheinlich auch nicht. Das ist ja nur was für Weicheier.

Und die Realisierung von Aufzählungstypen in C ist ein Witz:
enum wochentag = {Mo, Di, Mi, Do, Fr, Sa, So};
...
wochentag=Di; //funktioniert
wochentag=2;  // funktioniert auch!!!
Nein, funktioniert nicht. Es ist nicht definiert, welche Zahl der Compiler für Di
Doch. Der C-Compiler vergibt implizit Nummern sofern nicht eine eigene angegeben ist.

»»

Das sagte ich dir gerade. Es ist nur nicht definiert, welche Nummer er vergibt. Statt 2
könnte er auch eine beliebige andere Zahl aus dem int-Zahlenraum nehmen. Einzige Bedingung,
die gestellt wird: sie müssen direkt aufeinander folgen.

Verstehst Du denn nicht, worauf ich hinaus will?
Das man überhaupt eine int-Zahl zuweisen kann ist das Problem! Wozu brauche ich ein benutzerdefinierten Typ wenn im Fall des Falles dem Compiler sowieso alles egal ist.

Wenn du C kannst, weisst du auch so, woran du bist. Wenn du es nicht oder nur unzureichend
kannst, ist es unwichtig für dich.
Ich beklage mich auch nur darüber, daß C einem es unnötig(!) schwer macht.

»»

Wenn dir diese Philosophie nicht gefällt, wähle eine andere Sprache. Gibt genug.

Ich werde das Gefühl nicht los, daß bei C gar keine Philosophie dahinter steckt (ausser den Programmierer zu verwirren). Viele Dinge sind einfach nur unlogisch. Sowas wie Durchgängigkeit fehlt mir.
Warum müssen Prozeduren einen Datentyp (void) zurückgeben? Warum kann man bei einer mit void deklarierten Funktion überhaupt ein Rückgabewert angeben ohne das der Compiler meckert?
Eine Zuweisung geschieht so:
a=5;
Aber bei typedef ist es genau andersherum
typedef alt neu
Der Operatorreihenfolge ist ungeschickt gewählt. Beispiel:
int a;
a=10;
--x=(++x)--;
Hier kommt 11 raus und nicht 9 wie man (intuitiv) erwarten würde. Das nötigt einem viele Klammern zu setzen (vorallem bei Vergleichen), was der Übersichtlichkeit nicht gerade zuträglich ist.
Auch die Mehrfachverwendung von Schlüsselwörtern mit jeweils komplett unterschiedlicher Bedeutung macht es einem nicht gerade einfach (beispielsweise: static).
Viele Dinge in C sind nicht geregelt und implementierungsabhängig (Umfang von Datentypen usw).

Als Problematisch sehe ich auch den Präprozessor wenngleich er ein mächtiges Werkzeug sein kann (ich selbst vermisse ihn manchmal bei anderen Sprachen). Neben den vielen Unwegsamkeiten (so werden Typen von Makroargumenten nicht überprüft oder unliebsamen Seiteneffekten) sind Makrolastige Programme auch relativ schwer zu debuggen weil das Kompilat und der Quelltext eben nicht mehr soviel miteinander zu tun haben.
Nungut. Man muss ihn ja nicht verwenden wirst Du jetzt wieder sagen. Oftmals kommt man aber nicht umhin, um andere C Schwächen auszugleichen (beispielsweise wenn man plattformübergreifend programmiert).

Nene, Pascal war in vielerlei Hinsicht nix besser als C, was die Konstruktionen betraf.
Wenn man da ein bisschen über "das Normale"[tm] herausging und es wirklich effektiv nutzen
wollte, stiess man dort an die gleichen Probleme wie in C.
Schon die Strenge Typisierung in Pascal vermeidet viele Probleme (das ist auch der Grund,
warum man das in Java wieder eingeführt hat).
Das ist doch Humbug. Die Typisierung ist in Pascal gleich wie in C. Arbeite ich mit
Pointern, kann ich mich über jede Typisierung hinwegsetzen. Tue ich das nicht, muss ich
mich dran halten. Pascal wie C.

Es gibt den untypisierten Pointer auch in Pascal. Das stimmt. Und damit kann man sich dann über alle Typprüfungen hinwegsetzen.
Aber generell sind Pointer in Pascal typisiert (im Gegensatz zu C).

Zeiger sind immer fehleranfällig. In vielen Fällen wo man in C ein Zeiger benötigt braucht man in Pascal keinen und vermeidet dadurch die Fehlerquelle. Zum Beispiel Strings (statt CharArray) und ein echtes Call-by-Reference.

Was die anderen Datentypen angeht da wird es noch deutlicher. In C kann ich jeden Variablen den Wert einer anderen zuweisen egal welcher Typ es ist. Das geht in Pascal so nicht (wozu auch?). Daraus folgt: Bestimmte Fehler können prinzipbedingt nicht auftreten.

Die weitaus meisten Fehler (und damit Sicherheitslücken) die in Programmen auftreten
liegen nicht nur daran, daß C so verbreitet ist sondern an den teilweise kaputten Konzept.
Belege?

Schau mal in jede x-beliebige Security-Mailingliste. Da wirst Du öfter auf Meldungen treffen wie "Sicherheitsproblem durch BufferOverflow" etc. Ok. BufferOverflows gibt es in Pascal auch. Aber die Konstrukte die dazu führen können werden in Pascal wesentlich weniger benötigt.

Auch in Pascal musste ich, wenn
ich dynamisch grosse Arrays haben wollte, mit Pointern hantieren.
Pointer brauche ich immer, wenn ich mit Arrays dynamischer Größe (also praktisch Listen)
arbeite.
Nein. Siehe PHP, Perl, Ruby, Python, Java, etc, pp.

Auch da wird mit Pointern handtiert, wenngleich es auch gut verborgen wird.
Ich kenne jetzt nur Java genauer. Für die anderen Sprachen kann ich nichts sagen. Übrigens. Das Zeigerkonzept (sofern man das Zeiger nennen kann) bei Java ist vorbildlich und extrem sicher vor Programmierfehlern. Nicht zuletzt wegen der strengen Typisierung (es gibt keine typenlosen Zeiger).

Aber üblicherweise implementiert man sowas einmal (falls nicht sogar schon in einer
Bibliothek vorhanden) und verwendet es dann nur noch.
Dann mach das doch. Weder in C noch in Pascal hält dich etwas davon ab.

Eben.

Ich will es mal so formulieren:
C ist darauf getrimmt, daß man sehr viel im Code selbst optimieren kann und das zu lasten der Übersichtlichkeit und Sicherheit. Das ist aber heutzutage gar nicht mehr notwendig, weil die Compiler sehr viel besser geworden sind.
Für hardwarenahe Programmierung (Treiber/Betriebssyteme usw.) hat C durchaus seine Vorteile. Das will ich gar nicht mal abstreiten. Aber für die meisten anderen Belange gibt es Besseres.

Gruß
   MichaelB

0 111

Welche Programmiersprache ist die richtige?

Jürgen Ulmschneider
  • programmiertechnik
  1. 0
    Die dicke Tina
    1. 0
      wahsaga
      1. 0
        Andavos
    2. 0
      Onkel
      1. 0
        Fabian Transchel
    3. 0
      Atomfried
      1. 0
        Johannes Zeller
  2. 0
    Andavos
  3. 0
    Markus Trusk
    1. 0
      Andavos
      1. 0
        Markus Trusk
    2. 0
      Martin Jung
      1. 0
        MichaelB
        1. 0
          Martin Jung
          1. 0
            MichaelB
            1. 0
              Martin Jung
              1. 0
                MichaelB
                1. 0
                  Martin Jung
                  1. 0
                    MichaelB
    3. 0
      Andreas-Lindig
      1. 0
        MichaelB
  4. 0

    Nimm Java

    MichaelB
    1. 0
      Jürgen ulmschneider
      1. 0
        Fabian Transchel
        1. 0
          Christian Seiler
          1. 0
            Jürgen Ulmschneider
            1. 0
              Christian Seiler
              1. 0
                MichaelB
  5. 0
    Gerrit
    1. 0
      MichaelB
      1. 0
        Christian Seiler
        1. 0
          MichaelB
          1. 0
            Christian Seiler
            1. 0
              Jürgen ulmschneider
              1. 0
                MichaelB
              2. 0
                Ingo Turski
  6. 0
    Danny
    1. 0
      FrankieB
      1. 0
        MichaelB
        1. 0
          FrankieB
  7. 0
    Bio
    1. 0
      MichaelB
      1. 0
        Bio
        1. 0
          MichaelB
    2. 0
      Gerrit
      1. 0
        Gerrit
  8. 0
    Noodles
    1. 0
      MichaelB
      1. 0
        Noodles
        1. 0
          MichaelB
          1. 0
            Christian Kruse
            1. 0
              MichaelB
          2. 0
            GONZO
            1. 0
              MichaelB
    2. 0
      Jürgen Ulmschneider
      1. 0
        MichaelB
  9. 0
    Julian von Mendel
    1. 0
      MichaelB
  10. 0
    Jürgen Ulmschneider
    1. 0
      MichaelB
    2. 0
      Vinzenz
      1. 0
        MichaelB
        1. 0
          Klaus Mock
          1. 0
            MichaelB
          2. 0
            Frank Schönmann
            1. 0
              MichaelB
              1. 0
                Frank Schönmann
                1. 0
                  MichaelB
                  1. 0
                    Christian Seiler
                    1. 0
                      MichaelB
                      1. 0
                        Christian Kruse
                        1. 0
                          MichaelB
                          1. 0
                            Christian Kruse
                            1. 0
                              MichaelB
                              1. 0

                                Fortsetzung

                                MichaelB
                                1. 0
                                  Klaus Mock
                                  1. 0
                                    MichaelB
                  2. 0
                    Christian Kruse
                    1. 0
                      MichaelB
    3. 0
      Kopfwunde
    4. 0
      Eternius
      1. 0
        GONZO
        1. 0
          MichaelB
  11. 0
    Jürgen Ulmschneider
    1. 0
      MichaelB
      1. 0
        Fabian Transchel
        1. 0
          MichaelB
          1. 0
            Fabian Transchel
            1. 0
              MichaelB
      2. 0
        Christian Seiler
        • menschelei
        1. 0
          Fabian Transchel
  12. 0
    nobody
    1. 0
      Fabian Transchel
      1. 0
        MichaelB
        1. 0
          Fabian Transchel
          1. 0
            MichaelB
            1. 0
              Fabian Transchel
              1. 0

                Energien

                MichaelB
                • sonstiges
                1. 0
                  Christian Seiler
                  1. 0
                    Christian Seiler
                    1. 0
                      MichaelB
                  2. 0
                    Fabian Transchel
                    1. 0
                      Christian Seiler
                  3. 0
                    MichaelB
                  4. 0
                    Christian Seiler
                    1. 0
                      Klaus Mock
                      1. 0
                        Fabian Transchel
                    2. 0
                      Fabian Transchel
          2. 0
            Christian Seiler
            1. 0
              Fabian Transchel