Forum: Mikrocontroller und Digitale Elektronik Variablen eindeutig benennen damit der Typ eindeutig ist


von Joern DK7JB .. (moin)


Lesenswert?

Wie benennt ihr eure Variablen eindeutig in der Programmiersprache C 
damit eindeutig ist welcher Typ verwendet worden ist? Gibt es da eine 
bewährte Methode oder erfindet da jeder Programmierer das Rad neu?

von c-hater (Gast)


Lesenswert?

Joern DK7JB .. schrieb:
> Wie benennt ihr eure Variablen eindeutig in der Programmiersprache C
> damit eindeutig ist welcher Typ verwendet worden ist? Gibt es da eine
> bewährte Methode oder erfindet da jeder Programmierer das Rad neu?

Nur Anfänger kommen überhaupt auf die Idee, sich um solchen völlig 
unwichtigen Scheiss irgendwelche Gedanken zu machen. Damit du es 
begreifst: es spielt absolut kein Rolle, welchen Namen ein Symbol trägt. 
Wichtig ist allein, dass sinnvoll dokumentiert ist, was es 
repräsentiert.

Na klar: wenn man kann, wählt man Namen, die die wenigstens die halbe 
Dokumentation darstellen. Der Datentyp muss dabei allerdings nicht 
unbedingt erwähnt werden. Richtige Programiersprachen meckern nämlich 
sowieso, wenn man sich da vergreift...

von Rufus Τ. F. (rufus) Benutzerseite


Lesenswert?

Der Typ ist eindeutig, egal, wie die Variable heißt.

Manche Leute benutzen eine Konvention, daß sie im Variablennamen den Typ 
codieren, am verbreitetsten ist die "ungarische" Notation mit 
vorangestellten Kürzeln wie z.B. einem kleinen "p" zur Kennzeichnung 
eines Pointers, ein "i" für Kennzeichnung eines Ints etc.

"Ungarisch" heißt diese Konvention, weil sie von Charles Simonyi 
entwickelt wurde (der aus Ungarn kommt und eine Zeitlang bei Microsoft 
gearbeitet hat).

https://en.wikipedia.org/wiki/Charles_Simonyi
https://en.wikipedia.org/wiki/Hungarian_notation

Eine weitere Konvention aus ähnlichem Dunstkreis ist "CamelCase", bei 
dem Variablennamen, die aus mehreren Wörtern zusammengesetzt werden, mit 
Großbuchstaben im Wort geschrieben werden - der Gegenentwurf ist die 
Verwendung von Unterstrichen:

MeineVariableIstSchoen
meine_variable_ist_schoen

Ersteres mit der ungarischen Konvention gepaart kann dann so aussehen:
1
pstrMeineVariableIstSchoen = "Bla";
2
dwMeineVariableIstSchoen = 0xFFEEDDCC;
3
iMeineVariableIstSchoen = 6;
4
dblMeineVariableIstSchoen = 12.34E4;
Wie gesagt, das liegt im Auge des Betrachters.


Wirklich wichtig ist es aber, die einmal gefundene Konvention 
konsequent beizubehalten oder wieder abzuschaffen, aber niemals 
mehrere Konventionen, gar konträre, miteinander zu mischen.

von Ben B. (Firma: Funkenflug Industries) (stromkraft)


Lesenswert?

Ja, da halte ich doch gleich mal dagegen, daß ich es sehr praktisch 
finde, wenn ich mich um solchen Mist nur da kümmern muß wo ich es auch 
wirklich brauche.

$x=1234;
$x="Ach nee besser doch nicht.";
$x=(int)$x; wenns denn sein muß.

von kenny (Gast)


Lesenswert?

Rufus Τ. F. schrieb:
> pstrMeineVariableIstSchoen = "Bla";
> dwMeineVariableIstSchoen = 0xFFEEDDCC;
> iMeineVariableIstSchoen = 6;
> dblMeineVariableIstSchoen = 12.34E4;

Schöne Beispiel :)
Meine Erfahrungen:
Falls Konventionen genutzt werden, sind diese meist angelehnt an die 
Ungarische Notation mit individuellen Erweiterungen.

Weiteres Beispiel:
Es wird nicht nur der Typ, sondern auch der Gültigkeitsbereich dem Namen 
voran gestellt:

lokal: blMeineVariableIstSchoen = 6;  // Byte lokal

global:  bgMeineVariableIstSchoen = 6;  // Byte global

main:  bmMeineVariableIstSchoen = 6;  // Byte innerhalb Main

von Blume (Gast)


Lesenswert?

kenny schrieb:
> lokal: blMeineVariableIstSchoen = 6;  // Byte lokal
>
> global:  bgMeineVariableIstSchoen = 6;  // Byte global
>
> main:  bmMeineVariableIstSchoen = 6;  // Byte innerhalb Main

Das ist ja super. Da könnte man ja sogar noch die Zeilennummern mit rein 
kodieren und den Dateinamen. Dann bräuchte man sich um einen sinnvollen 
prägnanten Namen keine Gedanken mehr machen.

von Rufus Τ. F. (rufus) Benutzerseite


Lesenswert?

Ich bin mal einem von Betriebspraktikanten in jahrelanger Arbeit 
"gepflegtem" Projekt begegnet, in dem es allen Ernstes die folgenden 
Variablennamen gab:

a
aa
aaa
aaaa
aaaaa

von nip (Gast)


Lesenswert?

Joern DK7JB .. schrieb:
> Wie benennt ihr eure Variablen eindeutig in der Programmiersprache
> C
> damit eindeutig ist welcher Typ verwendet worden ist? Gibt es da eine
> bewährte Methode oder erfindet da jeder Programmierer das Rad neu?

Das hängt von der im Betrieb eingeführten Konvention ab. Profis 
gestalten ihren Code vor allem inheitlich und dazu gehört eben auch die 
Variablen vernünftig zu benennen. Die ungarische Notation empfinde ich 
als sehr sinnvoll. Man erkennt Code von Anfängern oder Schluderern 
daran, dass die Variablennamen und die gesamte Gestaltung des Codes 
unleserlich und schwer zu verstehen ist. Hier spielen auch Kommentare 
und optische Strukturierung eine Rolle (ist ein anderes Thema, lässt 
sich aber ebenfalls unter dieses Thema subsummieren).

von c-hater (Gast)


Lesenswert?

Rufus Τ. F. schrieb:
> Ich bin mal einem von Betriebspraktikanten in jahrelanger Arbeit
> "gepflegtem" Projekt begegnet, in dem es allen Ernstes die folgenden
> Variablennamen gab:
>
> a
> aa
> aaa
> aaaa
> aaaaa

Selbst das könnte unter gewissen Umständen einen Sinn ergeben. 
Allerdings: Es ist doch sehr stark anzunehmen: Es ergibt keinen.

von Sven B. (scummos)


Lesenswert?

In Projekten an denen ich arbeite ist die einzig übliche Notation 
typischerweise das m_-Präfix vor Membervariablen, um die Namenskollision 
mit einem Getter zu vermeiden. Andere Präfixe werden nicht benutzt, und 
ich halte sie auch nicht für hilfreich.

von El Helicoide (Gast)


Lesenswert?

c-hater schrieb:
> Nur Anfänger kommen überhaupt auf die Idee, sich um solchen völlig
> unwichtigen Scheiss irgendwelche Gedanken zu machen. Damit du es
> begreifst: es spielt absolut kein Rolle, welchen Namen ein Symbol trägt.
> Wichtig ist allein, dass sinnvoll dokumentiert ist, was es
> repräsentiert.

Es spielt also "absolut kein Rolle", welchen Namen ein Symbol trägt. Na 
denn, wenn du das meinst. Bisher war ich der Meinung, dass nur Pfuscher 
eine solche Meinung haben können.

Ich deklariere nur die Grundtypen per Prefix
f für Flag (Bool, Ja/Nein, 1/0)
i für Ganzzahl (int, long int)
j für Fließkoma
c für char (im Sinne eines einzelnen Zeichens)
s für String
p für Pointer

Andere halten sich strikt an die ungarische Konvention.

In Projekten muss man sich an die Projektvorgaben halten. Das sind aber 
auch nicht immer dieselben.

von El Helicoide (Gast)


Lesenswert?

Um Bösartigkeiten in Projekten (ausbleibende Zahlung) präventiv zu 
"beantworten", lassen sich Namen auf das funktionell Notwendige 
reduzieren. O0O0OO00 (Mischung aus 'O's und Nullen), IlIl1lII1, 
a010100001000001, a010100000100001, a001100000100001. Viele Spaß wünscht 
man dem Nachfolger, der das Projekt pflegen muss.

Es ist mir aber noch nie passiert, dass ich sowas tun musste. Allerdings 
sind die Zeiten härter geworden, und extrem assozial. Gell C-Hater, du 
weißt das auch ;)

von Dergute W. (derguteweka)


Lesenswert?

Moin,


Hier gibts neben guten Tipps zu Variablennamen noch mehr:

https://github.com/Droogans/unmaintainable-code

Gruss
WK

von Stefan F. (Gast)


Lesenswert?

Rufus Τ. F. schrieb:
> Ich bin mal einem von Betriebspraktikanten in jahrelanger Arbeit
> "gepflegtem" Projekt begegnet, in dem es allen Ernstes die folgenden
> Variablennamen gab:
>
> a
> aa
> aaa
> aaaa
> aaaaa

Ein Kollege nannte seine Funktionen gerne step1(), step2(), step3() und 
so weiter. Als er dann mal eine Funktion einfügen sollte, nannte er sie 
step2b(). Er war davon überzeugt, dass das viel besser sei, als normale 
sprechende Namen, weil man so ihre Aufruf-Reihenfolge ablesen kann.

Wegen seiner Weigerung, das zu unterlassen, wurde er zum ex-Kollegen.

von Ben B. (Firma: Funkenflug Industries) (stromkraft)


Lesenswert?

> wurde er zum ex-Kollegen
LOL! Das war dann wohl stepX().

von Axel S. (a-za-z0-9)


Lesenswert?

El Helicoide schrieb:
> c-hater schrieb:
>> Nur Anfänger kommen überhaupt auf die Idee, sich um solchen völlig
>> unwichtigen Scheiss irgendwelche Gedanken zu machen. Damit du es
>> begreifst: es spielt absolut kein Rolle, welchen Namen ein Symbol
>> trägt.
>
> Es spielt also "absolut kein Rolle", welchen Namen ein Symbol trägt.

Tja. Ich hätte nie gedacht, daß ich das mal sage, aber wo er Recht hat, 
hat er Recht.

Namen von Symbolen sollten vor allem aussagekräftig für den Menschen 
sein, der den Code lesen und pflegen muß. Der Typ ist dafür in 99.9% der 
Fälle  aber vollkommen irrelevant bzw. wenn erforderlich, von der IDE 
mit nur einem Tastendruck abrufbar ("zeige die Definition des Symbols 
unter der Maus").

Darüber hinaus halte ich es für höchst problematisch, wenn es 
Variablen mit gleichem "Grundnamen", aber verschiedenem Typ gibt. Also 
bspw.
1
pstrMeineVariableIstSchoen = "Bla";
2
dwMeineVariableIstSchoen = 0xFFEEDDCC;
3
iMeineVariableIstSchoen = 6;
4
...

wie weiter oben im Thread gesehen. Es gibt also genau gar keinen 
Grund, den Typ irgendwie in den Variablennamen aufzunehmen. Deswegen 
habe ich mich ungarischer Notation und ähnlichem Unsinn auch immer 
strikt verweigert. Probleme hatte ich damit übrigens noch nie, denn ich 
habe auch noch keinen ernstzunehmenden Programmierer getroffen, der auf 
ungarischer Notation bestanden hätte.

> Bisher war ich der Meinung, dass nur Pfuscher
> eine solche Meinung haben können.

Mit derartigen Ausfälligkeiten diskreditierst du dich nur selber.

von Yalu X. (yalu) (Moderator)


Lesenswert?

Das Thema wurde hier im Forum schon sehr oft diskutiert. Hier sind zwei
Beispiele für recht lange Threads mit entsprechend vielen verschiedenen
Meinungen:

  Beitrag "Notation (Ungarische Notation)"
  Beitrag "Typpräfixe im Programmcode"

Meine Meinung: Die Kodierung des Typs in Variablennamen

- ist unnötig (beim Durchlesen von Programmcode interessiert der
  Variablentyp nur selten und wenn doch, ist er schnell anderweitig
  auffindbar),

- bringt einige Nachteile mit sich (flüssiges Lesen wird erschwert, nach
  einer Änderung des Typs müssen alle Vorkommen der Variable geändert
  werden) und

- eine konsequente Umsetzung ist ohnehin nicht praktikabel (bei
  selbstdefinierten Typen reicht ein Präfix aus 1 oder 2 Zeichen zur
  Typidentifikation nicht aus, und bei Funktionsnamen, wo zum Gesamttyp
  sowohl der Rückgabetyp als auch die Typen sämtlicher Argumente
  gehören, hört der Spaß endgültig auf).

Ganz abgesehen davon entspricht die Microsoftsche Ungarische Notation
nicht den ursprünglichen Ideen ihres Erfinders Simonyi. Zudem hat auch
Microsoft längst den Unsinn darin erkannt und verbietet mittlerweile (in
.NET-Bibliotheken) sogar ihre Nutzung.

von Hans-Georg L. (h-g-l)


Lesenswert?

Rufus Τ. F. schrieb:
> Ich bin mal einem von Betriebspraktikanten in jahrelanger Arbeit
> "gepflegtem" Projekt begegnet, in dem es allen Ernstes die folgenden
> Variablennamen gab:
>
> a
> aa
> aaa
> aaaa
> aaaaa

Vieleicht war das ein skalierbares Programm zum Batterie testen ;-)

von Thomas M. (langhaarrocker)


Lesenswert?

Stefanus F. schrieb:
> Ein Kollege nannte seine Funktionen gerne step1(), step2(), step3() und
> so weiter. Als er dann mal eine Funktion einfügen sollte, nannte er sie
> step2b(). Er war davon überzeugt, dass das viel besser sei, als normale
> sprechende Namen, weil man so ihre Aufruf-Reihenfolge ablesen kann.

Ich finde diese Idee in manchen Kontexten (z.B. Handler in State 
Machines) gar nicht sooo verkehrt - aber unter der Voraussetzung dass 
der Indizierungspräfix den Kontext identifiziert und dass die einzelnen 
Steps auch noch einen semantischen Namensteil haben. Fiktives Beispiel
1
xfer00_Init
2
xfer01_SendRequest
3
xfer03_OnResponse

Ohne die Indizierung der Funktionen wäre sonst aus dem Code nur schwer 
ersichtlich in welcher Reihenfolge sie geplant waren.

Ansonsten halte ich nur in Ausnahmefällen es für sinnvoll übers Knie 
gebrochen den Typen in den Variablennamen hinen zu kodieren. Jede 
moderne IDE zeigt den einem genau so gut per Tooltip o.ä. an. Ungarische 
Notation bringt keinen Nutzwert, erwschwert nur das Lesen. Ausnahme 
wären wenn beispielsweise bei Konvertierungen inhaltlich gleiche Daten 
in unterschiedlichen Formaten vorliegen:
1
char *strAmount;
2
int iAmount;
3
float fAmount;

von Dergute W. (derguteweka)


Lesenswert?

Moin,

Wie waers denn mit: Programmiersprache wechseln?
Es gibt Programmiersprachen, wo man sich ueber Variablennamen keine 
Gedanken machen muss - da heissen die einfach: r0..r31 oder a,x,y oder 
a,f,b,c,d,e,h,l... ;-D

Gruss
WK

von Mach (Gast)


Lesenswert?

Yalu X. schrieb:
> Meine Meinung: Die Kodierung des Typs in Variablennamen
> - ist unnötig (beim Durchlesen von Programmcode interessiert der
>   Variablentyp nur selten und wenn doch, ist er schnell anderweitig
>   auffindbar),
In Pascal stellt man bei Typ- und Klassenbezeichnern gerne ein "T" vorne 
ran, um zu kennzeichnen, dass es keine Variable ist. Bei C++ verwendet 
man da ja gern Groß- und Kleinschreibung, da gefällt mir die 
Präfixvariante deutlich besser.

In den seltenen Fällen wo ich Pointer verwende stelle ich ein "p" vorne 
an, quasi als Warnblinkanlage, dass ich bei dieser Variablen besonders 
aufpassen muss.

von Jürgen W. (Firma: MED-EL GmbH) (wissenwasserj)


Lesenswert?

Bei C-Programmen ist das eigentlich eine unsinnige Sache (wird ja auch 
im entsprechenden Wikipedia-Artikel zur Ungarischen Notation mit einigen 
Zitaten ziemlich zerrissen).

Ich programmiere jedoch viel in Assembler für MSP430 und da hilft mir 
folgende Konvention für Präfixe:

          signed  uns.  Bedeutung
------------------------------------------------------
 8 bit     b       c    "Byte" bzw. "Character"
16 bit     s       w    "Short" bzw. "Word"
32 bit     i       q    "Integer" bzw. "Quad Byte"
64 bit     l       o    "Long long" bzw. "Octo Byte"


"q" für "Quad Word" statt "dw", damit ich das Präfix auf 1 Zeichen 
limitieren kann, dasselbe bei 64 bit. Ist es ein Array, dann wird "a" 
davorgesetzt, bei Zeigern "p"; ergibt dann z.B. "ac" für einen String 
oder "pas" als Zeiger auf ein Array von signed 16-bit-Werten.


Weiters sind die Funktionen in entsprechenden Modulen untergebracht, die 
typischerweise mit 3 bis max. 5 Zeichen abgekürzt werden, gefolgt von 
einem Unterstrich und dem eigentlichen Variablennamen, also z.B.
"wPwr_BatVlt" oder "wPwr_UsbVlt" (unsigned 16 bit-Wert im Power-Modul, 
enthält Batterie/USB-Spannungswert) oder "sPwr_SysTmp" (signed 16 bit 
Systemtemperatur).

: Bearbeitet durch User
von Jürgen (Gast)


Lesenswert?

Dergute W. schrieb:
> Es gibt Programmiersprachen, wo man sich ueber Variablennamen keine
> Gedanken machen muss - da heissen die einfach: r0..r31 oder a,x,y oder
> a,f,b,c,d,e,h,l... ;-D

Assembler ist keine Programmiersprache.

von Stefan F. (Gast)


Lesenswert?

Jürgen schrieb:
> Assembler ist keine Programmiersprache.

Oha, ich weiß jetzt schon, wer sich gleich dazu melden wird.

von M. Н. (Gast)


Lesenswert?

Ich musste auch schon an Code arbeiten, der einen solchen Coding Style 
hatte:

Präfixe
-------
g: global
a: array
st: struct

Da gab es dann ein globales array aus structs, das dann 
"gastReceivedMessages" hieß.

Meine Meinung: Absoluter Murks. Nie den typen in den Namen schreiben.
Wenn du nicht weißt, was eine Variable ist, solltest du dir überlegen, 
ob du da überhaupt rumcoden solltest.

Die Lesbarkeit von Code hat absoluten Vorrang. Code wird mal grob 
geschätzt zu über 80% gelesen und zu 20% geschrieben. Und eine solchen 
Variablenbenamung ist nicht leserlich.

Auch der übermäßige Gebrauch von typedefs ist eine Katastrophe. Die 
einzigen Dinge, die sinnvoll sind, sind uintX_t und solche Sachen. Das 
ist wenigstens halbwegs transparent. Aber eine struct würde ich nur 
typedef-en, wenn alle Zugriffe darauf komplett über Funktionen 
abstrahiert sind. So wie zum Beispiel der FILE Typ aus stdio.h. Darauf 
wird nur mit fopen() etc. zugegriffen.

Aus diesem Grund ist IMHO C++ schon inhärent kaputt, weil die 
Deklaration einer struct von Haus auch ein typedef auf denselben Namen 
verursacht.

