Forum: Compiler & IDEs woher nehmt ihr boolean?


von Henry (Gast)


Lesenswert?

Hallo zusammen,
leider enthält ja avr-gcc kein stdbool.h  (wieso eigentlich nicht? 
stdint existiert ja auch...).

Mir ist beim Ausmisten eines alten Projektes gerade aufgefallen dass ich 
dort stdbool benutze. Mein Eclipse kann mir den include auch auflösen, 
es wird die aus der "normalen" gcc Installation verwendet!
Ist natürlich gefährlich, auf Systemen ohne gcc (Windows).

Woher holt ihr denn eure boolschen Typen? Einfach selber einen Header 
schreiben? Wie genau definiert ihr boolean, TRUE und FALSE? 
Groß-/Kleinschreibung? Boolean oder Bool?
Oder einfach die stdbool abtippen und ins Projektverzeichnis kopieren?

Zugegeben, ist eher ne Frage aus Neugier denn ein technisches Problem 
:-)

Grüße und schönen Abend noch

von Philipp K. (numeriusnegidius)


Lesenswert?

unsigned char?

von Kaj (Gast)


Lesenswert?

Also unter Windows mit Atmel Studio 6.1 muss ich gar nichts includieren 
um
1
bool test_var = false;
 zu benutzen.

