Unterschied const #define



  • Michael E. schrieb:

    btw: ist es überhaupt erlaubt (bei neueren compilern) bei

    const int a = 557667;
    

    von a die adresse zu bilden. 😕

    Ja, mit einem konstanten Zeiger:

    const int *b = &a;
    

    und warum geht das?

    const int a = 12345;
      const int *c = &a;
      int *p = (int*)c;
    

    gcc 3.3.1, ohne error, ohne warning
    dann kann a ja nicht wirklich const sein



  • Das ist ein C-Cast. Ich find sowieso, dass man die verbieten sollte.

    [EDIT] Hast du auch versucht, den Wert zu ändern?



  • Michael E. schrieb:

    [EDIT] Hast du auch versucht, den Wert zu ändern?

    ja, a ändert sich nicht.
    aber was ist das denn für eine adresse? ich kann was reinschreiben und es auch wieder auslesen. komisch, komisch... 😕 😕 😕



  • Kurz eine Frage.. Ich habe das schon öfters in Quellcodes gesehen, hier im Thread kommts auch vor:

    b = (int)&a;

    Aber was genau steht dann in b? Eine Adresse bestimmt, aber was für eine? Und wozu braucht man sowas?



  • net schrieb:

    Michael E. schrieb:

    [EDIT] Hast du auch versucht, den Wert zu ändern?

    ja, a ändert sich nicht.

    Na also, es ist doch konstant. Was willst du mehr?



  • Michael E. schrieb:

    Na also, es ist doch konstant. Was willst du mehr?

    siehe oben. die adresse ist ja wohl eine andere, sonst würde sich a verändern. aber wo kommt die her?



  • net schrieb:

    nee, das ist was ganz anderes. der string ist deshalb konstant, weil er in einem read-only bereich gespeichert wird (alles was irgendwo gespeichert wird, hat eine adresse). wenn man die zugriffsrechte dieses speicherbereichs ändern würde (falls er ncht im rom ist), könnte man den string durchaus verändern.

    Nein, im Standard steht nichts von Read-Only-Bereichen oder sowas, Du hast keine Garantie dafür, daß etwas funktioniert, wenn Du in text rumpfuschst. Da "könnte man den String durchaus verändern" ist durch nichts abgedeckt.

    aber bei

    #define TEXT "Das ist ein konstanter Text."
    puts(TEXT);
    

    ist es unmöglich den string zur laufzeit zu manipulieren. überall wo TEXT erscheint wird unweigerlich "Das ist ein konstanter Text." eingesetzt. wenn das nicht konstant ist, dann garnix mehr.

    Das hat nichts mit konstant zu tun, sondern damit, daß eine Textersetzung vor dem Compilieren durchgeführt wurde. Streiche den Zusammenhang von define und Konstanten aus deinem Gedächtnis. Überlege dir, wie konstant

    #define KONST rand()
    

    ist.

    btw: ist es überhaupt erlaubt (bei neueren compilern) bei

    const int a = 557667;
    

    von a die adresse zu bilden.

    Ja.

    Brutus schrieb:

    b = (int)&a;

    Aber was genau steht dann in b? Eine Adresse bestimmt, aber was für eine? Und wozu braucht man sowas?

    Nein, da steht keine Adresse, sondern man interpretiert das Bitmuster, was an der Adresse von a steht, jetzt als Integer und speichert dieses Resultat in b. Das ist idR eine Bitschubssache, die exakte Kentnisse des Problems und des Systems erfordert, weil sowas nicht immer funktionieren muß ...



  • Daniel E. schrieb:

    net schrieb:

    nee, das ist was ganz anderes. der string ist deshalb konstant, weil er in einem read-only bereich gespeichert wird (alles was irgendwo gespeichert wird, hat eine adresse). wenn man die zugriffsrechte dieses speicherbereichs ändern würde (falls er ncht im rom ist), könnte man den string durchaus verändern.

    Nein, im Standard steht nichts von Read-Only-Bereichen oder sowas, Du hast keine Garantie dafür, daß etwas funktioniert, wenn Du in text rumpfuschst. Da "könnte man den String durchaus verändern" ist durch nichts abgedeckt.

    ok, ich bezog mich auch nicht auf die standards sondern darauf, was die mir bekannten compiler so machen

    Daniel E. schrieb:

    aber bei

    #define TEXT "Das ist ein konstanter Text."
    puts(TEXT);
    

    ist es unmöglich den string zur laufzeit zu manipulieren. überall wo TEXT erscheint wird unweigerlich "Das ist ein konstanter Text." eingesetzt. wenn das nicht konstant ist, dann garnix mehr.

    Das hat nichts mit konstant zu tun, sondern damit, daß eine Textersetzung vor dem Compilieren durchgeführt wurde.

    es gibt meiner meinung nach nichts konstanteres als eine textersetzung mit hilfe von '#define irgendwas konstanter_ausdruck'. da lässt sich zur laufzeit nichts mehr dran rütteln. das ding hat keine adresse, man kann es durch type-cast nicht variabel machen usw.

    Daniel E. schrieb:

    Überlege dir, wie konstant

    #define KONST rand()
    

    ist.

    sicher, das ist aber was ganz anderes. zwar auch eine textersetzung aber mit #define lässt sich ja mehr machen als nur konstantem zu definieren

    Daniel E. schrieb:

    btw: ist es überhaupt erlaubt (bei neueren compilern) bei

    const int a = 557667;
    

    von a die adresse zu bilden.

    Ja.

    aber was hat es für einen sinn wenn man das 'const' über umwege wegcasten kann?



  • net schrieb:

    nee, das ist was ganz anderes. der string ist deshalb konstant, weil er in einem read-only bereich gespeichert wird (alles was irgendwo gespeichert wird, hat eine adresse).

    Richtig der Text wird wo gespeichert und hat damit eine Adresse. Meinst du das ist bei "konstanten" Ausdrücken im Quellcode nicht der Fall?
    Denn nichts anderes ist dein Makro:

    #define TEXT "Das ist ein konstanter Text."
    puts(TEXT);
    

    ist es unmöglich den string zur laufzeit zu manipulieren. überall wo TEXT erscheint wird unweigerlich "Das ist ein konstanter Text." eingesetzt. wenn das nicht konstant ist, dann garnix mehr.

    Wie du ja schön berschreibst, überall wo TEXT steht, steht dann beim Compilieren "Das ist ein konstanter Text.", also:

    puts("Das ist ein konstanter Text.");
    

    Und was spricht jetzt dagegen, so vorzugehen?

    char * text = TEXT;
    

    Hoppla, da hat ja dein absolut "konstanter" Ausdruck doch wieder eine Adresse.



  • net schrieb:

    aber was hat es für einen sinn wenn man das 'const' über umwege wegcasten kann?

    Was für einen Sinn haben Haustüren, wenn die Einbrecher sie aufbrechen können?

    Const bietet, wie Bjarne Stroustrup sagen würde, Schutz gegen Zufälle aber nicht gegen Betrug.

    Du darfst das const nicht wegcasten, sofern das dahinterliegende Objekt wirklich als const definiert ist.

    void f(const char *p) { *(char*)p = 'a'; }
    void g(void) {
        const char c = 'c';
        char d = 'd';
    
        f(&d); /* legal */
        f(&c); /* undefiniertes Verhalten */
    }
    

Anmelden zum Antworten