von Dr. Sommer (Gast)


Lesenswert?

M. H. schrieb:
> Auch der übermäßige Gebrauch von typedefs ist eine Katastrophe.

Erlaubt aber später, den darunterliegenden Typ abzuändern. Klassisches 
Beispiel ist "time_t" - das kann man auf 64bit abändern um Zeiten nach 
2038 abbilden zu können. Gleiches gilt für mode_t, off_t usw. Das hilft 
auch bei der Selbst-Dokumentation des Codes: Eine Funktion "writefile 
(int, unsigned int, unsigned int)" ist nicht so durchsichtig. Mit 
Parametertypen "FILE*, mode_t, off_t" kann man schon erraten worum es 
geht.
C++ Metaprogrammierung wäre ohne typedef gar nicht erst möglich. Da wird 
das intensiv genutzt.

von Dr. Sommer (Gast)


Lesenswert?

M. H. schrieb:
> Aus diesem Grund ist IMHO C++ schon inhärent kaputt, weil die
> Deklaration einer struct von Haus auch ein typedef auf denselben Namen
> verursacht.

Es wird kein typedef (Alias) definiert. C++ hat überhaupt keine structs, 
"struct" definiert Klassen, und die kann man direkt nutzen, ohne 
"struct" oder "class" davor. Es ist übrigens Absicht, dass man einem 
Typ nicht direkt ansieht, ob er jetzt ein Klasse, enum oder Alias ist - 
das ist ein Abstraktionsmechanismus. Alle Typen werden so einheitlich 
wie möglich behandelt.

von M. Н. (Gast)


Lesenswert?

Dr. Sommer schrieb:
> Es wird kein typedef (Alias) definiert. C++ hat überhaupt keine structs

Na klar hat C++ structs:
http://www.cplusplus.com/doc/tutorial/structures/

Und in dem Beispiel dort sieht man auch gleich das von mir angesprochene 
Typedef verhalten. Hat man eine Struktur namens "foo", kann man sie 
entweder mit struct foo bar; instantiieren oder mit foo bar;.

von Dr. Sommer (Gast)


Lesenswert?

M. H. schrieb:
> Na klar hat C++ structs:
> http://www.cplusplus.com/doc/tutorial/structures/

cplusplus.com ist keine Referenz. Da steht viel Unsinn. C++ hat keine 
Structs, nur Klassen. Das Schlüsselwort "struct" definiert eine 
Klasse, in der per default alles "public" ist. Siehe z.B.:

http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2017/n4713.pdf
S. 238:
> Members of a class defined with the keyword class are private by default.
> Members of a class (!) defined with the keywords struct (!) or union
> are public by default.

Und S. 211:
class-key: class struct union

https://stackoverflow.com/a/34108140
> In fact, C++ has not had structs since 1985. It only has classes.

Und wie gesagt wird kein Alias definiert. Eine Klasse ist direkt ohne 
"struct" oder "class" davor zugänglich. Es wird einfach nicht gebraucht.
1
struct A { int x; };
ist in C++ das gleiche wie
1
class A {
2
  public:
3
    int x;
4
};
Und Klassen sind nun einmal direkt zugänglich, wie eben hier per "A"; 
"class A" ist redundant (und hässlich).

Code, welcher einen Typ nutzt, soll unabhängig davon sein, ob das jetzt 
eine Klasse, enum oder built-in Typ ist. Wenn ich immer "enum Mode m" 
schreibe, kann ich aus "Mode" keine Klasse mehr machen, wenn das nötig 
werden sollte. Wenn ich nur "Mode m" schreibe, geht das.

von Thomas M. (langhaarrocker)


Lesenswert?

Dr. Sommer schrieb:
> C++ hat /keine/
> Structs, nur Klassen. Das Schlüsselwort "struct" definiert eine
> Klasse, in der per default alles "public" ist.

Genau das ist der Unterschied zwischen struct und class: die 
Sichtbarkeit der Member, wenn sie nicht explizit angegeben wird. Und 
weil es einen Unterschied gibt, gibt es eben sehr wohl beides in C++. 
struct und class sind nicht eben nicht ganz synonym.

von Dr. Sommer (Gast)


Lesenswert?

Thomas M. schrieb:
> Und
> weil es einen Unterschied gibt, gibt es eben sehr wohl beides in C++.

Wenn aber "struct" eine Klasse definiert (siehe das Zitat), wie 
definiert man dann structs?

von A. S. (Gast)


Lesenswert?

c-hater schrieb:
> Damit du es
> begreifst: es spielt absolut kein Rolle, welchen Namen ein Symbol trägt.
> Wichtig ist allein, dass sinnvoll dokumentiert ist, was es
> repräsentiert.

Das erklärt vielleicht Deine mir unbegreifliche Abneigung von C 
gegenüber Assembler. Und es ist einfach falsch.

Eine sinnvolle, intuitive bzw. den Projekt/Firmen-Gepflogenheiten 
entsprechende Benamung ist weit hilfreicher als eine Dokumentation.

Neben den zu vernachlässigenden Schlüsselworten in C (und nur um C 
geht's in diesem Thread), erschaffen die gewählten Namen eines Projekts 
(oder einer Codebasis) ein sprachliches Universum, dessen 
Verständlichkeit / Nutzbarkeit mit den Benennungen steht und fällt.

Jeder Mensch ist sehr erfahren in natürlicher Sprache. Und genauso wie 
Wortneuschöpfungen dort gewissen intuitiven Regeln unterliegen, sollten 
sich diese auch in Projekten/Firmen entwickeln. Wenn es ein Verb 
"kongen" gibt, dann gibt es naheliegende Assoziationen mit "Konger", 
"gekongelt" oder "KongTreff". Weil man Konventionen folgt. Und je besser 
man das tut, umso lesbarer wird Prosa. Das gleich gilt für Quelltexte.

Was der Mensch allerdings weniger kann, ist Muster in Buchstaben oder 
Ziffern-Kombinationen zu "lesen". Präfixe a la pcav für pointer auf char 
Array volatile oder so sind oft ärgerlich.  Genauso wie Lange 
"Selbsterklärende" Namen. Wenn jemand Annegret Kramp Karrenbauer heißt, 
ist AKK das kleinere Übel. Und auch ein 
DonauDampschiffahrtsFregattenVizeKapitän wird, wenn man das öfter 
auftaucht eine glücklichere Bezeichnung finden.

von Rolf M. (rmagnus)


Lesenswert?

Thomas M. schrieb:
> Dr. Sommer schrieb:
>> C++ hat /keine/
>> Structs, nur Klassen. Das Schlüsselwort "struct" definiert eine
>> Klasse, in der per default alles "public" ist.
>
> Genau das ist der Unterschied zwischen struct und class: die
> Sichtbarkeit der Member, wenn sie nicht explizit angegeben wird.
> Und weil es einen Unterschied gibt, gibt es eben sehr wohl beides in C++.

Es gibt beide Schlüsselwörter, aber das dahinterstehende Konstrukt ist 
das selbe. Ich kann von einer Klasse ableiten, ihr Memberfunktionen 
(auch virtuelle) geben, Elemente private machen u.s.w., und das ist 
völlig unabhängig davon, ob ich es mit dem Schlüsselwort "class" oder 
dem Schlüsselwort "struct" definiert habe. Mit "struct" definiert man in 
C++ also nicht das, was in C eine struct wäre, sondern eine Klasse, mit 
allen Features, die es für Klassen in C++ gibt.

von Thomas M. (langhaarrocker)


Lesenswert?

Rolf M. schrieb:
> Es gibt beide Schlüsselwörter, aber das dahinterstehende Konstrukt ist
> das selbe.

Ja, das geht sogar soweit:
1
struct my_struct {
2
  int dummy;
3
}
4
5
void foo(){
6
  struct my_struct thing1;
7
  class my_struct *thing2;
8
9
  thing2 = &thing1; // Compiler meckert nicht
10
}

von Rufus Τ. F. (rufus) Benutzerseite


Lesenswert?

1
void foo(){
2
  struct my_struct thing1;
3
  class my_struct *thing2;
4
5
  thing2 = &thing1; // Compiler meckert nicht
6
}

Die Schlüsselworte "struct" und "class" sind hier überflüssig, der Typ 
heißt einfach nur "my_struct".

Direkt austauschbar sind struct und class nicht; der Unterschied ist die 
standardmäßige Zuordnung zu public bzw. private.

von a_zip (Gast)


Lesenswert?

Nachdem ich mich schweren Herzens von meinem VB6 (Visual Basic) 
verabschiedet habe, habe ich mich für Python unter Ubuntu entschieden. 
Trotz rudimentärer Kenntnisse in C, denn in Py definierst du eine 
Variable und der wird ein "passender" Typ zugeordnet. Wenn man die 
Variable explizit typisiert, dann steht es ja da und muß nicht noch im 
Namen erscheinen. Das scheint mir in C doch ähnlich und deshalb macht 
sich der TO wohl unnötige Sorgen...und wenn ich den Typ wissen will, 
dann schau ich in der IDE im Quellcode nach und weiß ihn sofort. Wenn 
ich ein fremdes Skript verstehen will, dann ist mir der Typ der Variable 
doch erst mal egal. Erst wenn ich bei der Ausführung auf Probleme 
stosse, dann wird mich vielleicht auch der Typ interessieren. Und dann 
gibt der Compiler in der Regel die entsprechenden Hinweise! Z.B. 
"Funktion in Zeile xyz erwartet ein Array" oder "erwartet 3 Argumente, 
hat 2". Das alles kann man durch eine entsprechende Benennung doch nicht 
verhindern. Deshalb wähle ich meine Bezeichnungen immer nach der 
Funktion. Also test_dat_in oder norm-matrix....
Gruß Rainer

von Stefan F. (Gast)


Lesenswert?

Ich bin erstaunt, dass so viele Leute die Präfixe mögen.

Aber egal, Hauptsache man macht es innerhalb eines Projektes konsistent.

von Rolf M. (rmagnus)


Lesenswert?

Rufus Τ. F. schrieb:
> Direkt austauschbar sind struct und class nicht; der Unterschied ist die
> standardmäßige Zuordnung zu public bzw. private.

Und dass man "class" bei Templates für Typ-Parameter verwenden kann, 
struct nicht.

a_zip schrieb:
> Trotz rudimentärer Kenntnisse in C, denn in Py definierst du eine
> Variable und der wird ein "passender" Typ zugeordnet.

In Python definiert man Variablen nicht. Man weist einfach was zu, und 
wenn sie noch nicht existiert, wird sie dann erzeugt. Und sie bekommt 
dann einfach den Typ, den die rechte Seite der Zuweisung hatte. Und bei 
der nächsten Zuweisung wieder. Nachteil ist, dass die Variable munter 
ihren Typ wechseln kann, ohne dass das an der Stelle auffält. Ein Fehler 
bei falschem Typ kommt dann erst später irgendwo tief in einem 
Funktionsaufruf. Und bei einem Tippfehler beim Variablennamen hat man 
schnell mal stillschweigend eine neue Variable angelegt, statt die schon 
existierende zu überschreiben. Das kann einen bei der Fehlersuche auch 
in den Wahnsinn treiben.

: Bearbeitet durch User
von Jobst Q. (joquis)


Lesenswert?

Präfixe für Typen finde ich meist überflüssig. Wichtig ist mir 
allerdings, schon im Namen zwischen lokalen und globalen Variablen zu 
unterscheiden.

Lokale Variablen fangen bei mir mit Kleinbuchstaben an, globale mit 
Großbuchstaben. Dasselbe bei Funktionsnamen. Funktionen, die nur mit 
lokalen Variablen arbeiten, fangen klein an. Funktionen, die auf globale 
Variablen zugreifen, bekommen einen Namen, der mit Großbuchstaben 
anfängt. Ausnahme ist nur 'main', da er von außen vorgegeben ist.

Die Länge der Variablen hängt davon ab, wie speziell die Aufgabe der 
Variablen ist, globale Variablen sind da naturgemäß länger.

Ich benutze auch einfache Buchstaben als lokale Variablen, die aber 
immer dieselben Aufgaben und denselben Typ haben, egal in welcher 
Funktion. Meist sind es diejenigen, die Kernighan&Ritchie schon in ihren 
Beispielfunktionen verwendet haben.

So ist 'i' immer die Indexvariable für einfache for-Schleifen und int. 
Stringanalyse wird mit 's' gemacht, ein Lesezeiger (const char *). 
Brauche ich mehrere Variablen dieser Art, fangen sie ebenfalls mit 's' 
an, also s1,s2 ... oder zB sr für Reststring. Das Schreiben von Strings 
geschieht entsprechend mit 't' (für target) als Schreibzeiger (char *).

von Dr. Sommer (Gast)


Lesenswert?

Jobst Q. schrieb:
> globale mit
> Großbuchstaben.

Jobst Q. schrieb:
> Funktionen, die auf globale
> Variablen zugreifen, bekommen einen Namen, der mit Großbuchstaben
> anfängt.

Und indem man globale Variablen ganz vermeidet spart man sich auch diese 
Komplexität.

von A. S. (Gast)


Lesenswert?

Dr. Sommer schrieb:
> Und indem man globale Variablen ganz vermeidet spart man sich auch diese
> Komplexität.

Popcorn

von uC-Bastler (Gast)


Lesenswert?

Dr. Sommer schrieb:
> Und indem man globale Variablen ganz vermeidet spart man sich auch diese
> Komplexität.

können Interrupt-Routinen dann überhaupt noch etwas sinnvolles tun?

von Dr. Sommer (Gast)


Lesenswert?

uC-Bastler schrieb:
> können Interrupt-Routinen dann überhaupt noch etwas sinnvolles tun?

ISRs sind eine Ausnahme... Man baut sich 1 globale Variable mit den 
relevanten Daten, auf die in der ISR 1x und ggf. in der main() 1x 
zugegriffen wird. Einen Zeiger/Referenz darauf übergibt man an alle 
Funktionen die es brauchen. So wird die globale Variable zentral genutzt 
und für diese 2 Funktionen braucht man dann auch keine spezielle 
Namenskonvention.

von Rainer V. (a_zip)


Lesenswert?

Rolf M. schrieb:
> In Python definiert man Variablen nicht. Man weist einfach was zu, und
> wenn sie noch nicht existiert, wird sie dann erzeugt

Ja, sorry, habe ich auch so gemeint...Katzenklappe = 3...
Gruß Rainer

von Sven B. (scummos)


Lesenswert?

Rolf M. schrieb:
> In Python definiert man Variablen nicht. Man weist einfach was zu, und
> wenn sie noch nicht existiert, wird sie dann erzeugt. Und sie bekommt
> dann einfach den Typ, den die rechte Seite der Zuweisung hatte. Und bei
> der nächsten Zuweisung wieder. Nachteil ist, dass die Variable munter
> ihren Typ wechseln kann, ohne dass das an der Stelle auffält. Ein Fehler
> bei falschem Typ kommt dann erst später irgendwo tief in einem
> Funktionsaufruf. Und bei einem Tippfehler beim Variablennamen hat man
> schnell mal stillschweigend eine neue Variable angelegt, statt die schon
> existierende zu überschreiben. Das kann einen bei der Fehlersuche auch
> in den Wahnsinn treiben.

Ach naja, so einen Fehler kann man sich in C++ mit dem Shadowing auch 
leicht bauen ...

von Rainer V. (a_zip)


Lesenswert?

Sven B. schrieb:
> Rolf M. schrieb:
...

Ja, aber...und wenn es hier vielleicht nicht hingehört...du arbeitest 
fast immer mit Klassen, deren Methoden und Funktionen im Modul definiert 
sind. Damit ist schon eine große Eindeutigkeit gegeben. Weiß nicht, ob 
das in C genau so ist, aber in einer OO-orientierten Sprache sollte das 
relativ eindeutig u n d lesbar sein oder?
Gruß Rainer

von Carl D. (jcw2)


Lesenswert?

Sven B. schrieb:
> Ach naja, so einen Fehler kann man sich in C++ mit dem Shadowing auch
> leicht bauen ...

Man muß aber die dann folgende Compiler-Warnung nicht ignorieren.

von Ratgeber (Gast)


Lesenswert?

A. S. schrieb:

> Popcorn

"Popcorn" bietet sich als Name für ein mehrdimensionales Feld an. Ist 
aber auf Grund der Kleinheit der einzelnen Elemente nur für Bits 
geeignet. Für längere Strukturen bietet sich "Rohr" oder "Kastenprofil" 
als Bezeichnung an.

"Sabbel" dann als Bezeichnung für einen String mit > 100 Zeichen.

von Jobst Q. (joquis)


Lesenswert?

Dr. Sommer schrieb:
> Und indem man globale Variablen ganz vermeidet spart man sich auch diese
> Komplexität.

Und schafft sich durch die Vermeidung neue Komplexitäten. Mir sind 
globale Variablen lieber als lange Parameterlisten, in denen dann oft 
immer wieder dasselbe steht. Da finde ich globale, also 
funktionsübergreifende Variablen für das, was man immer wieder braucht, 
deutlich praktischer. Je kürzer die Parameterlisten, um so weniger muss 
man auf die Reihenfolge achten.

Manche Daten braucht man dauerhaft. Da finde ich es weder sinnvoll, die 
alle in main als lokale Variablen zu deklarieren, noch sie mit static 
auf die Funktionen zu verteilen.

von Dr. Sommer (Gast)


Lesenswert?

Jobst Q. schrieb:
> Mir sind
> globale Variablen lieber als lange Parameterlisten, in denen dann oft
> immer wieder dasselbe steht.

Daher kapselt man zusammen gehörende Daten in Klassen. Die meisten 
Funktionen kommen dann mit 1-3 Parametern aus, aus denen sich die 
Funktion dann die entsprechenden Daten holt.
In Java funktioniert es doch auch - da gibt es überhaupt keine 
globalen Variablen.

von Jobst Q. (joquis)


Lesenswert?

Dr. Sommer schrieb:
> Daher kapselt man zusammen gehörende Daten in Klassen.

Aber innerhalb einer Klasse sind die meisten Variablen eben nicht lokal. 
Bei einer Quelldatei pro Klasse sind die Membervariablen im gesamten 
Quelltext verfügbar und damit global.

von A. S. (Gast)


Lesenswert?

Dr. Sommer schrieb:
> In Java funktioniert es doch auch - da gibt es überhaupt keine globalen
> Variablen.

Deshalb ist Java auch der Renner bei uC.

Oh, vertan: doch wohl eher bei Anwendungen ohne konkrete reale Objekte.

Niemand sollte die Sichtbarkeit höher wählen als nötig. Und Daten 
sollten gekapselt und strukturiert sein. Soweit Zustimmung.

Aber ob ich ein globales struct mit 100 Elementen habe, einen globalen 
Zeiger darauf oder eine globale Funktion die den Zeiger zurückgibt, ist 
oft gleichwertig.

von Dr. Sommer (Gast)


Lesenswert?

Jobst Q. schrieb:
> Aber innerhalb einer Klasse sind die meisten Variablen eben nicht lokal.

Richtig.

Jobst Q. schrieb:
> Bei einer Quelldatei pro Klasse sind die Membervariablen im gesamten
> Quelltext verfügbar und damit global.

Nur in den Funktionen eben dieser Klasse. Sie sind eben nicht global. 
Dass Member-Funktionen einer Klasse auf die Member-Variablen zugreifen 
ist klar - sonst wären es keine Member-Funktionen - womit sich die 
Konvention mit der Großschreibung dann erledigt.

Eine Konvention die ggf. noch sinnvoll sein kann ist "i" für Index und 
"n" für Number (Anzahl). Ein Code kann dann so aussehen:
1
for (std::size_t iBlock = 0; iBlock < nBlocks; ++iBlock) {...
Man muss halt nur wissen dass "i" hier nicht für Integer steht.

A. S. schrieb:
> Aber ob ich ein globales struct mit 100 Elementen habe, einen globalen
> Zeiger darauf oder eine globale Funktion die den Zeiger zurückgibt, ist
> oft gleichwertig.

Deswegen macht man das eben nicht global. Bei vernünftiger 
objektorientierter Programmierung übergibt man jeder Funktion was sie 
gerade braucht, inklusive dem impliziten this-Pointer. So wird der Code 
übersichtlich und man spart sich undurchsichtige Verpflechtungen über 
globale Variablen. Das ist auch auf eingebetteten Systemen sehr gut 
machbar - habe ich schon oft.

A. S. schrieb:
> Deshalb ist Java auch der Renner bei uC.
Man kann sich die guten Dinge da abschauen. Und ja, es gibt Java für uC.

von Egon D. (Gast)


Lesenswert?

Jobst Q. schrieb:

> Aber innerhalb einer Klasse sind die meisten Variablen
> eben nicht lokal. Bei einer Quelldatei pro Klasse sind
> die Membervariablen im gesamten Quelltext verfügbar
> und damit global.

Kuriose Sprachlogik.

Alles, was nicht auf Deinen Garten beschränkt ist, ist
global?

Ich würde eher verschiedene Grade von Lokalität unterscheiden
(blocklokal, funktionslokal, modullokal,...).

von Jobst Q. (joquis)


Lesenswert?

Dr. Sommer schrieb:
> Jobst Q. schrieb:
>> Bei einer Quelldatei pro Klasse sind die Membervariablen im gesamten
>> Quelltext verfügbar und damit global.
>
> Nur in den Funktionen eben dieser Klasse. Sie sind eben nicht global.
> Dass Member-Funktionen einer Klasse auf die Member-Variablen zugreifen
> ist klar - sonst wären es keine Member-Funktionen - womit sich die
> Konvention mit der Großschreibung dann erledigt.

Es geht mir um die wesentliche Unterscheidung zwischen lokalen und 
nicht-lokalen Variablen. Die nicht-lokalen Variablen fangen bei mir mit 
Großbuchstaben an. Wenn dich daran die Bezeichnung global stört, ersetz 
es einfach durch nicht-lokal.

von Rainer V. (a_zip)


Lesenswert?

Jobst Q. schrieb:
> Es geht mir um die wesentliche Unterscheidung zwischen lokalen und
> nicht-lokalen Variablen.

Diese Unterscheidung macht doch nur Sinn in einer Nicht-OO-Umgebung! 
Wenn du z.B. die Parameter eines Fensters in eine Klassendefinition 
packst, dann kannst du überall mit Class.Param drauf zugreifen und in 
der Klasse hast du möglicherweise den Typ expliziert definiert...das ist 
aber alles andere, als in einem "normalen" Progrämmchen Variablen als 
global zu definieren!
Gruß Rainer

von Wilhelm M. (wimalopaan)


Lesenswert?

Joern DK7JB .. schrieb:
> Wie benennt ihr eure Variablen eindeutig in der Programmiersprache C
> damit eindeutig ist welcher Typ verwendet worden ist? Gibt es da eine
> bewährte Methode oder erfindet da jeder Programmierer das Rad neu?

Benutzt Ihr keine IDE? Meine Bezeichner sind unterschiedlich bunt, und 
wenn ich darüber "hover", bekomme ich den Typ auch angezeigt ...

von Stefan F. (Gast)


Lesenswert?

Wilhelm M. schrieb:
> Benutzt Ihr keine IDE? Meine Bezeichner sind unterschiedlich bunt, und
> wenn ich darüber "hover", bekomme ich den Typ auch angezeigt ...

Eben, deswegen ist das Thema weniger wichtig, als der Geschmack der 
Tomaten, die ich gleich essen werde.

von Peter S. (Gast)


Lesenswert?

Hauptsache es herrscht bei allen beteiligten mindestens projektweit 
Konsistenz. Besonders leserlich finde ich es aber nicht, wenn man die 
Namen mit Prä- und Suffixen zumüllt.
Ich denke, da überwiegen die Nachteile eindeutig die Vorteile, zumal 
(fast) jede Popel-IDE den Typ anzeigen kann.

von Wilhelm M. (wimalopaan)


Lesenswert?

Leute, diese ganze Diskussion stammt doch aus einer Zeit, als man noch 
mit Zeileneditoren wie ed arbeitete.

von Kaj (Gast)


Lesenswert?

A. S. schrieb:
> Deshalb ist Java auch der Renner bei uC.
>
> Oh, vertan
Mag dir nicht klar sein, aber Java laeuft auf SIM-Karten und anderen 
Smart-Cards.

von Stefan F. (Gast)


Lesenswert?

Wilhelm M. schrieb:
> Leute, diese ganze Diskussion stammt doch aus einer Zeit, als man
> noch mit Zeileneditoren wie ed arbeitete.

Oder Arduino IDE. Die war damals um 2020 noch sehr aktuell und weit 
verbreitet.

von Wilhelm M. (wimalopaan)


Lesenswert?

Stefanus F. schrieb:
> Wilhelm M. schrieb:
>> Leute, diese ganze Diskussion stammt doch aus einer Zeit, als man
>> noch mit Zeileneditoren wie ed arbeitete.
>
> Oder Arduino IDE. Die war damals um 2020 noch sehr aktuell und weit
> verbreitet.

Was war nochmal Arduino?

von Stefan F. (Gast)


Lesenswert?

>>> Leute, diese ganze Diskussion stammt doch aus einer Zeit, als man
>>> noch mit Zeileneditoren wie ed arbeitete.

>> Oder Arduino IDE. Die war damals um 2020 noch sehr aktuell und weit
>> verbreitet.

Wilhelm M. schrieb:
> Was war nochmal Arduino?

Diese komische altmodische Entwicklungsumgebung ohne Debugger.
Give me Five!

von Wilhelm M. (wimalopaan)


Lesenswert?

Stefanus F. schrieb:
>>>> Leute, diese ganze Diskussion stammt doch aus einer Zeit, als man
>>>> noch mit Zeileneditoren wie ed arbeitete.
>
>>> Oder Arduino IDE. Die war damals um 2020 noch sehr aktuell und weit
>>> verbreitet.
>
> Wilhelm M. schrieb:
>> Was war nochmal Arduino?
>
> Diese komische altmodische Entwicklungsumgebung ohne Debugger.
> Give me Five!

Ich bin enttäuscht: wir beweisen doch die Korrektheit ;-)

von Stefan F. (Gast)


Lesenswert?

Wilhelm M. schrieb:
> Ich bin enttäuscht: wir beweisen doch die Korrektheit ;-)