Henry schrieb:
> leider enthält ja avr-gcc kein stdbool.h  (wieso eigentlich nicht?
Vielleicht ist das mal wo anders mit rein gewandert bzw. ist jetzt 
build-in.
Um
1
int
 zu benutzten musst du ja auch nichts extra einbinden.

Gruesse

von Holger S. (223rem)


Lesenswert?

bei Studio 4.18, 4.19 mit avr-gcc 2010:
1
#include  <stdbool.h>

Gruß Holger

von chris (Gast)


Lesenswert?

Weil stdbool.h gefährlich ist.
_Bool ist der reale boolean type.


        1 The header <stdbool.h> defines four macros.
        2 The macro
            bool expands to _Bool.
        3 The remaining three macros are suitable for use in #if 
preprocessing directives. They are
            true : which expands to the integer constant 1,
            false: which expands to the integer constant 0, and
            __bool_true_false_are_defined which expands to the integer 
constant 1.
        4 Notwithstanding the provisions of 7.1.3, a program may undefine 
and perhaps then redefine the macros bool, true, and false.


Früher hatte man true/false so definiert:
#define false (0!=0)
#define true  (0==0)

oder auch

#define true !false

Die C99 Definition ist aber 1 und 0
wenn du dann stdbool.h nimmst, dann wird folgender code niemals 
ausgeführt.

angenommen events_mask ist 0xfc

 if (events & events_mask == true) {
   ...
 }

wenn du aber nach der alten Norm programmierst, funktioniert der code,
weil dann (events&events_mask) in _bool convertiert wird und dann 
verglichen wird, weil true _bool ist, hingegen C99 true ist integer 1.

Weil dies in C++ nicht passiert, weil type enforcement dort herrscht,
ist dies anfänglich nicht aufgefallen, und später war der Schaden schon 
da.

Pascal hält sich halt lange, denn true/false ist pascal , in realem C
würde man einfach if(events & events_mask) schreiben, aber es stimmt,
true / false erhöht wirklich die Lesbarkeit des Codes.

von Simon K. (simon) Benutzerseite


Lesenswert?

chris schrieb:
> Weil stdbool.h gefährlich ist.
Das ist so pauschal doch Unsinn.

> _Bool ist der reale boolean type.
Ja, oder bool aus <stdbool.h>. Und ja, das gibt es beim AVR-GCC.

> angenommen events_mask ist 0xfc
>
>  if (events & events_mask == true) {
>    ...
>  }
>
> wenn du aber nach der alten Norm programmierst, funktioniert der code,
> weil dann (events&events_mask) in _bool convertiert wird und dann
> verglichen wird, weil true _bool ist, hingegen C99 true ist integer 1.
Wer so etwas programmiert, der hat nichts anderes verdient. Es wird eine 
Bitoperation ausgeführt, dessen Ergebnis ebenfalls wieder von einem 
Integer Datentypen ist. Warum sollte man einen Integer mit einem 
boolschen Wert vergleichen wollen?

von Peter (Gast)


Lesenswert?

#define TRUE 1
#define FALSE 0

Und ein Boolean wird per typedef aus einem uint8 "gewonnen". Dabei muss 
man aber aufpassen, dass man wirklich nur mit TRUE und FALSE arbeitet.

1
Boolean flag = TRUE;
2
if( flag ==TRUE )
3
...


Ich mache den Vergleich bei if-Anweisungen immer, auch wenn sie gerade 
bei Flags nicht immer benötigt werdn. Der Vorteil ist zu einem die 
bessere Lesbarkeit und zum anderen kann man dann auch mal die Variable 
schnell auf FALSE abfragen.

von Henry (Gast)


Lesenswert?

Danke erstmal euch,

Kaj schrieb:
> Um int zu benutzten musst du ja auch nichts extra einbinden.
Das sind aber Äpfel und Birnen. "int" ist ein eingebauter Typ (oder wie 
das laut Standard benamst wird). "bool" ist eher mit "uint8_t" zu 
vergleichen.
Der Typ ist zwar im (C99) Standard definiert, ist aber nicht Teil der 
Sprache sondern wird über einen (Standard) Header bekanntgemacht.
Und für "uint8_t" braucht man ja auch stdint.h.


> Und ja, das gibt es beim AVR-GCC.
In meiner Installation (4.7.2 unter Linux Mint 16) ist der Header nicht 
dabei.
Kompilieren tuts aber trotzdem, weil avr-gcc anscheinend den stdbool.h 
des nativen gcc's benutzt.

von Sven P. (Gast)


Lesenswert?

chris schrieb:
> Früher hatte man true/false so definiert:
> #define false (0!=0)
> #define true  (0==0)
Was wiederum völlig überflüssig war. 'Logisch wahr' ist in C eindeutig 
als '1' definiert und 'Logisch falsch' ist '0'. Und das nicht erst seint 
C99, sondern schon ein Jahrzehnt länger.

> angenommen events_mask ist 0xfc
>  if (events & events_mask == true) {
>    ...
>  }
Dieser Code ist semantisch einfach falsch. Dafür kann stdbool auch 
nichts. Der Code ist auch in allen anderen Programmiersprachen falsch 
und wird nicht funktionieren.

> wenn du aber nach der alten Norm programmierst, funktioniert der code,
> weil dann (events&events_mask) in _bool convertiert wird und dann
> verglichen wird, weil true _bool ist, hingegen C99 true ist integer 1.
Nein, es wird bestenfalls nach 'int' propagiert und gegen '0' 
verglichen. Das hat mit bool nichts zu tun. Zumindest nicht in C.

> Weil dies in C++ nicht passiert, weil type enforcement dort herrscht,
> ist dies anfänglich nicht aufgefallen, und später war der Schaden schon
> da.
Auch da kann der bool nichts für. Dein Code da oben ist auch in C++ 
falsch und funktioniert nicht, obwohl er syntaktisch korrekt ist und 
compilierbar ist.


Ich benutze aber üblicherweise einfach einen unsigned char.

von Lutz H. (luhe)


Lesenswert?

Sven P. schrieb:
> unsigned char

Es gibt aber einen Unterschied zwischen  einen Buchstaben und logischen 
Zuständen.
Wenn im Code ein Buchstabe genutzt wird, nehme ich auch gern char,

für logische Zustände gefällt mir Boolean besser.

von Sven P. (Gast)


Lesenswert?

lutz h. schrieb:
> Es gibt aber einen Unterschied zwischen  einen Buchstaben und logischen
> Zuständen.
Völlig korrekt. Darum nehme ich ja auch einen 'unsigned char'. Wenn ich 
ein Zeichen brauche, nehm ich auch eines, nämlich 'char'.

von chris (Gast)


Lesenswert?

Sven P. schrieb:
> chris schrieb:
>> Früher hatte man true/false so definiert:
>> #define false (0!=0)
>> #define true  (0==0)
> Was wiederum völlig überflüssig war. 'Logisch wahr' ist in C eindeutig
> als '1' definiert und 'Logisch falsch' ist '0'. Und das nicht erst seint
> C99, sondern schon ein Jahrzehnt länger.
>
Diese (0!=0) ist, weil der resultierende Datentyp dann _Bool ist, und 
bei
dem Vergleich
if (events & events_mask == true)
dann zuerst events&events_mask nach _Bool convertiert wird, was hingegen
wenn false mit 0 definiert wird nicht der Fall ist, denn dann ist der 
Ausdruck Int und wird als Int ausgerechnet.
In diversen Architekturen ist _Bool z.B. das Zero oder Carryflag, hat
also nichts mit 0 oder 1 zu tun, aber wenn _Bool zu Int Convertiert 
wird,
dann stimmen die Werte.

Solchen Code sieht man oft noch in public domain source code, welcher
hauptsächlich von der Unix/usenet herkam welche man doch recht oft 
benutzt.

von Sven P. (Gast)


Lesenswert?

chris schrieb:
> Sven P. schrieb:
>> chris schrieb:
>>> Früher hatte man true/false so definiert:
>>> #define false (0!=0)
>>> #define true  (0==0)
>> Was wiederum völlig überflüssig war. 'Logisch wahr' ist in C eindeutig
>> als '1' definiert und 'Logisch falsch' ist '0'. Und das nicht erst seint
>> C99, sondern schon ein Jahrzehnt länger.
>>
> Diese (0!=0) ist, weil der resultierende Datentyp dann _Bool ist,
Nein, aus Vergleichen resultiert ein 'int'.

> und
> bei
> dem Vergleich
> if (events & events_mask == true)
> dann zuerst events&events_mask nach _Bool convertiert wird,
Nein, umgekehrt. Die Konstante 'true' wird in den Datentyp von 
'events&events_mask' promoted, denn der bool hat den geringsten aller 
Ränge, und das wird dann irgendein 'int' werden.

> In diversen Architekturen ist _Bool z.B. das Zero oder Carryflag, hat
> also nichts mit 0 oder 1 zu tun, aber wenn _Bool zu Int Convertiert
> wird, dann stimmen die Werte.
Das kann die Maschine halten wie sie will, genau. Es muss dann aber 
transparent umgesetzt sein.


Edit: Anm.: Das gilt für C. In C++ ergeben die Vergleiche tatsächlich 
booleans. Aber auch da wird in den Typ größeren Ranges promoted, sodass 
der Vergleich oben nicht funktioniert.

von Kaj (Gast)


Lesenswert?

Sven P. schrieb:
> 'Logisch wahr' ist in C eindeutig
> als '1' definiert und 'Logisch falsch' ist '0'.

Da muss ich ein kleines bisschen widersprechen.
'0' ist logisch falsch und alles ungleich '0' ist logisch wahr, und 
nicht nur '1'.

von Sven P. (Gast)


Lesenswert?

Kaj schrieb:
> Da muss ich ein kleines bisschen widersprechen.
> '0' ist logisch falsch und alles ungleich '0' ist logisch wahr, und
> nicht nur '1'.

Ok, ich habs auch unvollständig formuliert.
Bei den Vergleichsoperatoren (>,<,>=,<=,==,!=) sind als Ergebnis '0' 
oder '1' festgelegt für 'falsch' und 'wahr'.
Bei Bedingungen (if, ternärer Operator etc.) hast du natürlich Recht.

von Henry (Gast)


Lesenswert?

Schön Schön.

Und woher nehmt ihr denn nun eure bools, booleans, trues, falses, oder 
was auch immer? Bzw. wie definiert ihr euch die Typen/Konstanten?

Wie gesagt, stdbool ist imho NICHT Teil einer avr-gcc Installation.

von Sven P. (Gast)


Lesenswert?

Ich schrieb bereits, dass ich schlicht 'unsigned char' und 0/1 benutze, 
total unspektakulär.

Beim avr-gcc ist alternativ stdbool.h vorhanden; sie gehört allerdings 
nicht zur avr-libc, sondern kommt mit dem gcc selbst.

von Kaj (Gast)


Lesenswert?

Henry schrieb:
> Und woher nehmt ihr denn nun eure bools, booleans, trues, falses, oder
> was auch immer? Bzw. wie definiert ihr euch die Typen/Konstanten?

Wie, woher ich die nehme?
Wenn wir ueber C/C++ reden schreib ich
1
int main(void)
2
{
3
  bool myVar;
4
  myVar = true;
5
  myVar = false;
6
  
7
  return 0;
8
}
und dann ist gut. Kein include, define oder sonst was noetig. Ehrlich 
gesagt verstehe ich dein Problem nicht :/

von Sven P. (Gast)


Lesenswert?

Kaj schrieb:
> Wenn wir ueber C

Das liegt aber dann entweder daran, dass du immer den C++-Compiler 
benutzt oder deine Entwicklungsumgebung ungefragt schon irgendwelche 
Header hereinzieht.

Bestandteil von nacktem C (C99) ist 'bool' nämlich nicht.

von Kaj (Gast)


Lesenswert?

Ah ok, jetzt versteh ich das Problem. :)
Ja, benutze tatsaechlich immer den C++-Compiler. Ist mir nie bewusst 
aufgefallen^^

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


