Peter II schrieb:> das ist zum schluss eine funktion
Naja... es hat nur den selben Effekt wie die von dir aufgeschriebene
Funktion.
In der Realität werden Makros vom Preprozessor textuell ersetzt.
entiwckler schrieb:> Die ADDRESS ist niergends im Projekt definiert.
Doch: es ist der formale Parameter des Makros selbst.
Du solltest dir ein gutes Buch über C zulegen und die Grundlagen
lernen.
Nö.
Ist nicht notwendig.
return ist ja kein Funktionsaufruf.
Und die Syntax sagt, dass nach dem Return eine Expression kommt.
Du schreibst ja auch nicht
i = (5);
also warum sollst du dann
return (5);
schreiben müssen.
return 5;
ist fein.
Entschuldige, die Argumentation verstehe ich jetzt nicht ganz und bitte
um Erklärung :).
1
return5;
ist ja, wie
1
i=5;
auch, klar.
"ADDRESS <= 0x20" ist ja aber ein Ausdruck und das Ergebnis des
Ausdrucks wollen wir zurückgeben.
Folglich schreibe ich
1
return(ADDRESS<=0x20);
Ich würde ja auch nicht schreiben:
1
i=ADDRESS<=0x20;
sondern
1
i=(ADDRESS<=0x20);
---------------------------------------------------------
Ok... gerade mal noch gegoogelt.
Alles was nach return kommt wird IMMER als Ausruck gewertet, ja?
Ich werde wohl trotzdem bei den Klammern bleiben wenn es ein Ausdruck
ist.
Gewohnheit, gefällt mir besser und selbst der dümmste Compiler kommt
nicht auf die Idee irgendwann mal nur ADDRESS zu "returnen" :)
Dominik S. schrieb:> Alles was nach return kommt wird IMMER als Ausruck gewertet, ja?
Richtig, das war in C schon immer so.
> Gewohnheit, gefällt mir besser
Dagegen ist nichts einzuwenden.
> und selbst der dümmste Compiler kommt> nicht auf die Idee irgendwann mal nur ADDRESS zu "returnen" :)
Wie sollte er auch? Es steht ja nicht ADDRESS dort. Falls er
wirklich saublöd wäre und noch nie etwas von der Sprache C gehört
haben sollte, dann könnte er bestenfalls auf die Idee kommen, dass
das ein Syntaxfehler wäre, wenn die Klammern da nicht stehen, aber
nur ADDRESS zurückzugeben geht nicht, denn was sollte dann mit den
restlichen Tokens dieser Zeile passieren? Ignorieren?
Es ist rein Geschmackssache, ob man da Klammern schreibt. Ich
selbst mache es nie, aber ich schreibe auch bei
1
#if FOO == 42 && BAR < 13
keine, da ich mir gemerkt habe, dass die Operatorenreihenfolge in
C vorsätzlich so gewählt worden ist, dass das so funktioniert, wie
man es erwarten würde (anders als bei Pascal).
Dominik S. schrieb:> "ADDRESS <= 0x20" ist ja aber ein Ausdruck und das Ergebnis des> Ausdrucks wollen wir zurückgeben.
Auch 5 ist nichts anderes als ein Ausdruck. Genauso wie i oder i + 5
oder ...
return 5;
return i;
return i + 5;
> return (ADDRESS <= 0x20);
Auch ADRESSE <= 0x20 ist nichts anderes als ein Ausdruck!
In C gibt es keine Unterscheidung zwischen arithmetischen und logischen
Ausdrücken. Ausdruck ist Ausdruck. Und der liefert einen Wert.
j = ( i > 5 ) * 8;
ist perfektes C.
Wir sind halt gewohnt, den 'Ausdruck' in einem if
if( Bedingung )
als etwas besonderes zu sehen, weil da eine logische Bedingung vorkommt.
In vielen Programmiersprachen ist das auch so. Aber nicht in C. In C
lautet die Syntax
if( Expression )
und der Wert der Expression wird auf 0 bzw. nicht 0 getestet um zu
entscheiden, welcher der Pfade im if zu nehmen ist. In diesem Sinne ist
i < 5 in
if( i < 5 )
einfach nur ein Ausdruck, der mit einem Wert hochkommt, der 0 ist, wenn
der Vergleich nicht zutrifft und der 1 ist, wenn der Vergleich zutrifft.
Das if interessiert das < überhaupt nicht. Das if interessiert nur der
Wert, der sich durch Auswertung des Ausdrucks ergibt - 0 oder nicht 0
> Ich würde ja auch nicht schreiben:>>
1
>i=ADDRESS<=0x20;
2
>
Warum nicht.
Das ist perfektes C.
Wenn es dir lieber ist, da zwecks leichterer Lesbarkeit Klammern zu
setzen, dann ist dir das natürlich freigestellt. Aber notwendig ist es
nicht.
> Gewohnheit, gefällt mir besser und selbst der dümmste Compiler kommt> nicht auf die Idee irgendwann mal nur ADDRESS zu "returnen" :)
Wenn ihm das pssiert, dann hat der Compiler noch ganz andere Probleme
:-)
Jörg Wunsch schrieb:> Es ist rein Geschmackssache, ob man da Klammern schreibt.
Oder aber die Programmierrichtlinien der Firma geben es vor, dass man
Klammern zu setzen hat.
Ich habe selten C-Code mit zu vielen Klammern gesehen - so manches mal
aber welchen mit zu wenigen, die der Compiler auch entsprechend
"verwarnt". ("warning - suggest parentheses around assignment used as
truth value" und dergleichen)
Mark Brandis schrieb:> Jörg Wunsch schrieb:>> Es ist rein Geschmackssache, ob man da Klammern schreibt.>> Oder aber die Programmierrichtlinien der Firma geben es vor, dass man> Klammern zu setzen hat.
Jaja, die Angst-Klammern nach dem Motto "ich bin mir unsicher und dann
gibt's eben Klammern mit der Gießkanne".
Und wo wir schon dabei sind, natürlich auch Casts mit der Gireßkanne.
Déjà vu... Beitrag "Re: Denke ich zu kompliziert?"
Johann L. schrieb:> Und wo wir schon dabei sind, natürlich auch Casts mit der Gireßkanne.
Yep, hatte ich neulich erst wieder. Und dann hat er sich gewundert,
dass eine zweite Variable überschrieben worden ist, weil er die
Adresse einer short-Variablen in einem scanf() auf "(int *)" gecastet
hat, damit der Compiler nicht mehr meckert ...
Mark Brandis schrieb:> Jörg Wunsch schrieb:>> Es ist rein Geschmackssache, ob man da Klammern schreibt.>> Oder aber die Programmierrichtlinien der Firma geben es vor, dass man> Klammern zu setzen hat.
Naja, auch dann ist es Geschmackssache. Nur eben nicht deine, sondern
die von dem, der die Richtlinie geschrieben hat.
> Ich habe selten C-Code mit zu vielen Klammern gesehen - so manches mal> aber welchen mit zu wenigen, die der Compiler auch entsprechend> "verwarnt". ("warning - suggest parentheses around assignment used as> truth value" und dergleichen)
Auch da kann man geteilter Meinung darüber sein, ob die Klammern
wirklich zu wenig sind und die Warnung wirklich sein müßte.
Jörg Wunsch schrieb:> Johann L. schrieb:>> Und wo wir schon dabei sind, natürlich auch Casts mit der Gireßkanne.>> Yep, hatte ich neulich erst wieder. Und dann hat er sich gewundert,> dass eine zweite Variable überschrieben worden ist, weil er die> Adresse einer short-Variablen in einem scanf() auf "(int *)" gecastet> hat, damit der Compiler nicht mehr meckert ...
Etwas, das ich bei gcc schon immer kontraproduktiv fand, ist bei z.B.
folgendem Code:
1
voidfunktion(int*p)
2
{
3
*p=3;
4
}
5
6
intmain()
7
{
8
inti;
9
funktion(i);
10
}
Der gibt folgede Warnung:
1
warning: passing argument 1 of ‘funktion’ makes pointer from integer without a cast
Die stimmt zwar, suggeriert aber, daß ein Cast die Lösung des Problems
sei, was er - so wie hier - in den meisten Fällen nicht ist.
Jörg Wunsch schrieb:> aber ich schreibe auch bei> #if FOO == 42 && BAR < 13> keine, da ich mir gemerkt habe, dass die Operatorenreihenfolge in> C vorsätzlich so gewählt worden ist, dass das so funktioniert, wie> man es erwarten würde (anders als bei Pascal).
Tja, wenn man zu lange C geübt hat, dann erscheint einem der Rest der
Welt unlogisch. (Was, ein Geisterfahrer? Nee, hunderte !)
Bedenke bitte, daß Pascal den Typ boolean kennt und logische
Verknüpfungen streng im jeweiligen Datentyp erfolgen, bei Integer also
bitweise. Das ist bei C ganz genau so, wenn man z.B. 42 & bar schreibt
(ohne &&). Nicht Pascal geht falsch, sondern deine Erwartungen sind
nicht logisch, sondern C-betriebsblind. Wie das? Versuch doch mal
#if FOO == 42 & BAR < 13
zu schreiben, also mit einfachem &.
Das wäre das C Pendant zu if foo=42 and bar<13
Bei Pascal gibt es kein andand oder oror - nun alles klaro?
Ansonsten halte ich deine Schreibweise
#if FOO == 42 && BAR < 13
für grottenschlecht, weil nicht wirklich deutlich lesbar. Man muß zum
Verstehen immer die Vorrangregeln von C en detail auswendig gepaukt
dabeihaben - und wehe, man ist noch mit anderen Sprachen befaßt, dann
ist die Verwechselung vorprogrammiert. Das ist Mist.
Wenn dastünde #if (FOO == 42) && (BAR < 13) dann wäre dies für dich nur
eine klitzekleine Mühe, aber es erhöht die Lesbarkeit erheblich.
W.S.
W.S. schrieb:> Bedenke bitte, daß Pascal den Typ boolean kennt und logische> Verknüpfungen streng im jeweiligen Datentyp erfolgen, bei Integer also> bitweise.
Nein, das erklärt das nicht. Es gibt keinen Grund, warum Pascal
dann nicht bei
if foo = 42 and bar < 13 then
den Vorrang so geregelt hätte, dass die Vergleiche zuerst passieren.
Schließlich ist die offensichtliche Bedeutung von "and" eine
logische Verknüpfung und nicht eine bitweise.
Das Fehlen eines Boolschen Types im Ur-C bedingt lediglich, dass
man dadurch für bitweises und logisches UND überhaupt erst einmal
zwei verschiedene Operatoren benötigt.
> Ansonsten halte ich deine Schreibweise> #if FOO == 42 && BAR < 13> für grottenschlecht, weil nicht wirklich deutlich lesbar.Ich finde ihn prima lesbar. ;-)
> Wenn dastünde #if (FOO == 42) && (BAR < 13)
...dann fände ich das bereits "obfuscated". Wo willst du dann
aufhören? Was ist, wenn da steht:
#if FOO == 42 && BAR < 2 * FOO
Müsste man das dann nicht deiner Meinung nach schreiben:
#if (FOO == 42) && (BAR < (2 * FOO))
weil sich natürlich niemand merken kann, ob der Vergleich oder die
Multiplikation nun Vorrang hat? Sollte man nicht auch bei
"Punktrechnung geht vor Strichrechnung" "sicherheitshalber" noch
Klammern setzen, denn es könnte ja sein, dass die Programmiersprache
der Wahl das nicht so implementiert hat, wie die Mathematiker es tun
würden?
Dass man zwischen logischem UND und logischem ODER Klammern setzt,
damit man sich deren gegenseitigen Vorrang nicht merken muss, finde
ich OK, aber bei Selbstverständlichkeiten geht schnell die
Übersichtlichkeit verloren.
Jörg Wunsch schrieb:> #if (FOO == 42) && (BAR < (2 * FOO))
Diese Klammern müssten so nicht sein wenn
zb.
#define FOO 10
aber bei
zb.
#define FOO 5+3
sieht das schon anders aus
Wenn nur ein Programmierer am Code beteiligt ist, weiß er/sie vielleicht
bei jedem Define wie es definiert ist.
Sind mehrere am Code beteiligt wird das sehr schnell unübersichtlich.
Und gerade solche define wie zb #define FOO 5+3 könne da ganz schon
Unordnung stiften.
Von der Seite her ist es sinnvoll die Klammern explizit zu setzen, auch
wenn es nicht unbedingt notwendig erscheint.
Es vermeidet saublöde Fehler die zum teil sehr schwer zu finden sind.
Das ist der Grund warum es in Firmen oft Regeln gibt, die hier Klammern
verlangen.
Wenn ich zb unseren Code ansehen, damit sind rund 1/2 MByte Flash des µC
belegt , da geht es nicht anderes als solche restriktiven Regeln zu
verwenden.
Und abgesehen davon, es bricht sich niemand einen Zacken aus der Krone
wenn er an solchen Stellen ein paar Klammern setzt.
Ralph schrieb:> Diese Klammern müssten so nicht sein wenn> zb.> #define FOO 10>> aber bei> zb.> #define FOO 5+3>> sieht das schon anders aus
Klar. Deshalb schreibt man auch
#define FOO (5 + 3)
Der Ersteller des Makros weiß nämlich, dass sein Makro unerwünschte
Seiteneffekte haben kann. Der Benutzer sollte sich darum nicht
kümmern müssen.
Jörg Wunsch schrieb:> Klar. Deshalb schreibt man auch>> #define FOO (5 + 3)>> Der Ersteller des Makros weiß nämlich, dass sein Makro unerwünschte> Seiteneffekte haben kann. Der Benutzer sollte sich darum nicht> kümmern müssen.
Ja klar, aber garantiere das mal wenn 50 und mehr Entwickler die
Weltweit verteilt sitzen Code zur gesamt Software beisteuern.
Dazu kommt noch autogenerierter Code aus Modellen , oder Codegeneratoren
für Konfigurationen,.........
Da hilft nur eins, strenge Regeln zur source code Erstellung die auch
solche Klammerregeln beinhalten.
Ansonsten gibt das ein gewaltiges Chaos.
Dadurch ergibt sich dann auch ein Source Code, der in automatisierten
Tests auf Code Ebene überprüft werden kann.
Sobald eine Software in irgendwelchen Transportmitteln eine Rolle
spielt, sind solche Prüfungen auch Pflicht.
Dabei ist es egal ob Auto , Flugzeug,.....
Und ja ich weiß für den Timer einer Kaffemaschine ( auch darin sind
mittlerweile µC ) brauch man sowas nicht.
Ralph schrieb:> Ja klar, aber garantiere das mal wenn 50 und mehr Entwickler die> Weltweit verteilt sitzen Code zur gesamt Software beisteuern.
Eben dafür hat man ja die Regeln, die dann besagen, dass nicht
seiteneffektfreie Ersetzungen im Makro geklammert werden müssen.
Bei einem
#if (FOO * 3 < 42)
würden dann auch die "offensichtlichen" Klammern
#if ((FOO * 3) < 42)
nicht mehr helfen, wenn der Trottel, der
#define FOO 5 + 3
gezimmert hat, seine Klammern vergessen hat.
Ralph schrieb:> Jörg Wunsch schrieb:>> #if (FOO == 42) && (BAR < (2 * FOO))>> Diese Klammern müssten so nicht sein wenn> zb.> #define FOO 10>> aber bei> zb.> #define FOO 5+3>> sieht das schon anders aus
Nein, auch dann müßten diese Klammern nicht sein, sondern andere. Wenn
FOO so blöd definiert ist, wird immer noch keine einzige der Klammern in
>> #if (FOO == 42) && (BAR < (2 * FOO))
irgendwas ändern.
Ralph schrieb:> Ja klar, aber garantiere das mal wenn 50 und mehr Entwickler die> Weltweit verteilt sitzen Code zur gesamt Software beisteuern.> Dazu kommt noch autogenerierter Code aus Modellen , oder Codegeneratoren> für Konfigurationen, ...>> Da hilft nur eins, strenge Regeln zur source code Erstellung die auch> solche Klammerregeln beinhalten.
Ja, sinnvolle Coding Rules sind auf jeden Fall notwendig, aber sie
lösen beiweitem nicht alls Probleme.
> Ansonsten gibt das ein gewaltiges Chaos.
Da helfen z.B. Code-Reviewing und Entwickler und Reviewer, die wissen,
was sie tun.
Durch technische Regeln und Barrieren wirst du nie das erreichen könne,
was Erfahrung und kritisches Denken können.
Johann L. schrieb:> Durch technische Regeln und Barrieren wirst du nie das erreichen könne,> was Erfahrung und kritisches Denken können.
Schon. Nur leider ist in vielen Firmen die "wir wollen Entwickler so
billig wie möglich haben" Mentalität weit verbreitet. Und dann is nix
mit Erfahrung und kritischer Herangehensweise, dann wird von
unerfahrenen Leuten im Code herumgesaut dass es nur so kracht.
Mark Brandis schrieb:> Johann L. schrieb:>> Durch technische Regeln und Barrieren wirst du nie das erreichen könne,>> was Erfahrung und kritisches Denken können.>> Schon. Nur leider ist in vielen Firmen die "wir wollen Entwickler so> billig wie möglich haben" Mentalität weit verbreitet. Und dann is nix> mit Erfahrung und kritischer Herangehensweise, dann wird von> unerfahrenen Leuten im Code herumgesaut dass es nur so kracht.
"Herumgesaut" ist hier die falsche Vokabel, denn die "Entwickler" können
und wissen es oft nicht besser, weil sie nicht richtig ausgebildet
wurden.
Verbockt wird das vom Management.
Manche coding guidelines sind zu recht sehr restriktiv bzgl Makros, das
sie ein großes Fehlerpotential durch die fehlende Typensicherheit
bringen und meist problemlos durch konstanten und inline Funktionen
ersetzt werden können. Man könnte argumentieren, dass mit Makros
schnellerer Code bei geringerem Optimierungsaufwand durch den Compiler
entsteht, aber angesichts der Fähigkeiten moderner Compiler und
Entwicklungswerkzeuge ist das Argument ziemlich zahnlos, um einen
typenmäßigen blindflug zu rechtfertigen. Die JSF rules (Kampfflugzeug)
erlauben generell nur Makros für Include Wächter in header files. Das
heißt nicht, dass ich mich nicht trotzdem immer wieder dazu hinreissen
lasse.