Ausnahmen bestätigen die Regel.

von Peter D. (peda)


Lesenswert?

Der Typ ist nur selten für das Verständnis wichtig. Ich hab schon genug 
damit zu tun, kurze und die Funktion beschreibende Namen auszudenken, da 
muß ich nicht noch die Lesbarkeit durch unnütze Präfixe und Suffixe 
erschweren.

von Profi (Gast)


Lesenswert?

Eine der erfolgreichsten Software Firmen ist Microsoft. Eine der 
Ursachen ist, sie beginnen jede Variable mit einem Typvorsatz und die 
Teile der Namen beginnen mit einem Großbuchstaben. Es gibt Profis und 
Stümper. Man sollte von den Profis lernen.

von Thomas M. (langhaarrocker)


Lesenswert?

Profi schrieb:
> Eine der erfolgreichsten Software Firmen ist Microsoft. Eine der
> Ursachen ist, sie beginnen jede Variable mit einem Typvorsatz und die
> Teile der Namen beginnen mit einem Großbuchstaben. Es gibt Profis und
> Stümper. Man sollte von den Profis lernen.

Wie schon in diesem Thread erwähnt wurde, hat selbst Microsoft 
eingesehen, dass das Unsinn war.

Yalu X. schrieb:
> Ganz abgesehen davon entspricht die Microsoftsche Ungarische Notation
> nicht den ursprünglichen Ideen ihres Erfinders Simonyi. Zudem hat auch
> Microsoft längst den Unsinn darin erkannt und verbietet mittlerweile (in
> .NET-Bibliotheken) sogar ihre Nutzung.

von A. S. (Gast)


Lesenswert?

Profi schrieb:
> Eine der erfolgreichsten Software Firmen ist Microsoft. Eine der
> Ursachen ist, sie beginnen jede Variable mit einem Typvorsatz und die
> Teile der Namen beginnen mit einem Großbuchstaben. Es gibt Profis und
> Stümper. Man sollte von den Profis lernen.

Laut Wikipedia: https://de.wikipedia.org/wiki/Ungarische_Notation

sollte eigentlich der Verwendungszweck angegeben werden. Die Notierung 
des Datentyps ist

> für den schlechten Ruf der Konvention verantwortlich, weil die Benennung einer 
Variablen nach dem Datentyp wenig zum Verständnis des Inhalts beiträgt und 
trotzdem viel Aufwand verursacht.

Typo-Konventionen (z.B. CamelCase oder _) oder ein Präfix n für Anzahl, 
i für Index oder auch p für Pointer sind doch ok. Schlimm sind "pac" für 
pointer auf Array of char oder "i" bzw. "i32" für Integer.

von Wilhelm M. (wimalopaan)


Lesenswert?

A. S. schrieb:

> Typo-Konventionen (z.B. CamelCase oder _)

Ich wusste gar nicht, dass es für Schreibfehler (typo) Konventionen gibt 
;-)

von Jobst Q. (joquis)


Lesenswert?

Egon D. schrieb:
> Alles, was nicht auf Deinen Garten beschränkt ist, ist
> global?
>
> Ich würde eher verschiedene Grade von Lokalität unterscheiden
> (blocklokal, funktionslokal, modullokal,...).

Dann sagt lokal garnichts mehr aus. Blocklokal ist zwar möglich, aber 
nicht sinnvoll. Modullokal ist eben nicht mehr lokal, man könnte 
modulregional sagen, wenn man das Wort global nicht mag.

Solange ein Programm nur aus einem Modul bzw einem Quelltext besteht, 
ist global und modulregional identisch. Erweitert man nun das Programm 
um ein Modul, sind alle bisher globalen Variablen nicht mehr global im 
Sinne von programmweit gültig, obwohl sich nichts an ihnen geändert hat. 
Global wären dann nur noch Variablen, die als extern deklariert sind.

Der Unterschied zwischen modulweit und programmweit ist also eher 
theoretischer Natur. Dagegen ist der Unterschied zu (funktions-)lokalen 
Variablen drastisch und von großer praktischer Bedeutung.

Lokale Variablen sind im allgemeinen auch temporär, also zeitlich nur 
gültig solange sie abgearbeitet wird. Es gibt zwar auch die Möglichkeit 
statische Variablen in einer Funktion zu deklarieren, das schafft aber 
meist mehr Probleme als sie löst.

von S. R. (svenska)


Lesenswert?

Jobst Q. schrieb:
>> Ich würde eher verschiedene Grade von Lokalität unterscheiden
>> (blocklokal, funktionslokal, modullokal,...).
>
> Dann sagt lokal garnichts mehr aus. Blocklokal ist zwar möglich, aber
> nicht sinnvoll. Modullokal ist eben nicht mehr lokal, man könnte
> modulregional sagen, wenn man das Wort global nicht mag.

Deine Definition von "lokal" beschränkt sich auf eine Weltsicht von "es 
gibt Funktionen und die haben ein drinnen (lokal) und ein draußen 
(global)". Das ist manchmal sinnvoll und manchmal nicht. Vor allem 
schränkt es dich in deiner Denkweise stark ein.

Wenn ich ein Buch verleihe, dann mache ich es jemandem zugänglich, der 
außerhalb meines Scopes liegt (ergo: nicht lokal). Aber deswegen mache 
ich es noch lange nicht jedem Menschen auf dieser Welt zugänglich (ergo: 
nicht global).

Im Übrigen nutze ich blocklokale Variablen sehr gerne (z.B. in 
Schleifen).

von Rolf M. (rmagnus)


Lesenswert?

Jobst Q. schrieb:

> Solange ein Programm nur aus einem Modul bzw einem Quelltext besteht,
> ist global und modulregional identisch. Erweitert man nun das Programm
> um ein Modul, sind alle bisher globalen Variablen nicht mehr global im
> Sinne von programmweit gültig, obwohl sich nichts an ihnen geändert hat.
> Global wären dann nur noch Variablen, die als extern deklariert sind.

Eine etwas merkwürdige Logik. Wenn man ihr weiter folgt, wären alle 
lokalen Variablen auch global, solange man nur eine Funktion (also 
main()) hat, da man sie ja dann auch vom ganzen Programm aus sieht und 
sie auch über die gesamte Programmlaufzeit existieren.

: Bearbeitet durch User
von A. S. (Gast)


Lesenswert?

Rolf M. schrieb:
> solange man nur eine Funktion (also
> main()) hat, da man sie ja dann auch vom ganzen Programm aus sieht und
> sie auch über die gesamte Programmlaufzeit existieren.

Wenn Du so willst, ja. Bzw. Nein. Auch dann würdest Du ja (nach der 
Initialisierung) eine Endlosschleife haben. Und die wiederum hat viele 
Blöcke, von denen aus gesehen es lokale (nur innerhalb dieses Blocks) 
und globale (oberhalb dieses Blocks) Variablen gibt.

Wenn auch Spaghtetti-Code, das Prinzip ist gleich (nur, dass die Blöcke 
im Gegensatz zu Funktionen keine Parameter)


Von daher finde ich die Unterscheidung Stimmig, egal ob Block, File oder 
Projekt:

Globale Variablen (von außerhalb)
Parameter (Übergeben)
lokale Varialen (nur innerhalb)

von S. R. (svenska)


Lesenswert?

A. S. schrieb:
> Und die wiederum hat viele Blöcke, von denen aus
> gesehen es lokale (nur innerhalb dieses Blocks)
> und globale (oberhalb dieses Blocks) Variablen gibt.

Membervariablen sind aus mehreren Blöcken (nämlich den Methoden) 
erreichbar, gleichzeitig aber nur von dort.

Wie würdest du sie einordnen? Lokal, global oder doch keins davon?

: Bearbeitet durch User
von M. Н. (Gast)


Lesenswert?

Profi schrieb:
> sie beginnen jede Variable mit einem Typvorsatz und die
> Teile der Namen beginnen mit einem Großbuchstaben. Es gibt Profis und
> Stümper. Man sollte von den Profis lernen.

Man kann aber auch den Linux Kernel anschauen Beispiel:

https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/tree/kernel/audit.c

Das ist auch ein großes Projekt und ziemlich erfolgreich. Klar. Das ist 
kein riesen SW-Unternehmen. Trotzdem ist es Code von hoher Qualität, 
obwohl der Coding-Style so ziemlich das Gegenteil ist.

Das wichtigste meiner Meinung nach ist, dass es sich flüssig liest. Und 
das ist, finde ich, bei ungarischer Notation nicht der Fall. Auch die 
Einrückung des Codes um einen TAB (entspricht 8 Leerzeichen) hilft, dass 
der Code sehr lesbar ist, obwohl vermutlich die meisten mit dem Kopf 
darüber schütteln

von Jobst Q. (joquis)


Lesenswert?

Rolf M. schrieb:
> Jobst Q. schrieb:
>
>> Solange ein Programm nur aus einem Modul bzw einem Quelltext besteht,
>> ist global und modulregional identisch. Erweitert man nun das Programm
>> um ein Modul, sind alle bisher globalen Variablen nicht mehr global im
>> Sinne von programmweit gültig, obwohl sich nichts an ihnen geändert hat.
>> Global wären dann nur noch Variablen, die als extern deklariert sind.
>
> Eine etwas merkwürdige Logik. Wenn man ihr weiter folgt, wären alle
> lokalen Variablen auch global, solange man nur eine Funktion (also
> main()) hat, da man sie ja dann auch vom ganzen Programm aus sieht und
> sie auch über die gesamte Programmlaufzeit existieren.

Das ist nicht meine Logik, deshalb "im Sinne von programmweit gültig". 
Von manchen wird global so verstanden, ich habe es eher als nicht-lokal 
verstanden und so ist auch die Unterscheidung in meiner 
Benennungskonvention: Nur lokale (temporäre) Variablen beginnen mit 
Kleinbuchstaben.

von Jobst Q. (joquis)


Lesenswert?

S. R. schrieb:
> Membervariablen sind aus mehreren Blöcken (nämlich den Methoden)
> erreichbar, gleichzeitig aber nur von dort.
>
> Wie würdest du sie einordnen? Lokal, global oder doch keins davon?

Könnte man regional nennen.

von c-hater (Gast)


Lesenswert?

M. H. schrieb:

> Das ist auch ein großes Projekt und ziemlich erfolgreich. Klar. Das ist
> kein riesen SW-Unternehmen. Trotzdem ist es Code von hoher Qualität,

Nein, er ist nur von durchgängig ziemlich gleicher, aber nicht von 
wirklich hoher Qualität.

Um das ganz klar zu sagen: Auch dieser Zustand ist ein Zustand, der den 
Linux-Kernel ganz klar über die meiste kommerzielle Software erhebt. 
Aber leider: immer noch weit entfernt von Perfektion.

Man braucht einfach mal nur die Kernel-Updates zu verfolgen, um einen 
Eindruck davon zu bekommen, wo die Säge klemmt. Das sind immer und immer 
wieder Sachen, die mit einer richtigen Hochsprache einfach garnicht erst 
passieren könnten. Sprich: hier ist schlicht die (wegen der Effizienz 
gewollte) Maschinennähe und deren gleichzeitig unzureichende 
Unterstützung durch die gewählte Programmiersprache "Schuld" an den 
Sicherheitslücken. Im Endeffekt ist es aber natürlich die Unfähigkeit 
der reinen Hochsprachenprogrammierer, die potentiellen Sicherheitslücken 
auch ohne Compilerhilfe (bzw. die Hilfe eines Laufzeitsystems) 
vorausschauend erkennen und verhindern zu können.

> obwohl der Coding-Style so ziemlich das Gegenteil ist.

Assemblernah, soweit es C halt zuläßt. Absolut sinnvoll im Sinne der 
Aufgabe. Das Ziel des aus der Sicht der C-only-Wichser "schlechten" 
Codierstils ist ganz klar: Wir machen es dem Compiler so einfach wie 
möglich, effizienten Code zu erzeugen. Weil wir (im Gegensatz zu diesen 
unsäglichen C-Only-Wichsern) wissen, dass Compiler halt nach wie vor 
weit weg davon sind, perfekt zu sein.

von Dr. Sommer (Gast)


Lesenswert?

c-hater schrieb:
> C-only-Wichser

Ja, gute Programmierer können auch noch mehr Sprachen wie Python, Scala, 
Scheme, Mathematica, SQL, Haskell, Erlang, JavaScript, Java, ... und 
können von dort Paradigmen übernehmen.

von Rufus Τ. F. (rufus) Benutzerseite


Lesenswert?

c-hater schrieb:
> unsäglichen C-Only-Wichsern

Sagt der unsägliche c-hater.

von Carl D. (jcw2)


Lesenswert?

Dr. Sommer schrieb:
> c-hater schrieb:
>> C-only-Wichser
>
> Ja, gute Programmierer können auch noch mehr Sprachen wie Python, Scala,
> Scheme, Mathematica, SQL, Haskell, Erlang, JavaScript, Java, ... und
> können von dort Paradigmen übernehmen.

Und gute Programmieren können vor allem auch Assembler, oft von all 
den Sache, mit denen sie im Läufe der Jahrzehnte Kontakt hatten. z80, 
8048, 8051, x86, AVR, ARM jeweils privat, oder eben /370 beruflich, wenn 
auch schon 2 Jahrzehnte nicht mehr.
Einfach nur die Mainstreamsprache zu hassen ist keine Leistung. Selbst 
wenn man bei C die Freiheit hat sich Probleme einzufangen, Assembler ist 
C darin haushoch überlegen.

von Marc V. (Firma: Vescomp) (logarithmus)


Lesenswert?

