Wutz erklärt C++ (Split aus: Frage zu extern)



  • Arcoth schrieb:

    Definiere X stattdessen im Header, ohne extern .

    Quatsch.



  • krümelkacker schrieb:

    Dass const die Bindung verändert ist ein C++ Feature, was Dir im Gegensatz zu C die per Präprocessor-Macro definierten Konstanten ersparen soll.

    Ziemlich gewagte These.



  • lemon03 schrieb:

    Sollte ich nicht-Konstanten dann weiterhin ein extern wie oben voransetzen?

    Du hast extern immer noch prinzipiell nicht verstanden.
    Das Setzen oder Weglassen von "extern" ist grundsätzlich unterschiedlich, d.h. niemals optional so wie du es verstehst.

    Bei "extern" wird nichts definiert, extern dient ausschließlich zur modulübergreifenden Sichtbarkeits-Erweiterung von bereits (irgendwo) definierten (d.h. globalen) Objekten bzw. Funktionen (um mal C-Sprech zu benutzen, denn wie bei allen Basics hat C++ hier nur Anleihen aus C genommen und unter dem Deckmantel "Feature" (s.o.) einiges verschlimmbessert).

    "extern" ist insofern fragil, als der Compiler keinen Fehler erkennen kann, sondern erst der Linker (der die Auflösung zur Definition herstellt).
    Ebenso kannst du bei extern (d.h. einer reinen Deklaration) nichts initialisieren.

    D.h.
    - benutze keine globalen Variablen (egal was irgendwelche Tutorials sagen oder Profiquellcode macht)
    - allenfalls benutze Konstanten global (was natürlich impliziert, dass du das const nicht wegcastest)

    Nachtrag:
    für das in C++ zwangsläufig häufige

    extern "C"
    

    gelten o.g. Aussagen natürlich nur eingeschränkt.


  • Mod

    Wutz schrieb:

    Arcoth schrieb:

    Definiere X stattdessen im Header, ohne extern .

    Quatsch.

    Erklären, aber dalli.

    Wutz schrieb:

    krümelkacker schrieb:

    Dass const die Bindung verändert ist ein C++ Feature, was Dir im Gegensatz zu C die per Präprocessor-Macro definierten Konstanten ersparen soll.

    Ziemlich gewagte These.

    Ich sehe nichts falsches.

    Bei "extern" wird nichts definiert

    Pauschal falsch

    extern dient ausschließlich zur modulübergreifenden Sichtbarkeits-Erweiterung von bereits (irgendwo) definierten (d.h. globalen) Objekten bzw. Funktionen

    Falsch

    Ebenso kannst du bei extern (d.h. einer reinen Deklaration) nichts initialisieren.

    Der Grund, warum die vorletzte Aussage falsch ist.



  • Auch du hast nichts verstanden und weißt nicht wovon du redest.



  • Wutz schrieb:

    krümelkacker schrieb:

    Dass const die Bindung verändert ist ein C++ Feature, was Dir im Gegensatz zu C die per Präprocessor-Macro definierten Konstanten ersparen soll.

    Ziemlich gewagte These.

    Man braucht keine Thesen aufstellen wenn an im Standard nachschlagen kann:

    §3.5 Abs. 3 schrieb:

    A name having namespace scope (3.3.6) has internal linkage if it is the name of
    — a variable, function or function template that is explicitly declared static; or,
    — a variable that is explicitly declared const or constexpr and neither explicitly declared extern nor previously declared to have external linkage; or
    — a data member of an anonymous union.

    Wutz schrieb:

    Auch du hast nichts verstanden und weißt nicht wovon du redest.

    Scheinbar bist du ja der einzige, der C und C++ hier versteht. Kannst aber nur behaupten das wir keine Ahnung haben aber irgendwas begründen kannst du auch nicht. Sind deine ~3500 Beiträge eigentlich alles solche Troll Beiträge? Letztens schon in dem Thread mit einem union Zeug bist du uns allen eine Erklärung für deinen Bullshit Code fällig geblieben.



  • Wutz ist das neue Hacker.



  • Wutz schrieb:

    krümelkacker schrieb:

    Dass const die Bindung verändert ist ein C++ Feature, was Dir im Gegensatz zu C die per Präprocessor-Macro definierten Konstanten ersparen soll.

    Ziemlich gewagte These.

    Das kommt gar nicht von mir. Stroustrup selbst hat in "The Design and Evolution of C++" so etwas in der Richtung gesagt. Ich kann das Buch übrigens empfehlen.



  • Wutz schrieb:

    Bei "extern" wird nichts definiert,

    Das ist so nicht richtig. Im C++ Standard findest Du Beispiele mit extern , die tatsächlich Definitionen sind. extern kann aus einer Definition eine Deklaration machen, muss es aber nicht. Beispiel:

    extern int foo = 9; // dies ist eine Definition
    


  • Was soll dieser Thread darstellen?
    Selbstverarschung?


  • Mod

    hustbaer schrieb:

    Was soll dieser Thread darstellen?
    Selbstverarschung?

    Es ist ein Split. Hab vergessen es im Titel zu erwähnen.



  • OK verstehe 💡 🙂



  • Vielleicht sollte ich kurz erklären, wie ich überhaupt auf extern gekommen bin.

    Bisher hatte ich im Header immer einige Konstanten deklariert, wie zB Breite und Höhe des aktuellen Konsolenfenster. Habe nicht eingesehen, warum ich solche Werte, die sich prinzipbedingt im laufenden Programm gar nicht ändern können, (weshalb sollte sich plötzlich im laufenden Programm die Dimensionen der Konsole ändern?) durch das ganze Programm zu schleppen.

    Andererseits wurde immer von globalen Variablen abgeraten mit einer Vehemenz, wo ich dachte, das schließt dann auch Konstanten ein.

    Beim Lesen meines neulich bekommen 'Der C++ Programmierer' wurde dann in Kapitel 3.3 'modulare Programmgestaltung' static und extern eingeführt.

    Da ich auf globale Konstanten im Header nicht verzichten möchte, dachte ich fahrlässigerweise, mit dem Schlüsselwort extern kann ich den Makel von globalen Variablen irgendwie "übertünchen". In dem kleinen Unterkapitel 'One Definition Rule' wird dann kurz gezeigt, wie das aussehen muss. Deklaration im Header, Definition in der cpp mit der Bemerkung "nur einmal im Programm".

    Da mir das gegenüber dem einfachen const im Header trotzdem nicht richtig klar wurde, habe ich dann dieses Beispiel hier gezeigt, ob das überhaupt sinnvoll ist. Und wie gesagt, ich stehe noch ziemlich in den Grundlagen, weshalb manche Fragen etwas sonderbar erscheinen, weil ich den großen Zusammenhang noch nicht im Blick habe.


  • Mod

    Bisher hatte ich im Header immer einige Konstanten deklariert, wie zB Breite und Höhe des aktuellen Konsolenfenster.

    Was, wenn du plötzlich zwei Konsolenfenster anbieten möchtest? Den gesamten Code umschreiben?

    Andererseits wurde immer von globalen Variablen abgeraten mit einer Vehemenz, wo ich dachte, das schließt dann auch Konstanten ein.

    Nicht alle. Man muss eben ein Verständnis davon haben, was programmunabhängige Konstanten sind (bspw. Pi) und was einer "Instanz" des Programs angeheftet ist (bspw. irgendwelche Dateinamen oder Fensterdimensionen). Letztere sollten wahrscheinlich von der main aus heruntergereicht werden, während es für erstere nur Sinn macht, wenn die Konstante in den gegebenen Funktion nicht um ihrer selbst willen verwendet wird.



  • Was, wenn du plötzlich zwei Konsolenfenster anbieten möchtest? Den gesamten Code umschreiben?

    Ich schätze, das läuft wie using namepace std und std::endl . Anfänglich nimmt man eben das, was einem angeboten wird. Später, wenn man verstanden hat, was da läuft, macht man das anders.

    Im Moment wüsste ich jetzt gar nicht, wie man überhaupt mehrere Konsolenfenster erzeugen kann. Kann also gar nicht passieren. Wenn ich dann soweit wäre, wird sich auch mein Wissen und Stil erweitert haben. Im Moment sehe ich nicht ein, warum ich solche Werte das ganze Programm durch übergeben sollte.

    EDIT: Und falls man doch umschreiben möchte, ist es sicherlich einfacher, einige Werte im Header umzuschreiben, als überall in den Aufrufen.


  • Mod

    Im Moment sehe ich nicht ein, warum ich solche Werte das ganze Programm durch übergeben sollte.

    Weil Erweiterbarkeit/Wiederverwendbarkeit deines Codes davon abhängt. Und das sind essentielle Eigenschaften guten Stils.

    EDIT: Und falls man doch umschreiben möchte, ist es sicherlich einfacher, einige Werte im Header umzuschreiben, als überall in den Aufrufen.

    In den Aufrufen wirst du doch eine Variable angeben, die irgendwo einmal im Programm definiert ist. Bspw. in der main .



  • @lemon03 Wieso musst du in den Aufrufen etwas ändern, wenn sich ein Wert ändert?



  • Stimmt, habt beide recht, der Wert der Variable ändert sich natürlich nicht.

    Aber irgendwie widerstrebt es mir, solch "natürliche" Variablen wie in dem Fall die Dimensionen des Konsolenfensters an Funktionen, wo sie genutzt werden zu übergeben. Es gibt ja schon genug Werte, die übergeben werden müssen.

    Mir fiele nur ein, die Werte dann direkt in den Funktionen zu deklarieren, wo man dann aber bei Änderung wieder mit suchen und ersetzen beschäftigt wäre.



  • lemon03 schrieb:

    Aber irgendwie widerstrebt es mir, solch "natürliche" Variablen wie in dem Fall die Dimensionen des Konsolenfensters an Funktionen, wo sie genutzt werden zu übergeben. Es gibt ja schon genug Werte, die übergeben werden müssen.

    Anstelle von:

    void f(int,int,int,int,int,int,int,int,int)
    

    Kannst Du es doch auch so lösen:

    struct Cfg {
      int a, b, c, d, e, f, g, h, i, j, k, l, m, n;
    }
    
    void f(const Cfg&);
    

    Falls Dich die Anzahl an Übergabeparameter stören sollten.



  • Das wäre in einem anderen Fall bei mir tatsächlich interessant, danke dafür.

    Ansonsten werde ich mal über die ganze Sache weiter nachdenken ...


Log in to reply