Ansi C: define Ausdruck

Gast #2917935
Lesenswert?

Aber das ist schon eine komische declaration....
1
bool IS_ETH_PHY_ADDRESS(ADDRESS int) {
2
   return  ADDRESS <= 0x20;
3
}

war nicht vielleicht so ?
1
bool IS_ETH_PHY_ADDRESS(int ADDRESS) {
2
   return  ADDRESS <= 0x20;
3
}

:)
#2917970
Lesenswert?

Davon, dass das ein Flüchtigkeitsfehler war bin ich jetzte einfach mal 
ausgegangen :D

Wenn wir schon dabei sind: ^^
1
bool IS_ETH_PHY_ADDRESS(int ADDRESS) {
2
   return  (ADDRESS <= 0x20);
3
}

Des weitern ist bool je nachdem von welchem

> Ansi C

man spricht auch nicht unbedingt so ganz vorgesehen.
Aber lassen wir es gut sein :D
#2917974
Lesenswert?

Dominik S. schrieb:

> Wenn wir schon dabei sind: ^^
>
>
1
> bool IS_ETH_PHY_ADDRESS(int ADDRESS) {
2
>    return  (ADDRESS <= 0x20);
3
> }
4
>

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.
#2918064
Lesenswert?

Entschuldige, die Argumentation verstehe ich jetzt nicht ganz und bitte 
um Erklärung :).
1
return 5;

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" :)
Moderator Persönliche Seite #2918088
Lesenswert?

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).
#2918090
Lesenswert?

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 
:-)
#2918113
Lesenswert?

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)
Persönliche Seite #2918132
Lesenswert?

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?"
Gast #2918185
Lesenswert?

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.
Gast #2918191
Lesenswert?

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
void funktion(int* p)
2
{
3
    *p = 3;
4
}
5

6
int main()
7
{
8
    int i;
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.
Gast #2918235
Lesenswert?

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.
Moderator Persönliche Seite #2918412
Lesenswert?

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.
Gast #2918510
Lesenswert?

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.
Moderator Persönliche Seite #2918514
Lesenswert?

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.
Gast #2918555
Lesenswert?

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.
Moderator Persönliche Seite #2918583
Lesenswert?

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.
Gast #2919059
Lesenswert?

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.
Persönliche Seite #2919115
Lesenswert?

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.
#2919121
Lesenswert?

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.
Persönliche Seite #2919133
Lesenswert?

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.
Gast #2920163
Lesenswert?

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.

Antwort schreiben

Bitte melde dich an, um einen Beitrag zu schreiben.

oder

Mit Google-Account einloggen

Die Registrierung ist kostenlos und dauert nur eine Minute.

Jetzt registrieren