Rufus Τ. F. schrieb:
> Eine weitere Konvention aus ähnlichem Dunstkreis ist "CamelCase", bei
> dem Variablennamen, die aus mehreren Wörtern zusammengesetzt werden, mit
> Großbuchstaben im Wort geschrieben werden

 Am übersichtlichsten.
 Den Typ da noch reinzuquetschen ist vollkommen überflüssig.

Axel S. schrieb:
> sein, der den Code lesen und pflegen muß. Der Typ ist dafür in 99.9% der
> Fälle  aber vollkommen irrelevant bzw. wenn erforderlich, von der IDE
> mit nur einem Tastendruck abrufbar ("zeige die Definition des Symbols
> unter der Maus").

 Genau.
 Und "Konstanten.hh" und "Variablen.hh" mit Blöcken für verschiedene
 Routinen, wo Variablen und Konstanten zusammengelegt werden, machen
 das Ganze übersichtlich genug.

Rufus Τ. F. schrieb:
> Ich bin mal einem von Betriebspraktikanten in jahrelanger Arbeit
> "gepflegtem" Projekt begegnet, in dem es allen Ernstes die folgenden
> Variablennamen gab:
>
> a
...
> aaaaa

 In kurzen Routinen mache ich mir nicht die Mühe, Variablen,
 insbesondere die Loop- und Umrechnungsvariablen, anders als x,y,z,
 zu benennen.

: Bearbeitet durch User
von Blechbieger (Gast)


Lesenswert?

Marc V. schrieb:
> In kurzen Routinen mache ich mir nicht die Mühe, Variablen,
>  insbesondere die Loop- und Umrechnungsvariablen, anders als x,y,z,
>  zu benennen.

Also zumindest bei geschachtelten Schleifen und mehrdimensionalen Arrays 
verwende ich sprechende Laufvariablen da man selber oder der nächste sie 
zu leicht verwechselt.

von Jobst Q. (joquis)


Lesenswert?

Blechbieger schrieb:
> Also zumindest bei geschachtelten Schleifen und mehrdimensionalen Arrays
> verwende ich sprechende Laufvariablen da man selber oder der nächste sie
> zu leicht verwechselt.

'laufvariable' ist vielleicht geschwätziger, sagt aber auch nicht mehr 
als 'i'. Und wenn es um verschachtelte Schleifen geht, sagt 'i1' 'i2' 
usw auch ohne Buchstabenballast etwas über die Tiefe der Verschachtelung 
aus.

von Blechbieger (Gast)


Lesenswert?

1
for device
2
  for target
3
     for slot
4
         array[device][target][slot] = irgendwas abhängig von device, target und slot

halte ich schon für übersichtlicher als x,y,z insbesondere wenn mit den 
Variablen noch gerechnet werden soll.

von Jörg W. (dl8dtl) (Moderator) Benutzerseite


Lesenswert?

Carl D. schrieb:
> Selbst wenn man bei C die Freiheit hat sich Probleme einzufangen,
> Assembler ist C darin haushoch überlegen.

Das ist signaturverdächtig. :-)

von Framulestigo (Gast)


Lesenswert?

Blechbieger schrieb:
> halte ich schon für übersichtlicher als x,y,z insbesondere wenn mit den
> Variablen noch gerechnet werden soll.

Im 3D-Raster passt's doch.

von Marc V. (Firma: Vescomp) (logarithmus)


Lesenswert?

Blechbieger schrieb:
> Also zumindest bei geschachtelten Schleifen und mehrdimensionalen Arrays
> verwende ich sprechende Laufvariablen da man selber oder der nächste sie
> zu leicht verwechselt.

 Kommt darauf an.
 x,y,z können nur Loop- oder Umrechnungsechnungsvariablen sein.
 Wenn man sich angewöhnt hat, die Variablen auch in dieser Reihenfolge
 zu verwenden, gibt es keine Probleme, da immer Array[x][y][z].
 Dabei ist für mich x immer die Breite, y die Höhe und z die Tiefe.
 Das hat auch noch den Vorteil, dass man nicht raten muss, ob diese
 Variablen noch für irgendetwas anderes benutzt werden.
 Natürlich benutze ich auch sinnvolle Namen - da wo es nötig ist.

 Ausführliche Kommentare (auch schon bei der Deklaration der
 Variablen/Konstanten) finde ich jedoch viel nützlicher.
 Man lernt so etwas spätestens dann zu schätzen, wenn nach ein paar
 Monaten etwas im Programm geändert werden muss.

Rufus Τ. F. schrieb:
> Ich bin mal einem von Betriebspraktikanten in jahrelanger Arbeit
> "gepflegtem" Projekt begegnet, in dem es allen Ernstes die folgenden
> Variablennamen gab:
>
> a

 Wenn wir schon von Kollegen reden - schreibfaule Typen, die Zeilen
 sparen wollen sind (für mich) viel schlimmer.
 Wir hatten mal einen, der fast immer Dutzend oder mehr Variablen, die
 zwar alle vom selben Typ waren, aber quer durch Programm in
 verschiedenen Routinen benutzt wurden, in einer Zeile deklariert hat,
 um Deklarationen so kurz wie möglich zu halten - prost mahlzeit.

von Daniel -. (root)


Lesenswert?

C und C++ sind nicht stark typisiert, sodass die Verwendung von einer 
Notation durchaus
nützlich sein kann. Vergleiche beispielsweise implizite casts unsigned 
and signed
Typen unterschiedlicher Bitbreite in C und Go.

Am besten eine funktionale Sprache ohne Variablen verwenden ... F# oder 
Haskell ;)

von W.S. (Gast)


Lesenswert?

Ach, hier tummeln sich mal wieder die selbsternannten Pseudo-Gurus und 
stellen ihre erweiterten Regeln für C gegenseitig vor.

Klasse!

Selbstverständlich reicht es nicht aus, sowas wie goto zu verteufeln, 
nein, man muß auch alle gängigen Typen umbenennen und alle Zahlen außer 
0 und 1 aus einem anständigen Programm entfernen und durch Bezeichner 
ersetzen, die dann in 37 verschiedenen Fremd-Dateien verschiedener 
Hersteller in die betreffende Zahl umgesetzt werden - und die 
betreffenden Dateien gehören selbstverständlich NICHT zum Projekt.

Sowas treibt natürlich die schiere Anzahl von Bezeichnern in 
astronomische Höhen, was offenbar gewollt ist. Merkt sich alles prima, 
wenn man sonst nix im Kopf hat, gelle? Mit irgend etwas muß selbiger ja 
gefüllt werden...

Hat mir dies doch neulich jemand angeraten. Das Schöne daran ist, daß er 
mir versprach, sich nicht mehr mit mir unterhalten zu wollen, solange 
ich seiner grandiosen Regel nicht nachkäme. Juchhei, endlich hält dieser 
Kerl seine Klappe und nervt mich und den Rest der Welt nicht mehr mit 
seinen Kommentaren. Ist ein erheblicher Gewinn für's Forum. Hoffentlich 
hält er sich auch an sein Versprechen und ans Klappe-Halten.

Aber sowas ist selbstverständlich nur der Anfang. Man muß schließlich 
auch Regeln für das Benennen von Typen, Variablen, Funktionen und 
sonstwas aufstellen, wo kämen wir denn hin, wenn irgend jemald so 
einfach nur den gesunden Menschenverstand walten ließe?

Also, um hier nen positiven Beitrag zu leisten, schlage ich vor, auch 
ein Kürzel des Autors sowie ein weiteres Kürzel die Datei betreffend, wo 
die Entität deklariert worden ist, in den Namen dieser Entität 
aufzunehmen. Kurze und prägnante Namen kann ja jeder, das muß weg! So 
richtig lange und aussagekräftige Namen müssen her, die man nur 
entziffern kann, wenn man die dazu zu befolgenden Regeln sich ausdruckt 
und an die Wand pinnt.

Sowas nennt man dann Fortschritt oder C 2019.

Ich habe mich übrigens neulich nicht getraut, den Verkäufer nach ner 
tragbaren USB-Festplatte mit 4 Tera-Uint8Tees zu fragen. Aber vielleicht 
kann das ja mal einer von euch probieren und davon berichten.

Also: Beckmesser war die Knalltüte in Wagners Meistersingern, der selber 
zwar nicht wirklich singen konnte, dafür aber mit dem Buch der ehernen 
Regeln unter'm Arm herum lief und allen Meistern ihre angeblichen 
Regelverstöße vorhalten wollte. Eben so einer aus der Klasse der 
selbsternannten Gurus. Aber er konnte deshalb trotzdem nicht gut singen. 
Eine Backpfeife eben.

W.S.

von S. R. (svenska)


Lesenswert?

Carl D. schrieb:
> Und gute Programmieren können vor allem auch Assembler, oft von all
> den Sache, mit denen sie im Läufe der Jahrzehnte Kontakt hatten.

Nicht jeder gute Programmierer hat vor mehreren Jahrzehnten angefangen, 
die damaligen Systeme (mangels Alternativen) in Assembler zu 
programmieren. Manche sind auch schlicht nicht alt genug.

Beitrag #5684146 wurde von einem Moderator gelöscht.
von Anfänger (Gast)


Lesenswert?

Lieber Dr. Sommer, bitte unterlasse doch solche vor allem Anfänger 
verwirrenden Aussagen:

1.) Dr. Sommer schrieb:
> C++ hat überhaupt keine structs

2.) Dr. Sommer schrieb:
> M. H. schrieb:
>> Na klar hat C++ structs:
>> http://www.cplusplus.com/doc/tutorial/structures/
>
> cplusplus.com ist keine Referenz. Da steht viel Unsinn. C++ hat keine
> Structs, nur Klassen. Das Schlüsselwort "struct" definiert eine
> Klasse, in der per default alles "public" ist. Siehe z.B.:

3.) Dr. Sommer schrieb:
> Wenn aber "struct" eine Klasse definiert (siehe das Zitat), wie
> definiert man dann structs?

Zu 1.)
Wenn C++ keine structs hätte, gäbe es in C++ das Schlüsselwort "struct" 
nicht bzw. müsste bei Verwendung zu einer Fehlermeldung führen.

zu 2.)
Ob cplusplus.com nun EINE Referenz für C++ ist oder eben DEINE Referenz 
für C++ gerade nicht ist, spielt keine Rolle. Tatsache ist, es gibt das 
Schlüsselwort struct in C++, nur dessen Bedeutung ist halt anders als in 
C, siehe

https://de.cppreference.com/w/cpp/keyword
https://namespace-cpp.de/std/doku.php/kennen/keywords

"Klassen und Strukturen (struct) sind in C++ gleichwertig mit einer 
Ausnahme: Das voreingestellte Zugriffsrecht einer Klasse ist private.

C, C++ : Das Schlüsselwort struct leitet die Deklaration bzw. Definition 
eines Verbunddatentyps (Struktur) ein, der Daten unterschiedlicher Typen 
bündelt. In C++ dürfen Strukturen, anders als in C, auch Methoden 
enthalten. Damit sind Klassen (class) und Strukturen gleichwertig mit 
einer Ausnahme: Das voreingestellte Zugriffsrecht einer Struktur ist 
public."

zu 3.)

Brauchst du Beispiele dafür?
http://programmingexamples.wikidot.com/struct

von Jörg W. (dl8dtl) (Moderator) Benutzerseite


Lesenswert?

Anfänger schrieb:
> Wenn C++ keine structs hätte, gäbe es in C++ das Schlüsselwort "struct"
> nicht bzw. müsste bei Verwendung zu einer Fehlermeldung führen.

Das ist doch nur eine Definitionsfrage.

C++ hat keine „reinen“ structs, das Schlüsselwort "struct" ist dort nur 
ein alternatives Schlüsselwort für Klassen.

Aber das wurde nun schon zur Genüge hier durchgekaut.

von Dr. Sommer (Gast)


Lesenswert?

Anfänger schrieb:
> Zu 1.) Wenn C++ keine structs hätte, gäbe es in C++ das Schlüsselwort
> "struct" nicht bzw. müsste bei Verwendung zu einer Fehlermeldung führen.

Es gibt hier 2 Ebenen. Die Syntax und die Semantik. Das ist auch etwas, 
das Anfänger verstehen müssen. In der Syntax steht zwar "struct", aber 
die Bedeutung ist "Klasse".

Anfänger schrieb:
> Ob cplusplus.com nun EINE Referenz für C++ ist oder eben DEINE Referenz
> für C++ gerade nicht ist, spielt keine Rolle.

Die einzige Referenz die zählt ist der C++ Standard. Den habe ich 
zitiert. Und da gibt es keine Strukturen, nur Klassen, welche man über 
die Schlüsselwörter "struct" oder "class" definieren kann.

Anfänger schrieb:
> "Klassen und Strukturen (struct) sind in C++ gleichwertig mit einer
> Ausnahme: Das voreingestellte Zugriffsrecht einer Klasse ist private.

Irgendwelche Websiten - noch dazu deutsche Übersetzungen - sind 
irrelevant. Im Internet und sogenannten Online-Tutorials und auch in 
Büchern wird unendlich viel Blödsinn über C++, aber auch über C, 
verbreitet. Nur der Standard zählt. Das "struct" Keyword wird da sogar 
oft in Beispielen verwendet - um Klassen zu definieren.

von Rolf M. (rmagnus)


Lesenswert?

Anfänger schrieb:
> Ob cplusplus.com nun EINE Referenz für C++ ist oder eben DEINE Referenz
> für C++ gerade nicht ist, spielt keine Rolle. Tatsache ist, es gibt das
> Schlüsselwort struct in C++, nur dessen Bedeutung ist halt anders als in
> C, siehe
>
> https://de.cppreference.com/w/cpp/keyword
> https://namespace-cpp.de/std/doku.php/kennen/keywords

Nunja, die einzige wirkliche Referenz für C++ ist die ISO-Spezifikation. 
Dort heißt es in Kapitel 9 "Classes":

A structure is a class defined with the class-key struct; its members 
and base classes (clause 10) are public by default

von Carl D. (jcw2)


Lesenswert?

Rolf M. schrieb:
>
> A structure is a class defined with the class-key struct; its members
> and base classes (clause 10) are public by default

was den Vorteil hat, kompatibel zu bestehendem C-Code zu sein.
Das, die Kompatibilität zur Vorgängern/Vorversionen ist der Grund für 
jede C++ "Sprachungereimtheit". Das ist aber auch der Grund dafür, daß 
sich C++ mit so vielen "besseren" Sprachen vergleichen lassen muß. Es 
hat sie schlicht alle überlebt.

von Yalu X. (yalu) (Moderator)


Lesenswert?

Carl D. schrieb:
> Rolf M. schrieb:
>>
>> A structure is a class defined with the class-key struct; its members
>> and base classes (clause 10) are public by default
>
> was den Vorteil hat, kompatibel zu bestehendem C-Code zu sein.

Ja, das Schlüsselwort struct existiert hauptsächlich aus Gründen der
Abwärtskompatibilität zu C und nicht etwa, um dem faulen Programmierer
das Tippen des Wörtchens "public" zu ersparen. Es wäre ja sonst ziemlich
unsinnig, für die beiden Dinge (class und struct), die sich lediglich in
der defaultmäßigen Sichtbarkeit ihrer Elemente unterscheiden, so völlig
unterschiedliche Bezeichnungen zu wählen.

Deswegen benutze ich struct ausschließlich C-like, d.h. für reine
Datenstrukturen ohne Elementfunktionen, und class ausschließlich für
echte Klassen, d.h. solche, die nicht nur Datenelemente, sondern auch
Elementfunktionen enthalten. Auch eine (selten vorkommende) echte
Klasse, in der sämtliche Elemente public sind, ist bei mir eine class,
auch wenn ich mit struct etwas weniger zu tippen hätte.

Das ganze ist natürlich eine eher philosophische bzw. linguistische
Frage, aber wenn man schon die freie Wahl hat, dürfen auch mal die
Geisteswissenschaften zu Wort kommen ;-)

von Sven B. (scummos)


Lesenswert?

Yalu X. schrieb:
> Deswegen benutze ich struct ausschließlich C-like, d.h. für reine
> Datenstrukturen ohne Elementfunktionen, und class ausschließlich für
> echte Klassen, d.h. solche, die nicht nur Datenelemente, sondern auch
> Elementfunktionen enthalten. Auch eine (selten vorkommende) echte
> Klasse, in der sämtliche Elemente public sind, ist bei mir eine class,
> auch wenn ich mit struct etwas weniger zu tippen hätte.

Den besten Vorschlag den ich zu dieser Unterscheidung gehört habe, war 
"class" für Dinge zu verwenden, die eine Invariante haben. Wenn jeder 
beliebige Wert für jedes der Member ok ist, ist "struct" meist sinnvoll. 
Das passt auch ziemlich gut zu dem, was man so intuitiv tun würde. Es 
passt auch gut zu dem "alles ist public"-Konzept.

: Bearbeitet durch User
von Rufus Τ. F. (rufus) Benutzerseite


Lesenswert?

W.S. schrieb:
> nein, man muß auch alle gängigen Typen umbenennen und alle Zahlen außer
> 0 und 1 aus einem anständigen Programm entfernen und durch Bezeichner
> ersetzen, die dann in 37 verschiedenen Fremd-Dateien verschiedener
> Hersteller in die betreffende Zahl umgesetzt werden - und

Es ist bestens bekannt, daß Du Fan von "magic numbers" im Quelltext 
bist, denn die lassen sich ja viel einfacher im Datenblatt finden.

von W.S. (Gast)


Lesenswert?

Rufus Τ. F. schrieb:
> Es ist bestens bekannt..

Ach, du nörgelst mal wieder.
Aber ich kann dich trösten: Das zuständige Hardware-Register, wo die 
Zahl reinkommt, findet man im RefManual ganz leicht. Und dann sieht man 
auch im zugehörigen Text sowohl die Stelle, wo die Zahl hinkommt, als 
auch..
_TADAA!_
eine zumeist relativ ausführliche Beschreibung, was verschiedene Werte 
für diese Zahl tatsächlich bewirken. Aus dem schieren Namen geht das 
nämlich selten bis nie hervor.

Das ist der wahre Sinn von Refrenz-Manuals - und von den dort 
nachlesbaren Zahlenwerten.

Ansonsten seid ihr ja noch immer beim Vergleichen eurer allerbesten 
Einschränkungen für Variablen-Bezeichner.

Aber daß ihr jetzt beim Käuen von C++ und Klassen versus Structs 
angekommen seid, ist ein Abdriften vom eigentlichen Thema.

Reißt euch zusammen und kreiert endlich die ultimative Vorschrift zum 
Bilden eines qualifizierten Variablennamens. Die Welt wartet sehnsüchtig 
drauf!

Ach ja, anbei fällt mir ein, daß man ja dann auch an die Chip-Hersteller 
herantreten müßte - wo unser wackerer Rufus das Thema schon 
angeschnitten hat. Die Bezeichner für Bitgruppen in den 
Hardwareregistern entsprechen ja selten bis nie den noch festzulegenden 
Variablennamen. Das muß natürlich sofort geändert werden - und dafür 
sind dann die Chiphersteller heranzuziehen.

W.S.

von Rufus Τ. F. (rufus) Benutzerseite


Lesenswert?

W.S. schrieb:
> Das zuständige Hardware-Register, wo die Zahl reinkommt, findet man im
> RefManual ganz leicht.

Ärgerlicherweise wird das Hardwareregister dort aber mit einem Namen 
angesprochen, statt dessen viel eindeutigere und verständlichere Adresse 
zu verwenden. Denn letztlich ist doch genau das Deine

> ultimative Vorschrift zum Bilden eines qualifizierten Variablennamens.

Das hier ist doch viel verständlicher und eingängiger :
1
  *(unsigned char *) 0x1A &= ~1;
2
  *(unsigned char *) 0x1A |= 2;

als das hier:
1
  DDRA &= ~(1 << PA0);
2
  DDRA |= (1 << PA1);

oder?

von A. S. (Gast)