Lesenswert?

Henry schrieb:
> Wie gesagt, stdbool ist imho NICHT Teil einer avr-gcc Installation.

Doch, ist es.  Seit vielen Jahren.

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


Lesenswert?

Kaj schrieb:
> Ja, benutze tatsaechlich immer den C++-Compiler. Ist mir nie bewusst
> aufgefallen^^

Dann solltest du nicht "C/C++" schreiben.  Es sind halt zwei 
verschiedene
Sprachen, wenn auch mit teilweise überdeckender Syntax (wobei sie
nicht überdeckend sind: beide Sprachen haben jeweils Elemente, die
die andere Sprache nicht hat).

von Dussel (Gast)


Lesenswert?

>beide Sprachen haben jeweils Elemente, die
>die andere Sprache nicht hat
Kurz zwischengefragt: Welche hat C++ nicht?

von 12V DC (Gast)


Lesenswert?

C++ hat z.B. einen fertigen Datentyp boolean, den C nicht hat.
Wenn du C benutzt, dann würde ich einen INT Datentyp benutzten, dem du 1 
oder 0 zuweist und 1 wie false und 0 wie true benutzt(oder andersrum), 
denn die meisten Funktionen haben auch einen Rückgabewert(1 wen's geht 
und 0 bei Fail). So wird's jedenfalls in C von A-Z beschrieben.

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


Lesenswert?

Dussel schrieb:
> Welche hat C++ nicht?

Beispielsweise benannte Initialisierungen von Strukturen und Arrays.
Strukturen sind in C++ zwar Klassen, sodass man sowas durch
Konstrukturen ersetzen kann, aber bei Arrays gibt es dann gar keinen
entsprechenden Ersatz, und ein Headerfile, welches sowohl für C als
auch C++ gehen soll, klappt damit auch nicht.

Named address spaces wären auch noch so ein Ding, gegen das C++ sich
gewehrt hat.

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


Lesenswert?

12V DC schrieb:
> C++ hat z.B. einen fertigen Datentyp boolean, den C nicht hat.

C hat ihn (seit C99), aber man muss dort <stdbool.h> einfügen, damit
der Compiler ihn kennt.  Aber das wurde jetzt schon ein paarmal hier
geschrieben.  (Intern heißt er _Bool.  Mit dem header heißt er dann
bool, so wie in C++ auch.)

von Henry (Gast)


Lesenswert?

Hallo Jörg Wunsch,

Kannst du mich bitte aufklären, wie man standard-konform Bool bei AVR 
Projekten nutzt?
Denn die avr libc bringt ja kein stdbool.h mit.

Bei mir kompilierts trotzdem, weil stdbool.h des nativen gcc benutzt 
wird.
Ich hab nur Angst, dass es irgendwie ein Dummer Zufall ist.

Und mittlerweile hab ich herausgefunden dass WinAvr eine stdbool.h 
mitbringt, jetzt bin ich völlig verwirrt :-)

von Yalu X. (yalu) (Moderator)


Lesenswert?

stdbool.h ist nicht Bestandteil der AVR-Libc, sondern vom GCC-Paket. Du 
kannst es auf jeden Fall bedenkenlos nutzen.

von Henry (Gast)


Lesenswert?

Danke dir!

von Rolf Magnus (Gast)


Lesenswert?

