Login
Newsletter
Werbung

Thema: Änderung in glibc deckt Fehler in Anwendungen auf

14 Kommentar(e) || Alle anzeigen ||  RSS
Kommentare von Lesern spiegeln nicht unbedingt die Meinung der Redaktion wider.
1
Von Trolly am Fr, 12. November 2010 um 15:29 #

Denn ziemlich viel in C ist "undefined behavior" oder "implementation-defined behavior".

Ach ja? Na, dann fang mal an mit dem Auflisten.
Sämtliches undefiniertes Verhalten, das ich aus C kenne sind Dinge, die ein Programmierer nur aus reiner Dummheit verwenden würden (Division durch 0, etc.).

[
| Versenden | Drucken ]
  • 0
    Von hhb am Fr, 12. November 2010 um 15:46 #

    Na, dann fang mal an mit dem Auflisten.
    Nein, ich werde jetzt sicher nicht den C-Standard vorlesen und Dinge auflisten. Lesen sollte ein Programmierer schon können.

    Aber ich kann aus den >100 Einträgen aus dem C-Standard mal zwei, drei häufige Fälle nennen, die mir zuerst in den Sinn kommen.

    Undefined behavior:
    - Integer overflow
    - fflush() auf Eingabeströme (dieser Fall wird sogar oft genug falsch gelehrt)
    - lesen von nicht-initialisierten Variablen mit "automatic storage". (z.B. int i; i++;)

    Implementation-defined behavior:
    - bitweise Operationen auf vorzeichenbehafteten Ganzzahltypen
    - Casting von Pointer in Integer und zurück
    - alles, was mit #pragma zu tun hat

    [
    | Versenden | Drucken ]
    • 1
      Von Trolly am Fr, 12. November 2010 um 16:04 #

      Toll. Die Verwendung aller undefinierten Verhalten, die du aufgelistet hast, sind reine Dummheit.

      Integer overflow? Tja, da hat wohl jemand keine Ahnung, wie groß die Zahlen in seinem Programm werden können. Wenn es dazu kommt, dann ist schon im Design der Software was grob falsch gelaufen.

      fflush() auf Eingabströme? Ernsthaft? Wo wird sowas denn gelehrt?

      Lesen von nicht-initialisierten Variablen? Es wird sogar schon kompletten Anfängern beigebracht dies nicht zu tun, selbst bei Programmiersprachen bei denen eine automatische Initialisierung vorgesehen ist.

      [
      | Versenden | Drucken ]
      • 0
        Von hhb am Fr, 12. November 2010 um 16:08 #

        Es wird sogar schon kompletten Anfängern beigebracht
        Sag das mal dem OpenSSL Team.

        Ehrlich, mich interessiert nicht die Bohne, ob du dich für den C-Halbgott hälst oder nicht. Fakt bleibt, dass in C "sehr viele" Konstrukte undefiniertes Verhalten haben.

        [
        | Versenden | Drucken ]
        1
        Von phreck am Fr, 12. November 2010 um 16:10 #

        Es ist dumm, sich nicht für dumm oder für unfehlbar zu halten.

        Fehler passieren jedem, und es ist unmöglich, Bugs in einem nicht trivialem Programm auszuschließen.

        [
        | Versenden | Drucken ]
    1
    Von phreck am Fr, 12. November 2010 um 16:03 #

    Und ich finde es dumm, so einen Satz zu posten, ohne auch nur einmal in den Standard geguckt zu haben.

    5.1.1.2, Translation Phases, 4: "If a character sequence that matches the syntax of a universal character name is produced by token concatenation (6.10.3.3), [b]the behavior is undefined[/b]."

    5.2.1, Character Sets, 4: "If any other characters are encountered [...] the [b]behavior is undefined[/b]"

    6.2.2, Linkage of Identifiers, 7: "If, within a translation unit, the same identifier appears with both internal and external
    linkage, [b]the behavior is undefined[/b]."

    6.2.4, Storage durations of objects, 2: "If an object is referred to outside of its
    lifetime, [b]the behavior is undefined[/b]."

    6.2.6.1, General, 5: "If the stored
    value of an object has such a representation and is read by an lvalue expression that does not have character type, [b]the behavior is undefined[/b]. If such a representation is produced
    by a side effect that modifies all or anypart of the object by an lvalue expression that
    does not have character type, the [b]behavior is undefined[/b]."

    6.2.6.2, Integer Types, 4: "If the implementation does not support negative zeros, [b]the behavior[/b] of the &, |, ^, ~, operators with arguments that would produce such a value [b]is undefined[/b]."

    6.2.7, Compatible type and composite type, 2: "All declarations that refer to the same object or function shall have compatible type;
    otherwise, [b]the behavior is undefined[/b]."

    6.3.1.4, Real floating and integer, 1: "If the value of
    the integral part cannot be represented by the integer type, [b]the behavior is undefined[/b]"

    6.3.1.4, Real floating and integer, 2: "If the value being converted is outside the range of
    values that can be represented, [b]the behavior is undefined[/b]."

    6.3.1.5, Real floating types, 2: "If the value being converted is outside the range of
    values that can be represented, [b]the behavior is undefined[/b]."

    6.3.2.1, Lvalues, arrays, and function designators, 1: "An lvalue is an expression with an object type or an incomplete type other than void;
    53)
    if an lvalue does not designate an object when it is evaluated, [b]the behavior is undefined[/b]."

    6.3.2.1, Lvalues, arrays, and function designators, 2: "If the lvalue has an incomplete type and does not have array type, [b]the behavior is
    undefined[/b]."

    6.3.2.1, Lvalues, arrays, and function designators, 2: "If the array object has register storage class, the
    [b]behavior is undefined[/b]."

    6.3.2.3, Pointers, 6: "If the result cannot be represented in the integer type,
    [b]the behavior is undefined[/b]"


    Und alleine bis 7.2 Diagnostics gibt es noch ca. [b]60 weitere undefined behaviors[/b]. Danach wurde mir das Zählen zu mühsam.

    [
    | Versenden | Drucken ]
    • 1
      Von Trolly am Fr, 12. November 2010 um 16:11 #

      Jo, und all das sind Dinge, die eine Sprache nicht definieren kann, weil es dafür keine allgemeingültige Lösung gibt.

      Um mal ein Beispiel rauszusuchen:

      6.3.1.4, Real floating and integer, 1: "If the value of
      the integral part cannot be represented by the integer type, the behavior is undefined"

      Klar könnte die Sprache definieren, dass der Integer dann 0 ist. oder INT_MAX, oder wasauchimmer. In jedem Fall ist das Ergebnis aber nicht das, was ein Entwickler haben möchte. Ganz abgesehen davon, dass er dann sein Programm nicht vernünftig designt hat.

      [
      | Versenden | Drucken ]
      • 1
        Von phreck am Fr, 12. November 2010 um 16:23 #

        Das grenzt langsam an Idiotie, wenn man in Betracht zieht, für wie gut du dich hälst.


        > Jo, und all das sind Dinge, die eine Sprache nicht definieren kann,

        Doch, kann sie. Es kann z.B. definiert sein, dass eine Division durch 0 eine divison_by_zero exception schmeißt. Oder sie könnte errno setzen und das Ergebnis bei 0 belassen.


        > In jedem Fall ist das Ergebnis aber nicht das, was ein Entwickler haben möchte.

        Das spielt auch keine Rolle. Definiertes Verhalten ist definiertes Verhalten, und ich könnte mich bspw. darauf verlassen, dass im Falle eines Overflows das Ergebnis INT_MAX ist. Bei undefiniertem Verhalten kann ich das nicht und ich muss Vorkehrungen treffen, damit dieser Fall nie eintritt.

        Dura Lex sed Lex.

        [
        | Versenden | Drucken ]
        • 1
          Von Trolly am Fr, 12. November 2010 um 16:28 #

          Doch, kann sie. Es kann z.B. definiert sein, dass eine Division durch 0 eine divison_by_zero exception schmeißt. Oder sie könnte errno setzen und das Ergebnis bei 0 belassen.
          C hat weder Exceptions noch ist es eine funktionale Sprache in dem Sinne, als dass eine Division etwas anderes als eine Zahl zurückliefern könnte.

          und ich könnte mich bspw. darauf verlassen, dass im Falle eines Overflows das Ergebnis INT_MAX ist
          Und woher willst du wissen, dass das Ergebnis nicht genau INT_MAX ist und gar kein Überlauf aufgetreten ist? Erkennst du das dann als Fehler?

          [
          | Versenden | Drucken ]
          • 1
            Von phreck am Fr, 12. November 2010 um 16:33 #

            > C hat weder Exceptions
            Das war ein C++-Beispiel. Exception Handling gibt es aber sehr wohl auch in C: http://www.on-time.com/ddj0011.htm .

            > noch ist es eine funktionale Sprache in dem Sinne

            Es ist in keinem Sinne eine funktionale Programmiersprache.

            > als dass eine Division etwas anderes als eine Zahl zurückliefern könnte.

            Was? Undefined behaviour kann heißen, dass das Resultat 0 ist bei Compiler X auf Linux um 12:33 Uhr. Es kann aber auch heißen dass nichts zurückgegeben wird sondern das Programm direkt abstürzt mit einem compiler-spezifischem Returncode.


            > Und woher willst du wissen, dass das Ergebnis nicht genau INT_MAX ist und gar kein Überlauf aufgetreten ist? Erkennst du das dann als Fehler?

            Indem man INT_MAX aus der Ergebnismenge ausschließt. Außerdem habe ich noch die Möglichkeit über errno genannt.

            Bist du so hohl oder ist das Gehabe.

            [
            | Versenden | Drucken ]
        1
        Von phreck am Fr, 12. November 2010 um 16:28 #

        Oh, und der Grund für undefiniertes Verhalten liegt nicht an der Banalität eines Statements, sondern eher u.a. darin, dem Compiler und den Library-Implementor mehr Freiheit beim Optimieren zu geben.

        Bsp.: Dieser Artikel.

        ---

        Du kennst nicht viel außer C, oder? Und das nicht mal gut ...

        [
        | Versenden | Drucken ]
        • 1
          Von Trolly am Fr, 12. November 2010 um 16:37 #

          Oh, und der Grund für undefiniertes Verhalten liegt nicht an der Banalität eines Statements, sondern eher u.a. darin, dem Compiler und den Library-Implementor mehr Freiheit beim Optimieren zu geben.
          Wäre das dann nicht "implementation specific behaviour"?

          Du kennst nicht viel außer C, oder? Und das nicht mal gut ...
          Ad hominem? Das hätte ich jetzt nicht von dir erwartet.

          [
          | Versenden | Drucken ]
          • 1
            Von phreck am Fr, 12. November 2010 um 16:50 #

            > Wäre das dann nicht "implementation specific behaviour"?

            a) Sowohl als auch.
            b) Das ist auch nicht viel besser wenn du portable Programme schreiben möchtest (wobei portabel schon die Kompatibilität deines Programmes zu gcc 4.4 und 4.5 bedeuten kann)

            > Ad hominem? Das hätte ich jetzt nicht von dir erwartet.

            Jemand, der Bugs mit Dummheit begründet, in einem Kontext, welcher den anderen signalisiert, er selbst sei dies nicht, sollte nicht die Wendung ad hominem benutzen.

            [
            | Versenden | Drucken ]
            1
            Von phreck am Fr, 12. November 2010 um 16:54 #

            Sorry, muss mich wirklich mal registrieren, kein edit möglich.


            Ich vermute deshalb, dass du nicht viel außer C kennst, weil es viele, viele Programmiersprachen gibt, die wohl definiert sind, sprich, die komplett ohne undefined behaviour auskommen. Beispiele: Haskell, C#, Java.

            [
            | Versenden | Drucken ]
Pro-Linux
Pro-Linux @Facebook
Neue Nachrichten
Werbung