Lesenswert?

W.S. schrieb:
> die dann in 37 verschiedenen Fremd-Dateien verschiedener
> Hersteller in die betreffende Zahl umgesetzt werden - und die
> betreffenden Dateien gehören selbstverständlich NICHT zum Projekt.

> Sowas treibt natürlich die schiere Anzahl von Bezeichnern in
> astronomische Höhen, was offenbar gewollt ist. Merkt sich alles prima,
> wenn man sonst nix im Kopf hat, gelle? Mit irgend etwas muß selbiger ja
> gefüllt werden...

> Aber sowas ist selbstverständlich nur der Anfang. Man muß schließlich
> auch Regeln für das Benennen von Typen, Variablen, Funktionen und
> sonstwas aufstellen, wo kämen wir denn hin, wenn irgend jemald so
> einfach nur den gesunden Menschenverstand walten ließe?

> Also, um hier nen positiven Beitrag zu leisten, schlage ich vor, auch
> ein Kürzel des Autors sowie ein weiteres Kürzel die Datei betreffend, wo
> die Entität deklariert worden ist, in den Namen dieser Entität
> aufzunehmen. Kurze und prägnante Namen kann ja jeder, das muß weg! So
> richtig lange und aussagekräftige Namen müssen her, die man nur
> entziffern kann, wenn man die dazu zu befolgenden Regeln sich ausdruckt
> und an die Wand pinnt.

Du sprichst mir bei dem Post in allen Punkten aus der Seele.

Nur bei den NamensRegeln möchte ich unterscheiden:
a) Regeln, die sich jemand ausdenkt, und an die sich dann alle halten 
sollen.
--> Das führt bei uns regelmäßíg ins Chaos. Das ist so, als würde man 
ein Schrauben-Lager einrichten wollen, ohne zu wissen welche 
Typen/Größen und in welchen Mengen.

b) Regeln, die evolutionär aus gewachsenem Code entstehen.
--> Hier gibt es häufig mehrere Strömungen, bestimmte Token-Typen zu 
benennen. Nach einiger Zeit überwiegt eine Art und die anderen treten 
bei Neubenennungen in den Hintergrund. Nach weiterer Zeit werden diese 
als unnatürlich empfunden, aus der Hauptströumg eine Regel formuliert 
und die anderen refakturiert.

von Marc V. (Firma: Vescomp) (logarithmus)


Lesenswert?

W.S. schrieb:
> Reißt euch zusammen und kreiert endlich die ultimative Vorschrift zum
> Bilden eines qualifizierten Variablennamens. Die Welt wartet sehnsüchtig
> drauf!

 Niemand zwingt dich dazu, deine Variablen so zu benennen - bleib
 doch einfach bei: a, ab, abc etc. wenn dich das glücklich macht.

 Zusätzlich zu den sinnvollen Variablennamen setze ich bei Konstanten
 immer ein c_ davor, etwa so:
1
#define c_SOF    0xAA
2
#define c_EOF    0xA9
3
4
// Position in Buffer
5
#define c_RcvAdr  0x01
6
#define c_SndAdr  0x02
7
#define c_CmdTyp  0x03
8
#define c_CmdLen  0x04
9
#define c_DatBlk  0x05
10
11
#define c_DatBlkLen  0x3F  // 63 Byt max

 So weiss ich immer womit ich es zu tun habe und kann die
 Variablen ohne Probleme so deklarieren:
1
typedef struct {
2
    uint8_t   Msg_SOF;
3
    uint8_t   RcvAdr;
4
    uint8_t   SndAdr;
5
    uint8_t   CmdTyp;
6
    uint8_t   CmdLen;
7
    uint8_t   DatBlk[c_DatBlkLen];
8
} USART_RAM;
9
USART_RAM UartRam; // CRC/ChkSum und EOF werden danach gesendet

 Und wenn du es irgendwann einmal zu einem sinnvollem  Programm,
 welches länger als 5 Zeilen eigenes Code ist, schaffen solltest,
 wirst du es wahrscheinlich selber so machen.

 Natürlich, bei Copy&Paste braucht man sich keine Gedanken darüber
 zu machen - Autor hat es wahrscheinlich schon getan - also bleib
 ruhig bei kopieren.

von Dr. Sommer (Gast)


Lesenswert?

W.S. schrieb:
> Selbstverständlich reicht es nicht aus, sowas wie goto zu verteufeln,
> nein, man muß auch alle gängigen Typen umbenennen und alle Zahlen außer
> 0 und 1 aus einem anständigen Programm entfernen und durch Bezeichner
> ersetzen

Du brauchst doch nur eine Rechtfertigung dafür, dass du in deinen 
Projekten aus Faulheit nicht jedes Bit einzeln mit Namen definierst, 
weil du ja auch die Hersteller-Header verteufelst... Dieses 
Tretminenfeld aus Makros ist zwar nicht schön, aber immer noch besser 
als Massen an Magic Numbers.

W.S. schrieb:
> Also: Beckmesser war die Knalltüte in Wagners Meistersingern

Kennst du eigentlich nur diese eine Oper? Bist du daher einer von diesen 
Intellektuellen?

von Thomas M. (langhaarrocker)


Lesenswert?

Marc V. schrieb:
> Ausführliche Kommentare (auch schon bei der Deklaration der
>  Variablen/Konstanten) finde ich jedoch viel nützlicher.

Grundsätzlich ein falscher Ansatz, aber ... nicht immer.

Jedesmal wenn es einen juckt einen Kommentar zu formulieren sollte man 
zuvor überlegen, ob nicht der gleiche Informationsgewinn durch 
Umbenennen des Bezeichners möglich ist. Zieht man das durch, bleibt 
erstaunlich wenig übrig, das eines Kommentars bedarf und der Code wird 
viel leichter verständlich.

doof:
1
ulong i = 0; // Index für Dingse

besser:
1
ulong dingsIdx = 0;

von A. S. (Gast)


Lesenswert?

Marc V. schrieb:
> Zusätzlich zu den sinnvollen Variablennamen setze ich bei Konstanten
>  immer ein c_ davor, etwa so:#define c_SOF    0xAA
> #define c_EOF    0xA9
>
> // Position in Buffer
> #define c_RcvAdr  0x01
> #define c_SndAdr  0x02
> #define c_CmdTyp  0x03
> #define c_CmdLen  0x04
> #define c_DatBlk  0x05
>
> #define c_DatBlkLen  0x3F  // 63 Byt max
>
>  So weiss ich immer womit ich es zu tun habe und kann die
>  Variablen ohne Probleme so deklarieren:typedef struct {
>     uint8_t   Msg_SOF;
>     uint8_t   RcvAdr;
>     uint8_t   SndAdr;
>     uint8_t   CmdTyp;
>     uint8_t   CmdLen;
>     uint8_t   DatBlk[c_DatBlkLen];
> } USART_RAM;
> USART_RAM UartRam; // CRC/ChkSum und EOF werden danach gesendet

Und warum nicht direkt Strukturen verwenden?

>  Und wenn du es irgendwann einmal zu einem sinnvollem  Programm,
>  welches länger als 5 Zeilen eigenes Code ist, schaffen solltest,
>  wirst du es wahrscheinlich selber so machen.

Dein Codefragment sieht aber genau so aus, als gäbe es nur einen sehr 
kleinen Kontext. Der einzige gemeinsame Nenner der 6 Konstanten (warum 
auch immer die bei 1 anfangen) ist das c_. Und genau das verwendest Du 
doch Deinen Worten nach auch woanders.

>  Natürlich, bei Copy&Paste braucht man sich keine Gedanken darüber
>  zu machen - Autor hat es wahrscheinlich schon getan - also bleib
>  ruhig bei kopieren.

Hat das noch einen Bezug zu irgendwelchen Aussagen von W.S. hier?

von Rufus Τ. F. (rufus) Benutzerseite


Lesenswert?

Marc V. schrieb:
> setze ich bei Konstanten
>  immer ein c_ davor, etwa so:
> #define c_SOF 0xAA

Die allgemein übliche Konvention für Macros ist es, deren Namen in 
Versalien zu schreiben. Deine "Konstanten" sind nämlich keine, sondern 
Macros.

Wenn das eine Konstante sein soll, muss es so aussehen:
1
const uint8_t c_SOF = 0xAA;


A. S. schrieb:
> Und warum nicht direkt Strukturen verwenden?