Henry schrieb:
> Danke erstmal euch,
>
> Kaj schrieb:
>> Um int zu benutzten musst du ja auch nichts extra einbinden.
> Das sind aber Äpfel und Birnen. "int" ist ein eingebauter Typ (oder wie
> das laut Standard benamst wird). "bool" ist eher mit "uint8_t" zu
> vergleichen.

Der Grund, warum es bool, true und false nicht ohne Header gibt, liegt 
eher darin, daß es da draußen viel existierenden Code gibt, der sich 
diese Namen selbst definiert. Dieser Code würde plötzlich ungültig, wenn 
die auf einmal Schlüsselwörter wären. Deshalb hat man den Typ _Bool 
genannt und schaltet ihn über den Header quasi frei.

> Der Typ ist zwar im (C99) Standard definiert, ist aber nicht Teil der
> Sprache sondern wird über einen (Standard) Header bekanntgemacht.

Alle Standardheader sind Teil der Sprache. Das ist es ja, was sie zu 
Standardheadern macht.

> In meiner Installation (4.7.2 unter Linux Mint 16) ist der Header nicht
> dabei.
> Kompilieren tuts aber trotzdem, weil avr-gcc anscheinend den stdbool.h
> des nativen gcc's benutzt.

Das würde mich wundern, denn bei meinem 4.7.2er ist der Header dabei:
1
$ locate stdbool.h
2
/usr/include/c++/4.7/tr1/stdbool.h
3
/usr/lib/gcc/avr/4.7.2/include/stdbool.h    <--- Hier ist er!
4
/usr/lib/gcc/x86_64-linux-gnu/4.7/include/stdbool.h
5
/usr/lib/syslinux/com32/include/stdbool.h

von Fred (Gast)


Lesenswert?

Dussel schrieb:
>>beide Sprachen haben jeweils Elemente, die
>>die andere Sprache nicht hat
> Kurz zwischengefragt: Welche hat C++ nicht?

Das Schlüsselwort restrict.

von Henry (Gast)


Lesenswert?

> Alle Standardheader sind Teil der Sprache. Das ist es ja, was sie zu
> Standardheadern macht.

Hihi, als ich diesen Satz schrub wusste ich schon, dass sich 
irgendjemand darauf aufhängen wird.

> Das würde mich wundern, denn bei meinem 4.7.2er ist der Header dabei:$
> locate stdbool.h
> /usr/include/c++/4.7/tr1/stdbool.h
> /usr/lib/gcc/avr/4.7.2/include/stdbool.h    <--- Hier ist er!
> /usr/lib/gcc/x86_64-linux-gnu/4.7/include/stdbool.h
> /usr/lib/syslinux/com32/include/stdbool.h

Ja, mein Fehler, den ich dank Jörg Wunsch mittlerweile erkenn konnte.
Ich hab avr-gcc und avr libc durcheinander geschmissen und nur die 
Header von Letzterem angeschaut. avr-gcc bringt stdbool.h natürlich mit.

von der mechatroniker (Gast)


Lesenswert?

> Kurz zwischengefragt: Welche hat C++ nicht?

Den impliziten Cast von einem void-Pointer in einen Nicht-void-Pointer.

Der Namensraum für gültige Bezeichner ist etwas kleiner (eine struct 
darf nicht genauso heißen wie eine Variable, Funktion oder ein typedef; 
"class", "protected", "private", "bool" etc. darf kein Bezeichner 
heißen).

Das dürften die wesentlichen Stellen sein, wo sich zeigt, dass C++ keine 
Obermenge von C ist.

von Läubi .. (laeubi) Benutzerseite


Lesenswert?

Peter schrieb:
> Ich mache den Vergleich bei if-Anweisungen immer, auch wenn sie gerade
> bei Flags nicht immer benötigt werdn.

Sie werden nie benötigt, ich verstehe bis heute nicht was diese 
Unsitte bringen soll außer fehlerträchtigen Code....

> Der Vorteil ist zu einem die bessere Lesbarkeit

Weil man mehr lesen und nochmal darüber nachdenken muss oder wieso? Wäre 
es dann nicht noch besser sich ein "reallyTrue" und "reallyFalse" Macro 
zu definieren?

> und zum anderen kann man dann auch mal die Variable
> schnell auf FALSE abfragen.

Konsequenterweise müsstest du dann aber auch folgendes schreiben:
1
Boolean flag = TRUE;
2
if( (flag == FALSE) == TRUE )
3
...

Ein boolean typ is sicher hilfreich, aber nicht für Vergleiche, 
sondern nur um den Wertebereich einer Variablen zu definieren.

von Sven P. (Gast)


Lesenswert?

Wenn das die Vögel von MISRA wüssten...

von der mechatroniker (Gast)


Lesenswert?