Macht er doch, die Konstante (genauer: das #define) taucht als Anzahl in 
dem Array aus Strukturen auf, das er anlegt.

von A. S. (Gast)


Lesenswert?

Rufus Τ. F. schrieb:
> A. S. schrieb:
>> Und warum nicht direkt Strukturen verwenden?
>
> Macht er doch, die Konstante (genauer: das #define) taucht als Anzahl in
> dem Array aus Strukturen auf, das er anlegt.

wofür c_RcvAdr, wenn es nur offsetof RcvAdr ist? In den meisten fällen 
schreibt man doch eh X.RcvAdr. Und wenn man den Index braucht ... 
doppelt gemoppelt failed schneller.

von Rufus Τ. F. (rufus) Benutzerseite


Lesenswert?

Ich bezog mich hierauf:
1
uint8_t DatBlk[c_DatBlkLen];

(nein, ein Array aus Strukturen ist das gar nicht, da hab' ich mich 
offensichtlich vertan)

Wozu die anderen "Konstanten" gut sein sollen, hatte ich mir gar nicht 
angesehen.

von Florian S. (sevenacids)


Lesenswert?

Ich versteh gar nicht, warum hier so viel auf C++, class und struct 
rumgekaut wird, darum ging es dem OP doch gar nicht.

"Variablen eindeutig benennen damit der Typ eindeutig ist" - eigentlich 
kann man sich die Frage selbst beantworten, indem man mal den Quellcode 
von einigen Open Source-Projekten überfliegt, die soetwas nutzen und 
sich daran orientieren: gängige Konvention ist wohl, dass dafür Präfixe 
verwendet werden, wenn auch in unterschiedlichen Ausformungen. Ich 
persönlich halte nicht viel davon. Letztlich kommt es, wie oft schon 
angesprochen, auch darauf an, was für das jeweilige Projekt 
vorgeschrieben ist. Für private Sachen kann man es dann halten, wie man 
will.

Viel schlimmer als Variablen mit Präfixen zu versehen finde ich in C 
eher die Unart von vielen Bibliotheken, für die primitiven Typen eigene 
typdefs zu definieren. Statt mit etwas Einheitlichem wie uint32_t darf 
man sich dann mit UINT, uint, UINT32, U32, u4 etc. herumschlagen. Hier 
wäre es mir echt lieber, wenn nicht jeder das Rad neu erfinden bzw. 
älterer Code in dieser Hinsicht mal gewartet werden würde.

: Bearbeitet durch User
von Stefan F. (Gast)


Lesenswert?

Florian S. schrieb:
> Viel schlimmer als Variablen mit Präfixen zu versehen finde ich in C
> eher die Unart von vielen Bibliotheken, für die primitiven Typen eigene
> typdefs zu definieren. Statt mit etwas Einheitlichem wie uint32_t

Ich glaube das hat historischen Grund. Die stdint.h gibt es erst seit 
C99.

von Rufus Τ. F. (rufus) Benutzerseite


Lesenswert?

Stefanus F. schrieb:
> Ich glaube das hat historischen Grund.

Ja, vor allem sind manche Betriebssystem-APIs auch ziemlich alt; das von 
MS verwendete Namensschema (BYTE, WORD, DWORD etc.) ist bald 30 Jahre 
alt (ich hab' zwar noch nie ein Windows 2.x-SDK gesehen, aber das werden 
sie nicht für Windows 3.0 erst so erfunden haben, und das kam im Mai '90 
raus).

von c-hater (Gast)


Lesenswert?

Carl D. schrieb:

> Einfach nur die Mainstreamsprache zu hassen ist keine Leistung.

Scheinbar irgendwie doch schon. Dem Hass liegt nämlich eine durch eigene 
Arbeit mit Blut, Schweiss und Tränen gewonnene Erkenntnisse zugrunde, zu 
der reine Lib-Zusammenleimer niemals gelangen werden...

> Selbst
> wenn man bei C die Freiheit hat sich Probleme einzufangen, Assembler ist
> C darin haushoch überlegen.

Das ist nach den Gesetzen der Informatik nicht wirklich so. Natürlich 
ist unbestritten, dass man in Assembler sehr leicht Fehler produzieren 
kann (Wer wüsste das besser als jemand wie ich, der sehr oft in 
Assembler programmiert o;)

Aber: Der Unterschied zu C ist: Hier kann man nicht nur (fast) alle 
typischen Fehler eines Assemblerprogrammierers begehen (denn die stehen 
einem fast alle durch die mögliche Maschinennähe von C genauso frei zur 
Verfügung), man kann DARÜBER HINAUS auch noch Unmassen C-Fehler begehen. 
D.h.: Fehler in einer Abstraktionsschicht, die in Assembler schlicht 
nicht passieren können, weil diese Abstraktionsschicht dort überhaupt 
nicht existiert.

Schonmal von Komplexitätsbetrachtungen gehört? Das ist eine sehr schönes 
Beispiel für eine nützliche Anwendung solcher Betrachtungen...

von Rufus Τ. F. (rufus) Benutzerseite


Lesenswert?

c-hater schrieb:
> eigene Arbeit mit Blut, Schweiss und Tränen

Wenn Du doch nur einfach C programmieren gelernt hättest, wäre Dir viel 
davon erspart geblieben.

von S. R. (svenska)


Lesenswert?

c-hater schrieb:
> Aber: Der Unterschied zu C ist: Hier kann man nicht nur (fast) alle
> typischen Fehler eines Assemblerprogrammierers begehen (denn die stehen
> einem fast alle durch die mögliche Maschinennähe von C genauso frei zur
> Verfügung), man kann DARÜBER HINAUS auch noch Unmassen C-Fehler begehen.

Die Wahrscheinlichkeit, dass ich einen halbwegs komplexen Ausdruck wie
1
  f = x + 2 * y * (z-1)
in Assembler falsch beschreibe, sind deutlich höher als in C.
Selbst dann noch, wenn man Überläufe usw. berücksichtigt.

Die Wahrscheinlichkeit, dass ich aus einem Array den falschen Wert lese, 
weil ich mich bei der Indexberechnung verhakle, ist in Assembler 
deutlich höher als in C.

Und ja, ich habe schon einiges mit Assembler gearbeitet (und auch 
absichtlich). Es gibt Situationen, in denen will man Assembler. Das sind 
aber äußerst wenige und selbst dort ist C-Interoperabilität hilfreich.

: Bearbeitet durch User
von Marc V. (Firma: Vescomp) (logarithmus)


Lesenswert?

A. S. schrieb:
> kleinen Kontext. Der einzige gemeinsame Nenner der 6 Konstanten (warum
> auch immer die bei 1 anfangen) ist das c_.

 Weil Offset 0 immer SOF ist.
 Und wenn du den Rest nicht verstehst (bzw. keinen gemeinsamen Nenner
 siehst), brauchen wir auch nicht weiter darüber zu diskutieren.

A. S. schrieb:
> wofür c_RcvAdr, wenn es nur offsetof RcvAdr ist? In den meisten fällen
> schreibt man doch eh X.RcvAdr. Und wenn man den Index braucht ...
 Deswegen vielleicht:
1
union {
2
  USART_RAM sRam;
3
  uint8_t sbuff[5 + c_DatBlkLen + 3];
4
} Uart_un;
 ?
 Ich bin mit solcher Bezeichnungsart bisher ganz gut gefahren,
 habe auch nach mehreren Monaten keine Probleme zu verstehen, was
 es bedeuten soll.

Thomas M. schrieb:
> Jedesmal wenn es einen juckt einen Kommentar zu formulieren sollte man
> zuvor überlegen, ob nicht der gleiche Informationsgewinn durch
> Umbenennen des Bezeichners möglich ist. Zieht man das durch, bleibt
> erstaunlich wenig übrig, das eines Kommentars bedarf und der Code wird
> viel leichter verständlich.

 Also, das stimmt bestimmt nicht, zumindest nicht für einigermassen
 komplexe Programe.
 Ich wollte schon unzählige Male beim ändern bzw. erweitern eines
 Programs klüger sein als beim schreiben, ein paar Bytes/Takte einsparen
 aber das hat sich ohne entsprechende Kommentare oft genug als ein
 Schuss nach hinten erwiesen.

 Wie gesagt, das alles mag Geschmacksache sein, nicht aber in einem
 Team - da fliegt man ohne entsprechend kommentierten Code ganz
 schnell raus.
 Und bei Variablen wie a, aa, aaa... erst recht.

: Bearbeitet durch User
von W.S. (Gast)


Lesenswert?

Rufus Τ. F. schrieb:
> Wenn Du doch nur einfach C programmieren gelernt hättest,

So nicht, mein Lieber. Er hat C gelernt. Aber C gelernt zu haben und es 
vernünftig benutzen zu können, ist etwa GANZ anderes, als diese 
Programmiersprache zu mögen oder gar zu lieben (oder noch schlimmer: sie 
zu verehren).

Nee, mit etwas Abstand betrachtet, ist C eine zwar versatile, aber 
dennoch häßliche Programmiersprache, die eben auch ihren Benutzern die 
Freiheit läßt, ihre Quelltexte bis zur Unleserlichkeit zu verhunzen. Ja, 
das geht und man kriegt das ganz einfach auf die bürokratische Weise 
hin, indem man saublöde Zusatz-Regeln aufstellt, die das Übliche sind: 
Gut gemeint und damit auch hier das Gegenteil von gut gemacht.

Tja, gut gemeint... Da setzen sich Leute hin, um sich sowas wie c_ für 
Konstanten per #define auszudenken (und meinen dazu "So weiss ich immer 
womit ich es zu tun habe") - oder noch anderen Schmonzes.

Dieser Thread ist ne Sammlung davon.

Aber wer sich schon daran macht, Regeln aufzustellen, der sollte diese 
auch zuende denken. Wenn man sowas wie

#define c_ottokar 4711

fordert, um das Konstantenhafte zu dokumentieren, was legt man dann für 
ne echte Konstante fest? Rufus hat das ja schon thematisiert:

const int c_i_echt_ottokar = 4711;

So? Oder wie sonst?

Wer Unterschiede so dokumentiert haben will, muß auch für alle im 
Sprachumfang erlaubten Fälle etwas Passendes ausdenken.

An so einem Mini-beispiel sieht man deutlich, was für Pappnasen hier 
sich an Regulierungen versuchen. Alles Mumpitz, was man deutlich sehen 
kann, wenn man diese dummen Gedanken mal konsequent zuende denkt.


Thomas M. schrieb:
> doof:ulong i = 0; // Index für Dingse
> besser:ulong dingsIdx = 0;

O ha! Und du bist ernstlich der Ansicht, daß man aus dingsIdx mehr an 
Verständnis entnehmen kann als aus einen einfachen i ?

Für lokale Zählindizes sind Namen wie i,j,k,l sehr brauchbar, denn sie 
halten die Ausdrücke kurz und haben auch nur einen Gültigkeitsbereich 
von nur wenigen Textzeilen. Hier mit Namen wie 'lokalerZaehlIndex' 
arbeiten zu wollen ist albern. Vielleicht sollten mal alle 
C-Programmierer nen Fortran-Kurs belegen.

Dr. Sommer schrieb:
> Kennst du eigentlich nur diese eine Oper? Bist du daher einer von diesen
> Intellektuellen?

Diese Oper ist leider hier die zuständige Instanz. Deswegen. Ich hätte 
mir durchaus hier mehr Leute mit Intellekt gewünscht, aber - nun ja - 
man kann ja leider nicht alles haben.

W.S.

von Stefan F. (Gast)


Lesenswert?

Also ich liebe meine Familie und ich hasse den Mann, der mich 3 Monate 
lang für sich arbeiten liess ohne zu bezahlen.

Der c_hater hat vermutlich weder eine Liebe noch eine Nemesis, deswegen 
fällt er hier so seltsam auf. Irgendwo braucht jeder sein Ventil.

von Dr. Sommer (Gast)


Lesenswert?

W.S. schrieb:
> Ich hätte mir durchaus hier mehr Leute mit Intellekt gewünscht, aber -
> nun ja - man kann ja leider nicht alles haben.

Die Welt ist kein Wunschkonzert. Nicht jeder kann deiner kruden 
Weltsicht folgen.

von Rainer V. (a_zip)


Lesenswert?

Dr. Sommer schrieb:
> Die Welt ist kein Wunschkonzert. Nicht jeder kann deiner kruden
> Weltsicht folgen.

Nun bin ich erst mal (wieder) überrascht, wieviele Beiträge sich zu so 
einem Blödsinn sammeln. Blödsinn, weil wenn privat, dann Jacke wie 
Hose...wenn Profi, dann gibt es eine bindende(!) Vorschrift, wie 
Programme geschrieben werden müssen!! Wenn nicht, dann reden wir von 
einer "Klitsche", die nicht besser als "privat" ist! Und hier melden 
sich offensichtlich Repräsentanten aller Kathegorien...zumindes die 
"Profis" hätte ich hier nicht erwartet :-)
Gruß Rainer

von A. S. (Gast)


Lesenswert?

Marc V. schrieb:
> Ich bin mit solcher Bezeichnungsart bisher ganz gut gefahren,
>  habe auch nach mehreren Monaten keine Probleme zu verstehen, was
>  es bedeuten soll.

Das glaube ich Dir. Es wird nur noch einfacher, wenn Du Dir redundante 
defines sparst. Poste ein Beispiel und ich spendiere Dir eine Kiste 
Bier, wenn ich es ohne Redundanz nicht einfacher hinbekomme .

Marc V. schrieb:
> ch wollte schon unzählige Male beim ändern bzw. erweitern eines
>  Programs klüger sein als beim schreiben, ein paar Bytes/Takte einsparen
>  aber das hat sich ohne entsprechende Kommentare oft genug als ein
>  Schuss nach hinten erwiesen.

Das sind aber 2 verschiedene Baustellen:

Sinnvolle Namen statt Kommentare (darum ging es)

Kommentieren von abgefahrenen  Tricks (darum ging es nicht)

von Sven B. (scummos)


Lesenswert?

Rainer V. schrieb:
> wenn Profi, dann gibt es eine bindende(!) Vorschrift, wie
> Programme geschrieben werden müssen!! Wenn nicht, dann reden wir von
> einer "Klitsche", die nicht besser als "privat" ist!

Was mich an diesem Forum immer beeindruckt ist das Muster aus diesem 
Post: "Ich bin Profi und mache alles superprofessionell. Wenn ihr das 
weniger professionell macht, seid ihr doofe Noobs!"

Und dann muss natürlich der nächste kommen und zeigen, dass er noch 
professioneller ist als das, weil er noch irgendeine wirre Maßnahme 
ergreift, bei der alle die das nicht machen doofe Noobs sind. Bis man 
bei irgendsoeinem absurden theoretischen Professionalitätsniveau 
angelagt ist, was mit der Realität nur noch wenig und mit der 
ursprünglichen Frage und Situation garantiert überhaupt nichts mehr zu 
tun hat. Nur damit jeder mal gezeigt hat, wie professionell er ist.

Das lustige daran ist, dass diese Posts immer darauf aus sind, andere 
mit der eigenen Erfahrung zu beeindrucken. Diesen Zweck verfehlen sie 
aber zuverlässig bei allen Lesergruppen.

Die tatsächlich erfahrenen Leute haben erfahrungsgemäß eine deutlich 
entspanntere Haltung zu vielen Dingen, und haben erkannt dass es meist 
viele Wege gibt, die zu einem vernünftigen Ergebnis führen. Die genaue 
Einhaltung eines einzelnen Konzepts ist dabei meist nicht so wichtig. 
Anders gesagt: An dem herummaulen was andere tun ist leicht. Schwieriger 
ist, konstruktiv darauf aufzubauen und ausgehend von der Situation des 
anderen einen pragmatischen Verbesserungsvorschlag zu machen.

: Bearbeitet durch User
von Frank M. (ukw) (Moderator) Benutzerseite


Lesenswert?

Rufus Τ. F. schrieb:
> Es ist bestens bekannt, daß Du Fan von "magic numbers" im Quelltext
> bist, denn die lassen sich ja viel einfacher im Datenblatt finden.

Es ist viel schlimmer: Diese "Magic Numbers by W.S." müssen für jeden 
ATmega/ATTiny bei einer Portierung auf einen Verwandten der AVR-Familie 
neu angepasst werden, weil die Bits öfter mal an anderen Positionen im 
Register stecken. Unnötige Arbeit, wenn man die entsprechenden 
Preprocessor-Konstanten wie z.B. COM0A0 verwendet.

Allerdings kann man da auch auf die Nase fliegen, da sie nicht immer nur 
innerhalb desselben Registers "wandern", sondern manchmal - aber 
glücklicherweise selten - auch (je nach AVR) das Register wechseln.

Deshalb hatte ich vor ein paar Jahren mal ein Projekt "Registersichere 
Anwendung von Flags" vorgeschlagen. Leider ist es aus Zeitmangel nur bei 
einem Konzept geblieben. Es wäre nämlich eine Menge Arbeit gewesen, für 
alle AVRs sämtliche Register und deren Flags bzw. Bitgruppen vollständig 
und registersicher zu beschreiben. Mit diesem Werkzeug wäre es dann aber 
vollkommen egal, in welchem Register die Bits überhaupt stecken.

Siehe auch: Beitrag "Re: AVR-Register als Bitfields"

von Marc V. (Firma: Vescomp) (logarithmus)


Lesenswert?

W.S. schrieb:
> Tja, gut gemeint... Da setzen sich Leute hin, um sich sowas wie c_ für
> Konstanten per #define auszudenken (und meinen dazu "So weiss ich immer
> womit ich es zu tun habe") - oder noch anderen Schmonzes.

 Mag für dich und andere Möchtegern- und Copy&Paste Experten Schmonz 
sein,
 für mich ist es nicht.

W.S. schrieb:
> auch zuende denken. Wenn man sowas wie
>
> #define c_ottokar 4711
>
> fordert, um das Konstantenhafte zu dokumentieren, was legt man dann für
> ne echte Konstante fest? Rufus hat das ja schon thematisiert:
>
> const int c_i_echt_ottokar = 4711;
>
> So? Oder wie sonst?

 Wie du nicht weisst, wird const ins Flash geschrieben, #define aber
 ist einfach eine Anweisung für Präprozessor.
 Einen Array mit festen Werten schreibe ich als:
1
static const uint8_t c_7seg[] = {
2
...
3
}
 und kann auch daraus lesen.

 So etwas kann man aber mit const nicht machen:
1
const uint8_t c_DatBlkLen = 0x3F;  // 63 Byt max
2
uint8_t   DatBlk[c_DatBlkLen];
 mit #define dagegen geht das ohne Probleme.

 Etwas, was mit #define definiert wurde, kann mit #undef wieder
 rückgängig gemacht werden.

 Wenn du mit Copy&Paste aufhörst, wirst du das (kaum wahrscheinlich
 aber immerhin zu 0,0001% möglich) auch verstehen.

: Bearbeitet durch User
von Jörg W. (dl8dtl) (Moderator) Benutzerseite


Lesenswert?

Frank M. schrieb:

> Deshalb hatte ich vor ein paar Jahren mal ein Projekt "Registersichere
> Anwendung von Flags" vorgeschlagen. Leider ist es aus Zeitmangel nur bei
> einem Konzept geblieben. Es wäre nämlich eine Menge Arbeit gewesen, für
> alle AVRs sämtliche Register und deren Flags bzw. Bitgruppen vollständig
> und registersicher zu beschreiben.

Könnte man mittlerweile per xslt aus den XML-Beschreibungen machen.

Beim ATmega128RFA1 (und seinen Nachfolgern) hatten wir sowas ins 
offizielle Headerfile in der avr-libc reingepackt, aber das hat in der 
restlichen AVR-Welt innerhalb Atmel keinen Anklang gefunden. Seit sie 
nun all ihren eigenen Device-Support nur noch über ihre "device packs" 
verteilen (und damit eigene Headerfiles ausliefern, die nicht denen des 
avr-libc-Projekts entsprechen), dürfte das gänzlich den Bach 
runtergegangen sein.

von Egon D. (Gast)


Lesenswert?

W.S. schrieb:

> Aber wer sich schon daran macht, Regeln aufzustellen,
> der sollte diese auch zuende denken.

Warum denn das? Worauf gründet sich diese Regel? Hast
Du die etwa selbst aufgestellt, ohne sie ganz zu Ende
zu denken?

Es ist sehr sinnvoll, nur häufig auftretende Problemfälle
durch explizit formulierte Regeln zu beseitigen. Andernfalls
löst man eben Probleme, die sich gar nicht stellen -- dafür
gibt es das schöne Wort "Überregulation".


> Wenn man sowas wie
>
> #define c_ottokar 4711
>
> fordert, um das Konstantenhafte zu dokumentieren, was
> legt man dann für ne echte Konstante fest? Rufus hat
> das ja schon thematisiert:
>
> const int c_i_echt_ottokar = 4711;

Das ist ja wohl eine perverse (="verdrehte") Weltsicht.
Das, was Du als "echte Konstante" bezeichnest, ist
technisch eine vorbelegte Variable.


> Thomas M. schrieb:
>> doof:ulong i = 0; // Index für Dingse
>> besser:ulong dingsIdx = 0;
>
> O ha! Und du bist ernstlich der Ansicht, daß man aus
> dingsIdx mehr an Verständnis entnehmen kann als aus
> einen einfachen i ?

Machst Du Witze?

Wenn eine Routine mit Koordinaten, Codeworten (die
aus zwei verschachtelten Koordinaten bestehen) und
Ternärvektoren (die ihrerseits aus einem Codewort
und einer Maske bestehen) operiert, dann möchte ich
schon gern auf einen Blick sehen, ob jetzt die nächste
Koordinate, das nächste Codewort oder der nächste
Ternärvektor gemeint ist. Das ist nämlich nicht GANZ
dasselbe.

Ich verwende durchaus auch i,j,k für Indizes und
Laufvariablen, aber das nur, wenn aus dem Zusammenhang
offensichtlich ist, worauf sich dieser Index bezieht.


> Für lokale Zählindizes sind Namen wie i,j,k,l sehr
> brauchbar, denn sie halten die Ausdrücke kurz und
> haben auch nur einen Gültigkeitsbereich von nur wenigen
> Textzeilen. Hier mit Namen wie 'lokalerZaehlIndex'
> arbeiten zu wollen ist albern.

Überhaupt nicht.
Wenn man Daten aus einem Quelldatenfeld liest, sie
verarbeitet und dann im Ergebnis der Verarbeitung
in eines von mehreren Ergebnisfeldern schreibt, dann
möchte man schon gern wissen, welcher Index in welches
Feld zeigt.

Es gibt mehr als for-Schleifen, und auch in zwei
geschachtelten Schleifen kann man mehr als zwei
Indizes benötigen. Und -- nein, dass lässt sich NICHT
immer vermeiden. Manche Algorithmen SIND eben einfach
kompliziert.


> Ich hätte mir durchaus hier mehr Leute mit Intellekt
> gewünscht, aber - nun ja - man kann ja leider nicht
> alles haben.

Nun ja. Intellekt liegt im Auge des Betrachters...

von Rainer V. (a_zip)


Lesenswert?

A. S. schrieb:
> Sinnvolle Namen statt Kommentare (darum ging es)

Ich wiederhole mich ungern, aber dem TO kann man nur sagen, was Profis 
machen oder HiWis! Da sich hier lustigerweise sowohl Profis, als auch 
HiWis die Klinke in die Hand geben...was soll man da sagen...ich fand 
meinen Beitrag zur Mausefalle unterhaltsamer!
Gruß Rainer

von S. R. (svenska)


Lesenswert?

Rainer V. schrieb:
> wenn Profi, dann gibt es eine bindende(!) Vorschrift, wie
> Programme geschrieben werden müssen!! Wenn nicht, dann reden wir von
> einer "Klitsche", die nicht besser als "privat" ist!

Ach was erzählst du da für einen Unsinn...
Professionell heißt nur, dass man damit Geld verdient und sagt nichts 
über die Qualität aus. Eine wie auch immer geartete, "bindende 
Vorschrift, wie Programme geschrieben werden müssen" ist ein 
untrügliches Zeichen dafür, dass man es entweder mit inkompetenten 
Idioten oder stark regulierten Märkten zu tun hat. Bei uns gibt es 
stattdessen mehrere Code-Reviews.

Marc V. schrieb:
>  Wie du nicht weisst, wird const ins Flash geschrieben, #define aber
>  ist einfach eine Anweisung für Präprozessor.

Auch "const" wird nicht ins Flash geschrieben, wenn es nicht ins Flash 
geschrieben werden muss. Stichwort Compiler-Optimierung.

Marc V. schrieb:
> So etwas kann man aber mit const nicht machen:
> const uint8_t c_DatBlkLen = 0x3F;  // 63 Byt max
> uint8_t   DatBlk[c_DatBlkLen];
> mit #define dagegen geht das ohne Probleme.

Auch das ist seit C99 schlicht falsch. Stichwort Variable Length Array.

Ein typischer Marc.

von Marc V. (Firma: Vescomp) (logarithmus)


Lesenswert?

A. S. schrieb:
> Das glaube ich Dir. Es wird nur noch einfacher, wenn Du Dir redundante
> defines sparst. Poste ein Beispiel und ich spendiere Dir eine Kiste
> Bier, wenn ich es ohne Redundanz nicht einfacher hinbekomme .

 Nein, umgekehrt.
 Ich spendiere dir eine Kiste Bier, wenn du mir die Redundanz in
 meinem Beitrag zeigst.

A. S. schrieb:
> Das sind aber 2 verschiedene Baustellen:
>
> Sinnvolle Namen statt Kommentare (darum ging es)

 Nun, so sehe ich das bestimmt nicht.
 Sinnvole Namen und Kommentare sowohl für Variablen, als auch
 innerhalb des Programms.

 Und es geht natürlich um Programme die länger als ein paar Zeilen
 sind, mehr als ein Dutzend Variablen haben und wesentlich komplizierter
 als BlinkLed Beispiel sind.
 Da sind mehrere Dutzend includes, mit mehreren Tausenden von Linien.
 Wenn man da etwas ändern muss und dazu erst die Routine xxyyzz finden
 muss, um zu sehen was diese Routine überhaupt tut, anstatt dies gleich
 aus Kommentar zu sehen oder vielleicht sogar aus dem Namen, z.B:
 PutDateTimeToI2C().
 Genauso ist es mit Variable xxyyzz.

 Das dies alles auch unter der Maus angezeigt wird, ändert nichts an
 der Sache.

von Dr. Sommer (Gast)


Lesenswert?

S. R. schrieb:
> Auch das ist seit C99 schlicht falsch. Stichwort Variable Length Array.

Die können aber nicht global/statisch sein. C++ hat übrigens echte 
Konstanten, die kann man auch für globale Arrays verwenden oder für 
die Definition weiterer Konstanten. Konstanten landen nicht 
notwendigerweise separat im Flash, die werden auch ggf. direkt in die 
Instruktionen kodiert. Allgemein braucht man in C++ sehr selten Makros, 
und das ist ein Vorteil...

von Marc V. (Firma: Vescomp) (logarithmus)


Lesenswert?

S. R. schrieb:
> Auch "const" wird nicht ins Flash geschrieben, wenn es nicht ins Flash
> geschrieben werden muss. Stichwort Compiler-Optimierung.

 Für mich bedeutet const eine readonly Variable, die demzufolge irgendwo
 im Flash abgelegt werden muss.
 Mit #define wird irgendetwas definiert, ob das ein Ausdruck, String
 oder schlicht ein Wert ist, ist absolut egal.

> Marc V. schrieb:
>> So etwas kann man aber mit const nicht machen:
>> const uint8_t c_DatBlkLen = 0x3F;  // 63 Byt max
>> uint8_t   DatBlk[c_DatBlkLen];
>> mit #define dagegen geht das ohne Probleme.
>
> Auch das ist seit C99 schlicht falsch. Stichwort Variable Length Array.

 Ahem.
 Kompiliere das mal bitte, so wie es da steht.
 Soviel ich und mein Compiler es wissen, geht das nur wenn man Array
 lokal deklariert, nicht aber wenn es global deklariert wird.

> Ein typischer Marc.
 Eher ein typischer svenska.

: Bearbeitet durch User
von Dr. Sommer (Gast)


Lesenswert?

Marc V. schrieb:
> Für mich bedeutet const eine readonly Variable, die demzufolge irgendwo
>  im Flash abgelegt werden muss.

Für dich vielleicht. Für z.B. den GCC aber nicht. Der merkt wenn sie 
nirgends verändert wird (typischerweise via "static const") und nimmt 
sie als fix an, und kodiert die Werte in die Immediates der 
Instruktionen direkt hinein.

Marc V. schrieb:
> Mit #define wird irgendetwas definiert, ob das ein Ausdruck, String oder
>  schlicht ein Wert ist, ist absolut egal.

Ja, eine dumme Textersetzung. Das ist ein sehr grobes Werkzeug, da kann 
man schnell mal daneben hauen...

von Tom (Gast)


Lesenswert?

Ich habe viel zu viel Zeit damit verbracht, Fehler zu finden, die 
dadurch getarnt waren, dass z.B. ein unsigned char u16BlaBlubb hieß, 
weil irgendein Profi früher beim Copy&Paste geschlampt hatte. Jahre 
später lief u16BlaBlubb aufgrund anderer Änderungen dann über, was laut 
Variablenname nicht sein konnte.

Die ungarischen Schniepel waren in dem Projekt "aus Sicherheitsgründen" 
vorgeschrieben. Gegen die Funktion mit 1000 Zeilen und 10 
verschachtelten Ebenen und die 20 unnötigerweise am Funktionsanfang auf 
Vorrat deklarierten Variablen, zwischen denen sich u16BlaBlubb versteckt 
hat, hatten die  Richtlinien natürlich nichts einzuwenden.

von Marc V. (Firma: Vescomp) (logarithmus)


Lesenswert?

Dr. Sommer schrieb:
> Marc V. schrieb:
>> Mit #define wird irgendetwas definiert, ob das ein Ausdruck, String oder
>>  schlicht ein Wert ist, ist absolut egal.
>
> Ja, eine dumme Textersetzung. Das ist ein sehr grobes Werkzeug, da kann
> man schnell mal daneben hauen...

 Stimmt, allerdings kann man an vielen Stellen in einem Programm ganz
 schnell daneben hauen...
 Der einzige Nachteil von #define ist meiner Meinung nach die fehlende
 Prüfung auf ev. Fehler, deswegen mag die definition von Makros
 fehlerträchtig sein, aber Deklarationen von einfachen Positionen im
 Buffer bestimmt nicht.

von A. S. (Gast)


Lesenswert?

Marc V. schrieb:
> Ich spendiere dir eine Kiste Bier, wenn du mir die Redundanz in
>  meinem Beitrag zeigst.

A. S. schrieb:
> wofür c_RcvAdr, wenn es nur offsetof RcvAdr ist? In den meisten fällen
> schreibt man doch eh X.RcvAdr. Und wenn man den Index braucht ...
> doppelt gemoppelt failed schneller.

Deshalb fragte ich fairer Weise nach einem sinnvollen Beispiel.

von Dr. Sommer (Gast)


Lesenswert?

Marc V. schrieb:
> Der einzige Nachteil von #define ist meiner Meinung nach die fehlende
>  Prüfung auf ev. Fehler

Das ist ein ziemlicher Nachteil. Dazu kommt dass die keinen Scope haben 
und dass man keine Pointer drauf bilden kann. Wenn man C++ nutzt gibt es 
keinen Grund diese Nachteile in Kauf zu nehmen; man nimmt einfach 
Konstanten und alles ist besser.

von S. R. (svenska)


Lesenswert?

Marc V. schrieb:
>> Auch "const" wird nicht ins Flash geschrieben, wenn es nicht ins Flash
>> geschrieben werden muss. Stichwort Compiler-Optimierung.
>
>  Für mich bedeutet const eine readonly Variable,
>  die demzufolge irgendwo im Flash abgelegt werden muss.

Das mag für dich so sein, der Compiler sieht das anders.

>> Marc V. schrieb:
>>> So etwas kann man aber mit const nicht machen:
>>> const uint8_t c_DatBlkLen = 0x3F;  // 63 Byt max
>>> uint8_t   DatBlk[c_DatBlkLen];
>>> mit #define dagegen geht das ohne Probleme.
>>
>> Auch das ist seit C99 schlicht falsch. Stichwort Variable Length Array.
>
>  Ahem.
>  Kompiliere das mal bitte, so wie es da steht.
1
$ cat test.c 
2
int main()
3
{
4
        const char x = 0x3F;
5
        char test[x];
6
7
        return 0;
8
}
9
$ gcc test.c
10
$ ./a.out 
11
$

Geht prima, wo ist dein Problem?

>  Soviel ich und mein Compiler es wissen, geht das nur wenn man Array
>  lokal deklariert, nicht aber wenn es global deklariert wird.

Dein geposteter Code enthält kein main(), lässt sich also nicht 
kompilieren. Ich habe mir nur die Freiheit genommen, eins einzubauen. 
:-)