Wenn statt
1
if (flag) {
besser ist:
1
if (flag == TRUE) {
dann ist angesichts der Tatsache, dass da ja Ende immer noch ein 
Wahrheitswert "einfach so" im if landet, folgendes logischerweise noch 
besser:
1
if ((flag == TRUE) == TRUE) {
ach nee, besser:
1
if (((flag == TRUE) == TRUE) == TRUE) {
bzw.
1
if ((((flag == TRUE) == TRUE) == TRUE) == TRUE) {

ad infinitum

von Läubi .. (laeubi) Benutzerseite


Lesenswert?

der mechatroniker schrieb:
> ad infinitum

Sicher ist halt sicher ;-)

von Henry (Gast)


Lesenswert?

Ich halt es so:

Wenn flag als boolean deklariert ist und nur direkte Zuweißungen 
stattfinden dann wird auch auf true getestet.
Stehen allerdings die einzelnen Bits für irgendwelche Zustände oder wird 
irgendwelche Maskenarithmetik betrieben, dann entfällt das == true. Dann 
ist flag aber auch ein uint_8 und kein bool.

von F. F. (foldi)


Lesenswert?

Was wiederum völlig überflüssig war. 'Logisch wahr' ist in C eindeutig
als '1' definiert und 'Logisch falsch' ist '0'. Und das nicht erst seint
C99, sondern schon ein Jahrzehnt länger.

Was in jedem uC Programm  schon immer  gut  an

while (1) {
}

zu erkennen ist, solange man nicht

for (;;){
}

nimmt.

von Rolf Magnus (Gast)


Lesenswert?

F. Fo schrieb:
> Was in jedem uC Programm  schon immer  gut  an
>
> while (1) {

Man könnt ja auch while ((1 == 1) == true) hinschreiben ;-)

> }
>
> zu erkennen ist, solange man nicht
>
> for (;;){
> }
>
> nimmt.

Das nehme ich in der Regel, weil ich es irgendwie sinniger finde, für 
eine Schleife ohne Abbruch-Bedinung auch keine hinschreiben zu müssen, 
statt einer pseudo-Bedingung, die halt nie false wird.

von Dussel (Gast)


Lesenswert?

Danke allen, die auf meine Zwischenfrage (Unterschied von C zu C++) 
geantwortet haben.

von Erwin (Gast)


Lesenswert?

Und dann verschwendet Ihr für jedes Flag ein Byte ?
Also ich nutze 8 einzelne Flags eines Bytes!

von Stefan R. (srand)


Lesenswert?

Erwin schrieb:
> Und dann verschwendet Ihr für jedes Flag ein Byte ?

Wääh, schluchz! Ein ganzes Byte!

> Also ich nutze 8 einzelne Flags eines Bytes!

Bist eben ein echter Mann.

von Erwin (Gast)


Lesenswert?

Ein echter Mann nutzt für ein Bit doch ein uint_32 !
Mit meiner Aussage ging es mir um die Sinnhaftigkeit auf einem AVR so 
vorzugehen.

von Lutz H. (luhe)


Lesenswert?

Läubi .. schrieb:
> Sie werden nie benötigt, ich verstehe bis heute nicht was diese
> Unsitte bringen soll außer fehlerträchtigen Code....

Kann  der Rückgabewert einer Funktion auch überladen werden?
Für mich ist es nur die Frage, den Code lesbarer zu machen.
Wenn die Funktion bekannt ist, und man kennt auch den erwarteten 
Rückgabewert und was dieser bedeutet, ist es nicht so wichtig. Wenn 
dieses Wissen nicht da ist, ist der Vergleich eine große Hilfe, dass 
Programm zu verstehen.

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


Lesenswert?

F. Fo schrieb:
> Was wiederum völlig überflüssig war. 'Logisch wahr' ist in C eindeutig
> als '1' definiert und 'Logisch falsch' ist '0'. Und das nicht erst seint
> C99, sondern schon ein Jahrzehnt länger.
>
> Was in jedem uC Programm  schon immer  gut  an
>
> while (1) {
> }
>
> zu erkennen ist

Aha.

Und was ist mit 2? Oder 5?

Die sind auch logisch wahr. Wie jeder beliebige andere Wert auch, 
der nicht 0 ist.

Also gibt es keinen Unterschied zwischen

  while (1)

und

  while (7)

oder

  while ('p')

oder auch

  while (9.5627)

von Rufus Τ. F. (rufus) Benutzerseite


Lesenswert?

lutz h. schrieb:
> Kann  der Rückgabewert einer Funktion auch überladen werden?
> Für mich ist es nur die Frage, den Code lesbarer zu machen.

Was ist an

  if (function(args) == true)

lesbarer als

  if (function(args))

oder was ist an

  if (function(args) == false)

lesbarer als

  if (!function(args))

?

Das ist alles nur eine Gewöhnungssache.

von Sven P. (Gast)


Lesenswert?

Rufus Τ. Firefly schrieb:
> Was ist an
>
>   if (function(args) == true)
>
> lesbarer als
>
>   if (function(args))
Nichts, die MISRA-Leute argumentieren das sogar noch weiter:
1
if (x == true)
ist gefährlicher als
1
if (x)
denn man könnte eines der beiden '=' vergessen und würde sich 'x' 
überschreiben. Darum soll man schreiben:
1
if (true == x)
Das gibt dann einen Fehler, wenn man ein '=' vergisst, vorausgesetzt, 
'true' ist keine Variable...

von Yalu X. (yalu) (Moderator)


Lesenswert?

Zum Thema Übersichtlichkeit von ==true:

Die Lesbarkeit wird in solchen Fällen viel effektiver dadurch erhöht, 
dass man Funktionen treffende Namen gibt. Boolesche Funktionen haben oft 
den Präfix "is", wie bspw. in isPrime oder is_convex. Die Abfrage
1
if (isPrime(number))
2
  ...

liest sich dann fast schon wie Prosa, und ein zusätzliches ==true wäre 
doppelt gemoppelt und würde die Sache eher unübersichtlicher machen.

von Rolf Magnus (Gast)


Lesenswert?

Erwin schrieb:
> Ein echter Mann nutzt für ein Bit doch ein uint_32 !
> Mit meiner Aussage ging es mir um die Sinnhaftigkeit auf einem AVR so
> vorzugehen.

Wenn man 8 zusammengehörige Flags hat, spricht meines Erachtens nichts 
dagegen, die in einem Byte zusammenzufassen. Es ging hier aber um 
einzelne boolesche Werte. Oder soll man sich noch 7 weitere eigentlich 
unnütze Flags ausdenken, nur damit man das Byte auch komplett genutzt 
hat?

lutz h. schrieb:
> Läubi .. schrieb:
>> Sie werden nie benötigt, ich verstehe bis heute nicht was diese
>> Unsitte bringen soll außer fehlerträchtigen Code....
>
> Kann  der Rückgabewert einer Funktion auch überladen werden?

Was meinst du mit "auch"? In C kann man Funktionen gar nicht überladen. 
In C++ schon, aber da kann man keine Funktionen mit gleicher 
Parameterliste und nur unterschiedlichen Rückgabetyp definieren.

Sven P. schrieb:
> Nichts, die MISRA-Leute argumentieren das sogar noch weiter:

Manchmal habe ich den Eindruck, daß ein großer Teil der MISRA-Regeln nur 
dazu gedacht sind, damit jemand, der keine Ahnung von C hat, auch das 
Gefühl bekommt, sauberen Code geschrieben zu haben.

Yalu X. schrieb:
> Zum Thema Übersichtlichkeit von ==true:
>
> Die Lesbarkeit wird in solchen Fällen viel effektiver dadurch erhöht,
> dass man Funktionen treffende Namen gibt. Boolesche Funktionen haben oft
> den Präfix "is", wie bspw. in isPrime oder is_convex.

Geschickt gewählt. Es sei angemerkt, daß isprime() z.B. nicht 
ISO-Konform wäre, da alle Namen, die mit "is" anfangen, auf das 
Kleinbuchstaben folgen, reserviert sind, genauso übrigens wie Namen, die 
mit "str" oder mit "to" anfangen, wie z.B. "today".

von Falk B. (falk)


Lesenswert?

@ Rolf Magnus (Gast)

>> Mit meiner Aussage ging es mir um die Sinnhaftigkeit auf einem AVR so
>> vorzugehen.

>Wenn man 8 zusammengehörige Flags hat, spricht meines Erachtens nichts
>dagegen, die in einem Byte zusammenzufassen.

Wenn es "normale" Flags sind, ist das OK. Bei Flags zwischen normalem 
Programm und Interrupts nimmt man besser ein Byte/Flag, damit hat 
man atomaren Zugriff. Die Speicher"verschwendung" ist meist zu 
verschmerzen. Oder so.

http://www.mikrocontroller.net/articles/AVR-GCC-Codeoptimierung#Speichern_von_globalen_Flags

"Als Alternative kann man ein nicht verwendetes Register des 
I/O-Bereichs verwenden. Dabei würde sich z. B. das Register eines 
zweiten UARTs, oder das EEPROM-Register anbieten, falls diese nicht 
benötigt werden."

Einige AVRs haben extra dafür Register, die sonst KEINERLEI Funktionen 
haben!

von Sven P. (Gast)


Lesenswert?

Rolf Magnus schrieb:
> Sven P. schrieb:
>> Nichts, die MISRA-Leute argumentieren das sogar noch weiter:
>
> Manchmal habe ich den Eindruck, daß ein großer Teil der MISRA-Regeln nur
> dazu gedacht sind, damit jemand, der keine Ahnung von C hat, auch das
> Gefühl bekommt, sauberen Code geschrieben zu haben.
Damit liegst du ziemlich dicht dran.

Das ist ähnlich wie mit den SPSen und AWL/ST. Damit schreibt man 
effektiv unlesbare und unwartbare Programme, inklusive 
Speicherzugriffsfehlern und so weiter. Aber man gibt dem Elektriker im 
Feld das Gefühl, dass es viel leichter damit geht, weil eine 
Programmiersprache ja viel zu kompliziert ist.

von Peter (Gast)


Lesenswert?

Rufus Τ. Firefly schrieb:
> if (function(args) == false)
>
> lesbarer als
>
>   if (!function(args))
>
> ?
>
> Das ist alles nur eine Gewöhnungssache.

Ganz einfach: Gerade das ! übersieht man leicht mal. Ich habe ja nicht 
gesagt, dass der Code dadurch schneller oder robuster wird. Genau wie du 
schreibst, es ist alles nur eine Sache der Gewöhnung.
Genau solche "Glaubenskriege" gibt es auch in unserer Abteilung. Ältere 
Kollegen, die schon 20 Jahre dabei sind fragen nicht auf true oder false 
ab. Jüngere, wie ich, machen dies schon.
Ich bin aber auch froh, dass in unserer Abteilung nur über solche 
Kleinigkeiten diskutiert wird, da wir uns über den Aufbau unsere 
Software vollkommen einig sind.
Ich will damit einfach sagen, dass es jeder so schreiben soll wie er es 
für die Übersicht am Besten findet!

von F. F. (foldi)


Lesenswert?

Peter schrieb:
> Ich will damit einfach sagen, dass es jeder so schreiben soll wie er es
> für die Übersicht am Besten findet!

Jeder schreibt seine Briefe in seinem Stil, das kann er auch bei 
Software so machen, solange nicht jemand danach damit umgehen muss.

Da ich ja gerade C lerne und hier unendlich viele Beispiele von 
unterschiedlichen Herangehensweisen kennen gelernt habe, frage ich mich, 
wie in den Firmen überhaupt Programme zustande kommen, wenn sie nicht 
einer allein macht.
Zunächst dachte ich immer, dass alles irgendwie genormt ist. Scheint es 
aber nicht zu sein.
Und das verstehe ich ehrlich gesagt überhaupt nicht, denn gerade in der 
Elektronik haben wir exakte Bezeichnungen und Schaltpläne, wieso dann 
nicht in der Programmierung selbst.

Allein die Schreibweisen in verschiedenen Compilern ist doch schon 
anders.

Für mich wird das keine Rolle mehr spielen wie ich ein Programm 
schreibe, da ich das nur für mich selbst mache, aber auch da halte ich 
mich an minimale Empfehlungen.
Gibt es denn eigentlich ein Standardwerk mit Empfehlungen, das man als 
verbindlich ansehen kann?

von Sven P. (Gast)


Lesenswert?

F. Fo schrieb:
> Zunächst dachte ich immer, dass alles irgendwie genormt ist. Scheint es
> aber nicht zu sein.
Doch, ist es. C und C++ sind genormte Programmiersprachen.

> Und das verstehe ich ehrlich gesagt überhaupt nicht, denn gerade in der
> Elektronik haben wir exakte Bezeichnungen und Schaltpläne, wieso dann
> nicht in der Programmierung selbst.
Haben wir doch. Haben wir das?
Wie nennst du denn deine Stecker? X? oder J? Oder ST? oder CON? Und die 
Transistoren? Q? T? Es gibt viele Freiheiten. Der Tiefpass ist nicht 
genormt...
Natürlich gibts auch da Normen. Aber ich bezweifle, dass du z.B. die 
aktuelle Norm für Schaltzeichen benutzen möchtest. In der[1] heißen 
Spule, Diode und Widerstand allesamt 'R'.

> Allein die Schreibweisen in verschiedenen Compilern ist doch schon
> anders.
Das wäre aber seltsam.
Allerdings bieten manche Compiler eigene Erweiterungen zur Sprache an, 
die sind dann natürlich nicht mehr genormt. Der Sprachschatz z.B. bei C 
ist aber sehr wohl genormt, inklusive Standardbibliothek.

Peter schrieb:
> Ganz einfach: Gerade das ! übersieht man leicht mal. Ich habe ja nicht
> gesagt, dass der Code dadurch schneller oder robuster wird.
Nö, aber der Code tut semantisch etwas völlig anderes.
Man kann Quelltexte übrigens auch unverständlich machen, indem man eben 
solche Dingen wie '== true' anwendet. Es gibt in C eine ganze Reihe von 
Idiomen, die sich im Laufe der Zeit etabliert haben und die 'jeder' 
C-Programmierer versteht. Dazu gehört auch das einfache 'if(x)'. Der 
erfahrenen Leser wird z.B. immer wieder über die unübliche Konstruktion 
mit '== true' stolpern, das kann auch fehleranfällig sein.

[1] EN 81346-2

von F. F. (foldi)


Lesenswert?

Sven P. schrieb:
>> Allein die Schreibweisen in verschiedenen Compilern ist doch schon
>> anders.
> Das wäre aber seltsam.
> Allerdings bieten manche Compiler eigene Erweiterungen zur Sprache an,
> die sind dann natürlich nicht mehr genormt. Der Sprachschatz z.B. bei C
> ist aber sehr wohl genormt, inklusive Standardbibliothek.

Ich hatte mal (ich lerne das ja gerade) versucht _BV in den Code 
einzubauen, aber das Studio meckerte da und vorher lief das Programm.

Aber darauf wollte ich nicht hinaus. Es geht mir mehr um die 
Schreibweisen für solche Problemstellungen.

Kann man sich denn nicht grundsätzlich auf solche Schreibweisen wie 
==true oder =1 oder was auch immer einigen?

Sicher, auch in der Schaltungstechnik gibt es Unterschiede, wenigstens 
ist (gerade bei neuer Norm) noch am Symbol zu erkennen, ob es ein 
Widerstand oder eine Spule ist.
Allein in unserer Firma gibt es zwei verschiedene Ausführungen von 
Schaltplänen. Die einen mutieren schon zu ganzen Tapeten und andere gibt 
es seitenweise.

von Rufus Τ. F. (rufus) Benutzerseite


Lesenswert?

F. Fo schrieb:
> Ich hatte mal (ich lerne das ja gerade) versucht _BV in den Code
> einzubauen, aber das Studio meckerte da und vorher lief das Programm.

Ein wesentlicher Schritt dabei, mit einem C- (oder auch C++-) Compiler 
umgehen zu lernen, ist der, Fehlermeldungen zu verstehen.

Wenn "das Studio meckert", wird also irgendwas nicht richtig sein -- 
hier z.B. wird vermutlich das Macro _BV nicht definiert gewesen sein.

> Kann man sich denn nicht grundsätzlich auf solche Schreibweisen wie
> ==true oder =1 oder was auch immer einigen?

Natürlich kann man sich darauf einigen -- die Leute mit Erfahrung 
einigen sich darauf, weder die eine noch die andere Variante zu 
verwenden.

von F. F. (foldi)


Lesenswert?

Rufus Τ. Firefly schrieb:
> Ein wesentlicher Schritt dabei, mit einem C- (oder auch C++-) Compiler
> umgehen zu lernen, ist der, Fehlermeldungen zu verstehen.

Das sehe ich auch so, aber wo finde ich mal ne Erklärung zu diesen meist 
kryptisch wirkenden Fehlermeldungen?

von Sven P. (Gast)


Lesenswert?

F. Fo schrieb:
> Ich hatte mal (ich lerne das ja gerade) versucht _BV in den Code
> einzubauen, aber das Studio meckerte da und vorher lief das Programm.
Ja, aber _BV gehört auch nicht zum standardisierten C.
Du würdest genauso scheitern, wenn du CreateProcess() 
gtk_recent_chooser_widget_new_for_manager() verwenden wolltest. Die 
gehören nämlich auch nicht zu Standard-C sondern zum Windows-API und zu 
GTK.

> Aber darauf wollte ich nicht hinaus. Es geht mir mehr um die
> Schreibweisen für solche Problemstellungen.
Es gibt mehr als eine Lösung für ein Problem. Das ist in der Elektrik 
aber auch nicht anders.

> Kann man sich denn nicht grundsätzlich auf solche Schreibweisen wie
> ==true oder =1 oder was auch immer einigen?
Hat man doch schon vor 30 Jahren. Man lässt es weg, das ist die übliche 
Konvention.

von Sven P. (Gast)


Lesenswert?

F. Fo schrieb:
> Das sehe ich auch so, aber wo finde ich mal ne Erklärung zu diesen meist
> kryptisch wirkenden Fehlermeldungen?
Google? Hier im Forum nachfragen? Compiler-Handbuch?

von F. F. (foldi)


Lesenswert?

Sven P. schrieb:
> F. Fo schrieb:
>> Das sehe ich auch so, aber wo finde ich mal ne Erklärung zu diesen meist
>> kryptisch wirkenden Fehlermeldungen?
> Google? Hier im Forum nachfragen? Compiler-Handbuch?

Gute Idee, mach ich mal gleich. :-)
Manchmal kommt man ja erst durch solche Beiträge auf etwas, was einen 
schon lange stört. Aber da es so viel zu lesen gibt, und ab Januar habe 
ich einen Haufen ganz neues Zeug zu lernen, und die Zeit begrenzt ist, 
merkt man das oft erst nach einem Hinweis - ich jedenfalls.:-)

Aber ein Link wäre trotzdem nett gewesen.

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


Lesenswert?

F. Fo schrieb:
> Das sehe ich auch so, aber wo finde ich mal ne Erklärung zu diesen meist
> kryptisch wirkenden Fehlermeldungen?

In der Dokumentation Deines Compilers.

Immer bedenken: Bei Fehlermeldungen, die ein C- oder C++-Compiler 
ausgibt, ist immer die erste die interessante. Alle weiteren Meldungen 
können Folgefehler sein.

Auch Warnungen sollte man ernstnehmen; gut geschriebener Code erzeugt 
auch keine Warnungen.

von F. F. (foldi)


Lesenswert?

Rufus Τ. Firefly schrieb:

>
> In der Dokumentation Deines Compilers.
>
> Immer bedenken: Bei Fehlermeldungen, die ein C- oder C++-Compiler
> ausgibt, ist immer die erste die interessante. Alle weiteren Meldungen
> können Folgefehler sein.
>
> Auch Warnungen sollte man ernstnehmen; gut geschriebener Code erzeugt
> auch keine Warnungen.

Vielen Dank für den Hinweis!

Den letzten Satz sehe ich genauso und auch Warnungen sind für mich, in 
meinem Code nicht akzeptabel.
Ich hoffe das auch noch in einigen Jahren sagen zu können. :-)