>> Ein typischer Marc.
>  Eher ein typischer svenska.

Mir ging es darum, dich darauf hinzuweisen, dass deine beiden Aussagen 
maximal Halbwissen sind. Das stört vor allem, weil du immer in 
Absolutismen schreibst und selbstverständlich niemals Unrecht hast.

Ein "sowas kann man nicht machen" ist falsch, wenn man es eben doch 
meistens machen kann. Und mit Aussagen wie "wie du nicht weißt, gilt X" 
blamierst du dich vor allem dann, wenn X nicht uneingeschränkt gilt.

Und genau das ist typisch.
Damit wäre ich dann wieder raus, streitet euch mal weiter. :-)

von Marc V. (Firma: Vescomp) (logarithmus)


Lesenswert?

A. S. schrieb:
> A. S. schrieb:
>> wofür c_RcvAdr, wenn es nur offsetof RcvAdr ist? In den meisten fällen
>> schreibt man doch eh X.RcvAdr. Und wenn man den Index braucht ...
>> doppelt gemoppelt failed schneller.
>
> Deshalb fragte ich fairer Weise nach einem sinnvollen Beispiel.

Marc V. schrieb:
> Deswegen vielleicht:
> union {
>   USART_RAM sRam;
>   uint8_t sbuff[5 + c_DatBlkLen + 3];
> } Uart_un;
>  ?

 Falls ich:
1
 sbuff[offsetof(UartRam, CmdTyp)]
 anstatt:
1
 sbuff[c_CmdTyp]
 verwende, habe ich deutlich mehr an vielen Stellen zu schreiben.
 Deklarieren tue ich es dagegen nur einmal ;)

von A. S. (Gast)


Lesenswert?

Marc V. schrieb:
> falls ich: sbuff[offsetof(UartRam, CmdTyp)]  anstatt:  sbuff[c_CmdTyp]
> verwende, habe ich deutlich mehr an vielen Stellen zu schreiben.
>  Deklarieren tue ich es dagegen nur einmal ;)

Und warum nicht sRam.CmdTyp? Wie gesagt, Fetzen bringen wenig.

Zumal es trotzdem nicht rechtfertigt, Struktur und define parallel zu 
pflegen.

von Marc V. (Firma: Vescomp) (logarithmus)


Lesenswert?

S. R. schrieb:
>>  Ahem.
>>  Kompiliere das mal bitte, so wie es da steht.
> $ cat test.c
> int main()
> {
>         const char x = 0x3F;
>         char test[x];
>
>         return 0;
> }
> $ gcc test.c
> $ ./a.out
> $
>
> Geht prima, wo ist dein Problem?

 Sure.
 Und so ?
1
 const char x = 0x3F;
2
 char test[x];
3
int main()
4
{
5
//        const char x = 0x3F;
6
//        char test[x];
7
8
        return 0;
9
}

S. R. schrieb:
> Mir ging es darum, dich darauf hinzuweisen, dass deine beiden Aussagen
> maximal Halbwissen sind. Das stört vor allem, weil du immer in
> Absolutismen schreibst und selbstverständlich niemals Unrecht hast.

 Tja, eigentlich geht es mir so mit dir.

von Mark B. (markbrandis)


Lesenswert?

Joern DK7JB .. schrieb:
> Wie benennt ihr eure Variablen eindeutig in der Programmiersprache C
> damit eindeutig ist welcher Typ verwendet worden ist? Gibt es da eine
> bewährte Methode oder erfindet da jeder Programmierer das Rad neu?

Mir ist nicht ganz klar, wie man auf die Idee kommt, dass es sinnvoll 
wäre dies zu tun. Wie andere schon gesagt haben - jeder moderne Editor 
zeigt einem den Variablentyp an, wenn man z.B. kurz mit der Maus 
drübergeht.

Was immer sinnvoll ist, sind selbstsprechende Namen für Variablen und 
Funktionen. Man liest den Namen und schon weiß man um was es geht. 
Beispiele:

Vehicle_speed
RoomTemperature
TransmitBuffer[]

display_speed()
temperature_to_Fahrenheit()
isBufferFull()

von Marc V. (Firma: Vescomp) (logarithmus)


Lesenswert?

A. S. schrieb:
> Und warum nicht sRam.CmdTyp? Wie gesagt, Fetzen bringen wenig.

 Weil sbuff ein Array ist und da ist sbuff[c_CmdTyp] für mich
 irgendwie logischer.
 sRam ist eine Struktur, da passt sRam.CmdTyp schon.

> Zumal es trotzdem nicht rechtfertigt, Struktur und define parallel zu
> pflegen.

 Mag sein, aber die sind gleich untereinander deklariert, zusammen mit
 allen anderen Variablen fur RS485.
 Die Namen sind vielleicht nicht ganz passend gewählt, aber das ganze
 funktionert seit vielen Jahren so, warum jetzt ändern ?

von Rainer V. (a_zip)


Lesenswert?

S. R. schrieb:
> Ach was erzählst du da für einen Unsinn...
> Professionell heißt nur, dass man damit Geld verdient und sagt nichts
> über die Qualität aus. Eine wie auch immer geartete, "bindende
> Vorschrift, wie Programme geschrieben werden müssen" ist ein
> untrügliches Zeichen dafür, dass man es entweder mit inkompetenten
> Idioten oder stark regulierten Märkten zu tun hat. Bei uns gibt es
> stattdessen mehrere Code-Reviews.

Also seid ihr Klitsche nach meinem Verständniss! Und es sagt erst mal 
auch gar nichts über die (welche) Qualität aus, was wem möglicherweise 
vorgeschrieben wird. Aber wenn mehr als 2 Mann/Frau an einer Software 
basteln, dann sind nicht nur die Übergabeparameter festgeschrieben, 
sondern auch der Stil der Programmierarbeit überhaupt! Wenn ich von 
einem Fuzzi 3 Mal in der Woche Module bekomme, die Fehler erzeugen, dann 
schau ich doch mal in dessen Quellcode und wehe, der ist anders als im 
Pflichtenheft geschrieben!
Und bitte verzeih', "Code-Review" hört sich für mich an wie 
"Therapeutensitzung"
Und klar heisst professionell, dass man Geld verdient...was sonst?
Gruß Rainer

von Sven B. (scummos)


Lesenswert?

Rainer V. schrieb:
> S. R. schrieb:
> Bei uns gibt es
>> stattdessen mehrere Code-Reviews.
>
> Also seid ihr Klitsche nach meinem Verständniss! Und es sagt erst mal
> auch gar nichts über die (welche) Qualität aus, was wem möglicherweise
> vorgeschrieben wird. Aber wenn mehr als 2 Mann/Frau an einer Software
> basteln, dann sind nicht nur die Übergabeparameter festgeschrieben,
> sondern auch der Stil der Programmierarbeit überhaupt! Wenn ich von
> einem Fuzzi 3 Mal in der Woche Module bekomme, die Fehler erzeugen, dann
> schau ich doch mal in dessen Quellcode und wehe, der ist anders als im
> Pflichtenheft geschrieben!
> Und bitte verzeih', "Code-Review" hört sich für mich an wie
> "Therapeutensitzung"

Genau! Bäm! Du Noob! Ich Profi! Überhaupt sind nur Leute mit 
Pflichtenheft Profis! Und Leute mit anderen etablierten Verfahren, wie 
Reviews, sind Noobs, weil ich als Profi das nicht mache und deshalb kann 
das gar nicht professionell sein!

Mehrere verschiedene Möglichkeiten, professionell zu arbeiten, sind 
grundsätzlich nicht vorstellbar: sonst ist das Feld der Professionalität 
ja vielleicht gar nicht total geordnet, und dann kann ich gar nicht ganz 
oben in der Hackordnung stehen.

Wie gesagt, dieses Muster ist hier im Forum echt typisch und es hat noch 
nie zu einer gewinnbringenden Diskussion geführt, ever. Es nervt nur 
alle: die Beteiligten und die Leser gleichermaßen.

In der Softwareentwicklung ist das besonders krass, weil es ohne 
Übertreibung hunderte solcher Vorgaben gibt, die von weiten Kreisen als 
ein absolutes Muss gehandelt sind, anderen hingegen völlig unbekannt 
sind. Deshalb kann man sich da trefflich stundenlang anmaulen, wer der 
größere Noob ist weil er keine Versionskontrolle // keine Reviews // 
kein Pflichtenheft // keine Style Guide // keine 
Dokumentations-Guideline // kein Scrum // kein whaaatever macht. 
Projekte wie der Code für die Mondrakete beweisen aber z.B., dass man 
sehr wohl ohne Versionskontrollsystem gute Software entwickeln kann ...
Man wird hier nicht dadurch zum Profi, dass man möglichst viele Punkte 
auf der Buzzword-Liste abhakt. Weniger ist manchmal sogar mehr.

: Bearbeitet durch User
von Rolf M. (rmagnus)


Lesenswert?

S. R. schrieb:
> Marc V. schrieb:
>>  Wie du nicht weisst, wird const ins Flash geschrieben, #define aber
>>  ist einfach eine Anweisung für Präprozessor.
>
> Auch "const" wird nicht ins Flash geschrieben, wenn es nicht ins Flash
> geschrieben werden muss. Stichwort Compiler-Optimierung.

Das geht aber nur, wenn es static ist. Sonst muss sie im Flash stehen, 
da eine andere Übersetzungeinheit sie referenzieren könnte.

> Marc V. schrieb:
>> So etwas kann man aber mit const nicht machen:
>> const uint8_t c_DatBlkLen = 0x3F;  // 63 Byt max
>> uint8_t   DatBlk[c_DatBlkLen];
>> mit #define dagegen geht das ohne Probleme.
>
> Auch das ist seit C99 schlicht falsch. Stichwort Variable Length Array.

Die gibt es aber aus offensichtlichen Gründen nur bei lokalen Variablen.

Tatsächlich gibt es in C gar keine echten Konstanten. #define ist die 
beste Annäherung daran. Deshalb wird es auch so oft dafür verwendet. Ein 
const int ist keine Konstante, sondern eine Variable, die man nicht 
ändern darf. Und ja, das macht einen Unterschied. Beispiel:
1
const int a = 0;
2
const int b = a;

Das führt in gcc zu folgendem Fehler:
1
const2.c:20:15: error: initializer element is not constant
2
 const int b = a;
3
               ^

von Rainer V. (a_zip)


Lesenswert?

Sven B. schrieb:
> Genau! Bäm! Du Noob! Ich Profi! Überhaupt sind nur Leute mit
> Pflichtenheft Profis!

Mann, dich in einem Vorstellungsgespräch...göttlich...
und Betriebssystem "Hello World"...
Kleiner Mann mit peinlich kleinem Hut...
Rainer

von Jörg W. (dl8dtl) (Moderator) Benutzerseite


Lesenswert?

Rainer V. schrieb:
> Mann, dich in einem Vorstellungsgespräch...göttlich...

Hmm, meinst du, es wäre besser, dir in einem Vorstellungsgespräch 
gegenüber zu sitzen?

Wenn ich es mir aussuchen kann, würde ich wohl Sven jederzeit den Vorzug 
geben. Leute mit Dogma mag ich nicht (weder als Chef noch als 
Mitarbeiter).

Ich habe schon an so vielen verschiedenen Projekten mitgearbeitet, dass 
ich mir die Flexibilität leisten muss, nicht auf einen coding style 
festgefahren zu sein. Auch ohne geschriebene coding guides kann man 
konsistenten Code produzieren, wenn man nur will. („Ungarische“ Notation 
war aber, von paar Win32-Syscalls in AVRDUDE abgesehen, bislang zum 
Glück noch nicht dabei.)

von Mark B. (markbrandis)


Lesenswert?

Sven B. schrieb:
> Projekte wie der Code für die Mondrakete beweisen aber z.B., dass man
> sehr wohl ohne Versionskontrollsystem gute Software entwickeln kann ...
> Man wird hier nicht dadurch zum Profi, dass man möglichst viele Punkte
> auf der Buzzword-Liste abhakt. Weniger ist manchmal sogar mehr.

Na ja, heutzutage kann man tatsächlich nicht mehr professionell ohne 
Versionskontrolle entwickeln. Alleine schon wenn man gegenüber dem 
Gutachter reproduzierbar nachweisen muss, welcher SW-Stand wann wie zur 
Zulassung gebracht werden soll oder wenn man eben Änderungen 
(nach-)dokumentieren muss.

Gehört nicht ohne Grund zum "Joel Test" ;-)

https://www.joelonsoftware.com/2000/08/09/the-joel-test-12-steps-to-better-code/

von Axel S. (a-za-z0-9)


Lesenswert?

Rolf M. schrieb:
>> Auch "const" wird nicht ins Flash geschrieben, wenn es nicht ins Flash
>> geschrieben werden muss. Stichwort Compiler-Optimierung.
>
> Das geht aber nur, wenn es static ist. Sonst muss sie im Flash stehen,
> da eine andere Übersetzungeinheit sie referenzieren könnte.

In der Theorie ja. In der Praxis gibt es auch link-time-optimization 
(gcc: -flto). Damit funktionieren solche Optimierungen auch über die 
Grenzen von Übersetzungseinheiten hinweg.

von Marc V. (Firma: Vescomp) (logarithmus)


Lesenswert?

Axel S. schrieb:
>> Das geht aber nur, wenn es static ist. Sonst muss sie im Flash stehen,
>> da eine andere Übersetzungeinheit sie referenzieren könnte.
>
> In der Theorie ja. In der Praxis gibt es auch link-time-optimization
> (gcc: -flto). Damit funktionieren solche Optimierungen auch über die
> Grenzen von Übersetzungseinheiten hinweg.

 Mit switches kann man vieles anders machen und verdrehen, fragt sich
 nur ob das auch sinnvoll ist.
 Bei einem Teamprojekt steht der switch bei einem Kollegen so, bei
 anderen wiederum anders und schon werden aus selbem Code 4 verschiedene
 Versionen kompiliert - bei einem funktioniert es, bei anderem (der
 zufälligerweise gerade seine Routine geändert hat) nicht und dann
 geht die Sucherei los...

: Bearbeitet durch User
von mh (Gast)


Lesenswert?

Marc V. schrieb:
> Axel S. schrieb:
>>> Das geht aber nur, wenn es static ist. Sonst muss sie im Flash stehen,
>>> da eine andere Übersetzungeinheit sie referenzieren könnte.
>>
>> In der Theorie ja. In der Praxis gibt es auch link-time-optimization
>> (gcc: -flto). Damit funktionieren solche Optimierungen auch über die
>> Grenzen von Übersetzungseinheiten hinweg.
>
>  Mit switches kann man vieles anders machen und verdrehen, fragt sich
>  nur ob das auch sinnvoll ist.
>  Bei einem Teamprojekt steht der switch bei einem Kollegen so, bei
>  anderen wiederum anders und schon werden aus selbem Code 4 verschiedene
>  Versionen kompiliert...

Ernsthaft? Etwas überspitzt gefragt: Redet ihr in diesem "Team" auch 
miteinander? Es gibt Dinge die sollte man im Team festlegen.

von Dr. Sommer (Gast)


Lesenswert?

Marc V. schrieb:
> Bei einem Teamprojekt steht der switch bei einem Kollegen so, bei
>  anderen wiederum anders

Die Switches sollten im Makefile, IDE-Projekt o.ä. stehen und daher bei 
allen gleich sein. Ein Grund, Projektdateien eben doch in der 
Versionskontrolle einzuchecken, was IMO unberechtigterweise so verpönt 
ist.

von mh (Gast)


Lesenswert?

Dr. Sommer schrieb:
> Marc V. schrieb:
>> Bei einem Teamprojekt steht der switch bei einem Kollegen so, bei
>>  anderen wiederum anders
>
> Die Switches sollten im Makefile, IDE-Projekt o.ä. stehen und daher bei
> allen gleich sein. Ein Grund, Projektdateien eben doch in der
> Versionskontrolle einzuchecken, was IMO unberechtigterweise so verpönt
> ist.

Wie genau meinst du das? Ist die Versionskontrolle allgemein oder 
Projektdateien im VCS verpönt?

von Dr. Sommer (Gast)


Lesenswert?

PS: Der Code sollte natürlich bei allen Compiler-Switches korrekt 
funktionieren (außer bei solchen welche die Standard-Konformität 
beeinflussen wie -std=gnu99 oder -ffast-math), aber optimale Ergebnisse 
darf man ohne die richtigen Optimierungen nicht erwarten. Und in C++ ist 
das alles wie gesagt sowieso kein Problem, weil das Konstanten echt 
konstant sind.

von Dr. Sommer (Gast)


Lesenswert?

mh schrieb:
> Wie genau meinst du das? Ist die Versionskontrolle allgemein oder
> Projektdateien im VCS verpönt?

Projektdateien im VCS einchecken ist verpönt. Wenn die Projekdateien 
keine absoluten Pfade o.ä. nutzen ist das aber IMO völlig in Ordnung. 
Selbst wenn ein Teammitglied unbedingt eine andere IDE nutzen möchte 
(was bei manchen Embedded Plattformen sowieso nicht geht, weil es nur 1 
IDE dafür gibt), hat man so immerhin ein "Referenz"-Setup an welches man 
sich halten kann. Insbesondere bei Embedded-Plattformen kann das Anlegen 
& Konfigurieren von Projekten ziemlich kompliziert sein - da spart das 
Einchecken der Projektdatei eine Menge Arbeit.

von Marc V. (Firma: Vescomp) (logarithmus)


Lesenswert?

mh schrieb:
> Ernsthaft?
 Natürlich,

> Etwas überspitzt gefragt: Redet ihr in diesem "Team" auch
> miteinander?
 Ja, wir reden miteinander.

> Es gibt Dinge die sollte man im Team festlegen.
 Und es gibt Dinge, die soll man nicht mit Gewalt und ohne Grund
 ändern, nur damit man beweist, dass irgendein Beitrag in uC.net
 nicht stimmt.
 So etwas nennt sich Korinthenkackerei und es gibt ein paar
 Leute hier, die genau das immer wieder tun, nur um zu beweisen
 wie klug und allwissend sie sind und wie unwissend die
 anderen.

 Dass das genau nichts zum Thema beiträgt und dem TO in keiner
 Weise hilft, berührt diese Experten überhaupt nicht, Hauptsache
 die anderen werden als unwissend/halbwissend dargestellt...

 P.S.
 Aussage:
 Mercedes ist ein verkehrssicheres Fahrzeug.

 Behauptung:
 Ja, aber wenn man die Reifen auf 0,5 bar aufpumpt und dann mit
 200Km/h auf der Autobahn fährt, stimmt das überhaupt nicht...

 Schlussfolgerung:
 Die obige Aussage ist falsch und derjenige der das behauptet,
 hat überhaupt keine Ahnung von Fahrzeugen und fahren.