von Sven P. (Gast)


Lesenswert?

F. Fo schrieb:
> Ich hoffe das auch noch in einigen Jahren sagen zu können. :-)

Wart mal ab, bis du die Compileroptionen -Wall und -Wextra entdeckst... 
:-)

von Simon K. (simon) Benutzerseite


Lesenswert?

Sven P. schrieb:
> F. Fo schrieb:
>> Ich hoffe das auch noch in einigen Jahren sagen zu können. :-)
>
> Wart mal ab, bis du die Compileroptionen -Wall und -Wextra entdeckst...
> :-)

Und dann muss man sich mit Warnungen abfinden oder was ist jetzt die 
Aussage?

Ich hoffe ja nicht, dass du uns das damit sagen willst.

von Sven P. (Gast)


Lesenswert?

Nee, aber dann gibts noch eine Extraportion an Warnungen dazu :-)

von Kaj (Gast)


Lesenswert?

Sven P. schrieb:
> Wart mal ab, bis du die Compileroptionen -Wall und -Wextra entdeckst...
Dann aber bitte auch noch auf pedantic stellen :D

von Johann L. (gjlayde) Benutzerseite


Lesenswert?

Henry schrieb:
>> Und ja, das [stdbool.h] gibt es beim AVR-GCC.
> In meiner Installation (4.7.2 unter Linux Mint 16) ist der Header nicht
> dabei.

Dann ist deine Installation kaputt oder jemand hat sie erstellt, deer 
keine Ahnung hat.  stdbool.h befindet sich in

 $INSTALL/lib/gcc/avr/$VERSION/include

wobei $VERSION durch die GCC-Version zu ersetzen ist, etwa 4.3.3 für 
WinAVR-20100110.

In allen mir vorliegenden avr-gcc Versionen ist die stdbool.h dabei, und 
die Versionen reichen von 3.4.6 bis 4.8.1.

von Johann L. (gjlayde) Benutzerseite


Lesenswert?

Anmerkung: Manche Distributionen setzen gerne einen Wust von 
configure-Optionen.  Wenn dann stdnool.h in einen Pfad installiert wird, 
der nicht in des Suchpfaden enthalten ist, findet er die stdbool.h 
natürlich nicht.

Eine saubere Installation funktioniert, ohne Standard-Pfade per -L 
oder -l anzugeben!

von Henry (Gast)


Lesenswert?

Wie schon angemerkt hab ich avr-gcc und avr-libc durcheinandergebracht.
Dachte die libc bringt die Header mit, deswegen meine Verwunderung.

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.