: Bearbeitet durch User
von W.S. (Gast)


Lesenswert?

Egon D. schrieb:
> Es ist sehr sinnvoll, nur häufig auftretende Problemfälle
> durch explizit formulierte Regeln zu beseitigen. Andernfalls
> löst man eben Probleme, die sich gar nicht stellen -- dafür
> gibt es das schöne Wort "Überregulation".

Dieses schöne Wort heißt in der Mechanik und woanders "Überbestimmt" und 
ist ein Designfehler. Aber hier handelt es sich gar nicht darum, sondern 
es handelt sich um Vollständigkeit. Das ist was grundlegend Anderes.

Und wenn du "nur häufig auftretende Problemfälle" mit Regeln versiehst, 
was ist dann deine Regel wert? Garnichts. Entweder ist eine Regel eine 
Regel oder sie ist nur heiße Luft - und sollte deshalb schlichtweg 
ignoriert werden.


>> const int c_i_echt_ottokar = 4711;
>
> Das ist ja wohl eine perverse (="verdrehte") Weltsicht.
> Das, was Du als "echte Konstante" bezeichnest, ist
> technisch eine vorbelegte Variable.

Du redes Unsinn. Das Obengenannte ist eine Konstante. Und zwar eine 
echte, die bei einem µC im Flash landet. Im Gegensatz dazu ist alles, 
was man per #define macht, eine Textersetzung. Und das was man mit 
typedef macht, ist ein Alias.

Versuche du erstmal das logische Denken und das Verwenden korrekter 
Wörter zu erlernen, bevor du hier große Töne redest.

W.S.

von Dr. Sommer (Gast)


Lesenswert?

W.S. schrieb:
> Du redes Unsinn. Das Obengenannte ist eine Konstante. Und zwar eine
> echte, die bei einem µC im Flash landet.

Nein. Wozu haben wir das gerade diskutiert? Lesen bildet!

von Jörg W. (dl8dtl) (Moderator) Benutzerseite


Lesenswert?

W.S. schrieb:

>> Das ist ja wohl eine perverse (="verdrehte") Weltsicht.
>> Das, was Du als "echte Konstante" bezeichnest, ist
>> technisch eine vorbelegte Variable.
>
> Du redes Unsinn. Das Obengenannte ist eine Konstante.

Nein, ist es technisch gesehen nicht. C kennt in diesem Sinne keine 
Konstanten, es ist eine Variable, bei dem Versuche, ihren Wert zur 
Laufzeit zu ändern, vom Compiler abgewiesen werden.

C++ kennt echte Konstanten, deshalb darf man sowas dort auch zur 
Definition der Größe eines (beliebigen) Arrays benutzen, was man in C 
nicht darf:
1
$ cat > foo.c
2
const int a = 42;
3
int b[a];
4
^D
5
$ gcc -xc++ -c foo.c
6
$ gcc -xc -c foo.c
7
foo.c:2:5: error: variably modified ‘b’ at file scope
8
 int b[a];
9
     ^

> Und zwar eine
> echte, die bei einem µC im Flash landet.

Primär landet bei einem µC natürlich alles im Flash. Aber obige 
Definition besagt noch lange nicht, dass für das Datum explizit Flash 
reserviert wird. Der Wert kann genauso gut als Direktwert in einen 
Operanden gepackt werden, oder der Compiler benutzt dafür ein Register, 
von welchem er weiß, dass dort genau dieser Wert gerade drin steht.

> Im Gegensatz dazu ist alles,
> was man per #define macht, eine Textersetzung.

Das hat keiner in Frage gestellt.

von W.S. (Gast)


Lesenswert?

Jörg W. schrieb:
> Nein, ist es technisch gesehen nicht. C kennt in diesem Sinne keine
> Konstanten, es ist eine Variable, bei dem Versuche, ihren Wert zur
> Laufzeit zu ändern, vom Compiler abgewiesen werden.

Jörg, das mag am PC drin sein, schließlich kennt Pascal solche 
"typisierten Konstanten" ja auch - und am PC liegt schlichtweg alles 
im RAM, weswegen man bei Pascal auf sowas sogar schreibend zugreifen 
kann, wenn man das tatsächlich will.

Aber bei allen Mikrocontrollern, die ich kenne, landet so eine 
"Variable" tatsächlich im Flash und das war's.

Es ist technisch gesehen, eine hart in Silizium gegossene Variable, die 
dadurch zu einer echten Konstanten wird, weil sie als "Ding" wirklich 
existiert und weil wirklich jeder Schreibversuch zum Fault oder zu nix 
führt - auch wenn da kein Compiler meckern würde.

Ich habe sowas reichlich in den USB-Treibern, siehe:

const byte DeviceDescriptor[] =
{ ....

Nochmal:
Wenn jemand schreibt
#define joerg 99
 X = joerg + Y;

dann wird in den allermeisten Fällen "joerg" niemals in der Firmware 
tatsächlich auftauchen, sondern als Teil eines Maschinenbefehls zu Y 
addiert werden.

Wenn jeman aber
const int joerg = 99;
schreibt, dann gibt es mit Sicherheit innerhalb der Firmware eine 
zumindest 16 bittige Zahl mit dem Wert 99. Und die kann adressiert 
werden wie alle anderen Dinge.

Der Knackpunkt liegt darauf, daß ein #define überhaupt keine Konstante 
erzeugt, sondern eine schlichte Textersetzung macht. Der Compiler kriegt 
davon nur die finale Zahl mit.

W.S.

von Dr. Sommer (Gast)


Lesenswert?

W.S. schrieb:
> Aber bei allen Mikrocontrollern, die ich kenne, landet so eine
> "Variable" tatsächlich im Flash und das war's.

Dann probier doch mal einen STM32F103 aus.

Aus
1
#include <stdint.h>
2
3
static volatile uint32_t * const GPIOA_BSRR = ((volatile uint32_t*) 0x40010810);
4
static const uint8_t iPin = 3;
5
6
void setPin () {
7
  *GPIOA_BSRR = (1 << iPin);
8
}
macht der GCC hier
1
00000000 <setPin>:
2
   0:  f44f 6301   mov.w  r3, #2064  ; 0x810
3
   4:  2208        movs  r2, #8
4
   6:  f2c4 0301   movt  r3, #16385  ; 0x4001
5
   a:  601a        str  r2, [r3, #0]
6
   c:  4770        bx  lr
7
   e:  bf00        nop
Da ist nirgendwo eine adressierbare Konstante. Sowohl Adresse als auch 
Bitmaske landen direkt als Immediates in den Instruktionen. Genau so 
als hätte man ein Makro verwendet. Nur hat man so die diversen Nachteile 
des Makros vermieden.

Der Code wurde mit -Os -mpure-code kompiliert. Letzteres ist nötig, um 
dem GCC eine andere Optimierung abzugewöhnen, bei welcher er Literal 
Pools nutzt; der gezeigte Assembler-Code ist schneller aber größer als 
ohne diese Option. Zu Demonstrationszwecken ist es aber hier 
interessant, die Version ohne Literal Pool zu sehen.

von Yalu X. (yalu) (Moderator)


Lesenswert?

@ Teilnehmer der Konstantendiskussion:

Ihr redet teilweise aneinander vorbei, weil ihr nicht dazuschreibt,
über welche Sorte von Konstanten ihr redet. In der Softwaretechnik
lässt sich der Konstantenbegriff in (mindestens) vier Kategorien
unterteilen:

- Literale (literals)
- Compilezeit-Konstanten (compile-time constants)
- Compilezeit-konstante Ausdrücke (compile-time constant expressions)
- Nichtüberschreibbare Variablen (immutable variables, Obermenge der
  Compilezeit-Konstanten)

Zusätzlich kann man Konstanten jeder dieser drei Kategorien in C per
Makrodefinition neue Namen geben, die damit ebenfalls Konstanten der
jeweiligen Kategorie repräsentieren.

In der Mathematik, von wo der Begriff "Konstante" entlehnt wurde, wird
er nochmals etwas anders genutzt, ebenso in der Physik. Da viele
Softwareentwickler einen mathematischen und/oder physikalischen
Hintergrund haben, wird der Begriff oft auch in diesen Bedeutungen
verwendet.

Wenn ein Softwareentwickler also einfach nur "Konstante" sagt, können
damit sieben verschiedene Dinge gemeint sein. In 6/7 aller Fälle muss
eine Diskussion zwischen zwei Softwareentwicklern in einem Internet-
forum über Konstanten deswegen unweigerlich zu einem nicht konstanten,
sondern eskalierenden Streit führen ;-)

: Bearbeitet durch Moderator
von Jörg W. (dl8dtl) (Moderator) Benutzerseite


Lesenswert?

W.S. schrieb:
> const byte DeviceDescriptor[] =

Erstens ist ein Array schon mal was ganz anderes, zweitens hast du auch 
hier zumindest bei einer recht prominenten µC-Architektur unrecht: da 
der AVR für Operationen aus dem Flash andere Befehle braucht als für 
Operationen aus dem RAM, werden selbst string literals (die schon seit 
C89 "immutable" waren) dort im RAM untergebracht und nur aus dem Flash 
initialisiert. Normale Arrays oder structs werden ebenfalls im RAM 
untergebracht, auch wenn sie "const" markiert sind. Der Compiler wirft 
das zwar in die section ".rodata":
1
$ cat foo.c
2
const struct {
3
  int a;
4
  char *b;
5
} foo = { 
6
  .a = 42,
7
  .b = "hi"
8
};
9
$ avr-gcc -Os -S foo.c
10
$ cat foo.s
11
        .file   "foo.c"
12
__SP_H__ = 0x3e
13
__SP_L__ = 0x3d
14
__SREG__ = 0x3f
15
__tmp_reg__ = 0
16
__zero_reg__ = 1
17
.global foo
18
        .section        .rodata.str1.1,"aMS",@progbits,1
19
.LC0:
20
        .string "hi"
21
        .section        .rodata
22
        .type   foo, @object
23
        .size   foo, 4
24
foo:
25
        .word   42
26
        .word   .LC0
27
        .ident  "GCC: (GNU) 5.4.0"
28
.global __do_copy_data

… aber dem Linker bleibt nichts anderes übrig, als das dann in den RAM 
zu packen und aus dem Flash zu initialisieren:
1
$ avr-gcc -mmcu=atmega328 -Wl,--defsym=main=0 -o foo.elf foo.s
2
$ avr-nm foo.elf
3
4
5
00800100 D foo

(Adressen ab 0x800000 werden bei der AVR-GCC-Tolchain als RAM behandelt, 
Flash ist ab 0.)

So pauschal, wie du das behauptest, passt es eben nicht. Von 
Fachbegriffen sehen wir mal ganz ab („Verwenden korrekter Wörter“), denn 
spätestens beim C-Standard wirst du dich ziemlich schnell auf 
ungewolltes Glatteis begeben …

: Bearbeitet durch Moderator
von Jörg W. (dl8dtl) (Moderator) Benutzerseite


Lesenswert?

Yalu X. schrieb:
> In 6/7 aller Fälle muss
> eine Diskussion zwischen zwei Softwareentwicklern in einem Internet-
> forum über Konstanten deswegen unweigerlich zu einem nicht konstanten,
> sondern eskalierenden Streit führen ;-)

:-))

von HyperMario (Gast)


Lesenswert?

Joern DK7JB .. schrieb:
> Wie benennt ihr eure Variablen eindeutig in der Programmiersprache C
> damit eindeutig ist welcher Typ verwendet worden ist? Gibt es da eine
> bewährte Methode oder erfindet da jeder Programmierer das Rad neu?

Ungarische Notation, war lange bei Microsoft Hausideologie mit dem 
bekannten Ergebnis. Seit Sie das lassen scheint es besser zu laufen, 
kann aber auch Zufall sein. Auf jeden Fall hat es nichts gebracht.

Hab ich auch eine Zeitlang gemacht weil Anfänger. Inzwischen lasse ich 
es, kostet unnötig Gehirnschmalz und Zeit und lenktab. Zusätzlich wird 
die Software überdefinert was Änderungen erschwert.

Zum lernen aber war es Klasse. Hat das Typenproblem bei mir besser 
eingebrannt. Kann jedem empfehlen ungarisch anzufangen und es sein zu 
lassen wenn man C besser kann.

von Egon D. (Gast)


Lesenswert?

W.S. schrieb:

>>> const int c_i_echt_ottokar = 4711;
>>
>> Das ist ja wohl eine perverse (="verdrehte") Weltsicht.
>> Das, was Du als "echte Konstante" bezeichnest, ist
>> technisch eine vorbelegte Variable.
>
> Du redes Unsinn.

Das mag der Ungebildete so sehen...


> Das Obengenannte ist eine Konstante.

Du hast Schwierigkeiten mit der Exaktheit, kann das sein?

Ich habe nicht bestritten, dass das eine Konstante ist.
Ich habe darüber gespottet, dass Du das einzige, was
technisch nicht zwingend eine Konstante, sondern eine
vorbelegte Variable ist, als "echte Konstante" bezeichnest.


> Und zwar eine echte, die bei einem µC im Flash landet.

Variablen, vorbelegte Variablen und Konstanten gibt es
schon wesentlich länger als Flash-Speicher; das, was Du
versuchst, ist ein Anachronismus.


> Im Gegensatz dazu ist alles, was man per #define macht,
> eine Textersetzung.

Richtig. Und deshalb sind die Sprachelemente, die davon
betroffen sind, zur Laufzeit GARANTIERT konstant -- was
man von vorbelegten Variablen nicht behaupten kann.


> Versuche du erstmal das logische Denken und das Verwenden
> korrekter Wörter zu erlernen, bevor du hier große Töne
> redest.

Das gebe ich gern zurück und ergänze: Versuche, auf das
Herabsetzen Deines Kontrahenten zu verzichten -- es schadet
Dir selbst mehr als ihm.

von Axel S. (a-za-z0-9)


Lesenswert?

HyperMario schrieb:
> Ungarische Notation
...
> Hab ich auch eine Zeitlang gemacht weil Anfänger
...
> Zum lernen aber war es Klasse. Hat das Typenproblem bei mir besser
> eingebrannt. Kann jedem empfehlen ungarisch anzufangen und es sein zu
> lassen wenn man C besser kann.

Au weia. Ist das die masochistische Extremversion von "Lernen durch 
Schmerz"? Klar lernt man Sachen besonders nachhaltig, wenn der Irrtum 
mit Schmerzen verbunden war. Aber ich würde nicht so weit gehen, 
Schmerzen als unabdingbar für einen Lerneffekt anzusehen.

von S. R. (svenska)


Lesenswert?

mh schrieb:
>>  Mit switches kann man vieles anders machen und verdrehen, fragt sich
>>  nur ob das auch sinnvoll ist.
>
> Ernsthaft? Etwas überspitzt gefragt: Redet ihr in diesem "Team" auch
> miteinander? Es gibt Dinge die sollte man im Team festlegen.

Nein, das sind nur rhetorische Tricks, um nicht feststellen zu müssen, 
dass die Welt ein bisschen komplizierter ist. Genauso wie das hier:

Marc V. schrieb:
> Aussage:
>  Mercedes ist ein verkehrssicheres Fahrzeug.
>
>  Behauptung:
>  Ja, aber wenn man die Reifen auf 0,5 bar aufpumpt und dann mit
>  200Km/h auf der Autobahn fährt, stimmt das überhaupt nicht...
>
>  Schlussfolgerung:
>  Die obige Aussage ist falsch und derjenige der das behauptet,
>  hat überhaupt keine Ahnung von Fahrzeugen und fahren.

Der erste Teil der Schlussfolgerung ist richtig.
Der zweite Teil ist Unsinn zur Ablenkung.

Eine wunderschöne rhetorische Figur, inhaltlich ist der Pfeil leider an 
der Dartscheibe vorbeigeflogen, aber es sollte ja nur zeigen, dass ... 
was eigentlich?

Ein typischer Marc eben.

von Rolf M. (rmagnus)


Lesenswert?

Axel S. schrieb:
> Au weia. Ist das die masochistische Extremversion von "Lernen durch
> Schmerz"? Klar lernt man Sachen besonders nachhaltig, wenn der Irrtum
> mit Schmerzen verbunden war. Aber ich würde nicht so weit gehen,
> Schmerzen als unabdingbar für einen Lerneffekt anzusehen.

Es gibt ja Dinge, von denen behauptet wird, dass man sie mal selber 
falsch gemacht haben muss, um wirklich zu verstehen, warum es falsch 
ist.
Ist wie mit dem Kind, dem auch erst dann wirklich klar wird, warum es 
vom Herd wegbleiben soll, wenn es sich mal die Finger an der Herdplatte 
verbrannt hat.
Ob das jetzt für die Microsoft'sche ungarische Notation auch gilt, sei 
aber mal dahingestellt. Ich hab noch nie verstanden, wozu das gut sein 
soll und es deshalb auch noch nie benutzt.

von Walter T. (nicolas)


Lesenswert?

Frage an die Profis von einem reinen Hobbyisten: Redet ihr bei den 
Namenskonventionen von den im Verhältnis wenigen globalen Variablen, 
oder wendet ihr das auch auf lokale Variablen an?

Eigentlich sind bei mir gefühlt 95% der Funktionen kürzer als zwei 
Fensterhöhen, dass der komplette Scope jeder Variablen fast immer 
komplett sichtbar ist. Und dann beschränke ich mich meist auf einfache, 
kurze und sprechende Namen.

(Damit ist dann 'g' mein einziger echter Präfix, nämlich für globale 
Variablen.  Ansonsten halt Abkürzungen nObj, iObj etc., aber das sind ja 
keine echten Präfixe, sondern Namensteile.)

: Bearbeitet durch User
von Rolf M. (rmagnus)


Lesenswert?

Walter T. schrieb:
> Frage an die Profis von einem reinen Hobbyisten: Redet ihr bei den
> Namenskonventionen von den im Verhältnis wenigen globalen Variablen,
> oder wendet ihr das auch auf lokale Variablen an?
>
> Eigentlich sind bei mir gefühlt 95% der Funktionen kürzer als zwei
> Fensterhöhen, dass der komplette Scope jeder Variablen fast immer
> komplett sichtbar ist. Und dann beschränke ich mich meist auf einfache,
> kurze und sprechende Namen.

Ich gehe nach dem Prinzip vor: Je größer der Scope, desto 
aussagekräftiger sollten die Namen sein.

> (Damit ist dann 'g' mein einziger echter Präfix, nämlich für globale
> Variablen.

Bei mir gehören globale Variablen - so sie denn existieren - zu einem 
bestimmten Modul, und dann ist der Name des Moduls der Präfix.

von Jörg W. (dl8dtl) (Moderator) Benutzerseite


Lesenswert?

Rolf M. schrieb:
> Ich gehe nach dem Prinzip vor: Je größer der Scope, desto
> aussagekräftiger sollten die Namen sein.

Hier auch so. Eine strikte Regulierung von Namen haben wir nicht. Die 
gängige Konvention, dass Makronamen (zumindest eigene, nicht aus fremdem 
Code "geerbte") GROSS geschrieben werden, wird jedoch eingehalten.

Namenspräfixe für globale Namen (sowohl Variablen als auch Funktionen) 
werden vorzugsweise nach Subsystem vergeben, damit deren Namen nicht mit 
normalem Anwendercode (der diese Subsysteme natürlich kennt) kollidieren 
können.  Für modulinterne Namen ist das nicht notwendig, die können 
keine Namenskollision verursachen.

Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.