und der Compiler warnt mich (zu Recht) mit der Meldung des Threadtitels.
Nur wie überzeuge ich ihn davon, daß das in diesem Fall Absicht ist?
Viele Grüße
W.T.
P.S.: Für all jene, die sonst den ganzen Nachmittag ein mulmiges Gefühl
im Bauch hätten:
Ich verwende bei vorerst ungenutzten variablen ein cast nach void.
Könnte auch hier funktionieren.
(void)(1+2);
Dann gibts nähmlich kein ungenutztes ergebnis mehr, weil 1+2 beim cast
benutzt wird und das ergebnis void nunmal kein ergebnis ist.
Hier wäre jedoch ein if/else konstrukt sinnvoller.
heyho,
deine "Funktion" liefert einen Rückgabewert mit dem nichts gemacht wird.
Mach eine richtige Funktion draus, oder ein switch-case...
beste grüße
public
Ich würde davon absehen #define als Ersatz für Funktionen zu nutzen.
Es mag im ersten Moment elegant aussehen, aber es ist Gift für die
Wartbarkeit und aufgrund der Wirkungsweise anfällig für Operator-Binding
Probleme.
An Zweiteres hast du z.B. bei der Definition von
Hng, da habe ich Klammern vergessen. Danke für's Entdecken!
Tim Seidel schrieb:> Es mag im ersten Moment elegant aussehen,
Ich finde Präprozessorgefrickel keineswegs elegant - aber manchmal
unvermeidbar. Aus dem folgenden:
(für die inline-Funktion kann ich leider kein switch/case verwenden, da
sich der Datentyp "_SFR_IO8" wohl nicht in ein Int casten läßt.)
Aus dem Makro von oben wird:
1
// I/O einstellen
2
void encoder_init(void)
3
{
4
gpio_setInputPU(ENC_A_GPIO,ENC_A_Pin);
5
4084: a2 98 cbi 0x14, 2 ; 20
6
4086: aa 9a sbi 0x15, 2 ; 21
7
gpio_setInputPU(ENC_B_GPIO,ENC_B_Pin);
8
4088: a3 98 cbi 0x14, 3 ; 20
9
408a: ab 9a sbi 0x15, 3 ; 21
10
408c: 08 95 ret
und da das Ganze u.A. auch in Bitbanging-Routinen seinen Platz findet,
ist das schon ein Unterschied.
Und ich sehe gerade, daß ich vorher den Cast nach void, den ich probiert
hatte, bevor ich die Frage ins Forum stellte, einfach an die falsche
Stelle gesetzt habe. So ist die Warnung weg:
1
// Port mit Pin-Bitmaske als Eingang mit Pull-Up setzen
2
#define gpio_setInputPU(PORT,PIN) (void) (\
3
(&PORT==&PORTA) ? (DDRA &= ~(PIN), PORTA |= (PIN)) :\
Walter Tarpan schrieb:> Ich finde Präprozessorgefrickel keineswegs elegant - aber manchmal> unvermeidbar. Aus dem folgenden: static inline> __attribute__((always_inline)) void> gpio_setInputPU(uint8_t PORT,const uint16_t Pin)
Warum ist PORT ein uint8_t? Das hätte eigentlich eine Adresse sein
müssen.
> {> if(PORT==PORTA) {
Hier liest du den Wert von PORTA aus (also den Wert, der im Register
selbst gespeichert ist) und vergleichst den mit dem an die Funktion
übergebenen uint8_t. Du wolltest wahrscheinlich eine Adresse übergeben
und die mit der Adresse von PORTA vergleichen. Das läßt sich dann nicht
nur zur Compilezeit auflösen, sondern ist außerdem noch korrekt.
Walter Tarpan schrieb:> Ich finde Präprozessorgefrickel keineswegs elegant - aber manchmal> unvermeidbar. Aus dem folgenden:> ...> if(PORT==PORTA) {
Das vergleicht nicht mehr die Adresse.
Mit dem üblichem do/while-Trick kann man 'normalen' Code in ein Makro
packen:
1
#define gpio_setInputPU(PORT,PIN) \
2
do { \
3
if (&(PORT) == &PORTA) { \
4
DDRA &= ~(PIN); \
5
PORTA |= (PIN); \
6
} else if (&(PORT) == &PORTB) { \
7
DDRB &= ~(PIN); \
8
PORTB |= (PIN); \
9
} else \
10
... \
11
} while (0)
(Aber das Gefrickel mit Klammern und die Gefahr von Seiteneffekten
bleibt.)
Walter Tarpan schrieb:> macht der AVR-GCC das hier:
Moment, Schritt zurück.
Es ist ein vollkommen anderer Code. Auslöser des unterschiedlichen
Kompilats ist nicht der Präprozessor, sondern, dass du den Ablauf und
die Semantik deines Quellcodes änderst.
Zudem ist deine Funktion falsch. Warum willst du anhand des Port-Inhalts
entscheiden welcher Port angesprochen wird?
1
gpio_setInputPU(uint8_tPORT,constuint16_tPin)
2
{
3
if(PORT==PORTA){
4
...
Analog zu deinem #define:
(Ohne Gewähr, da Copy&Paste ohne Test)
Das macht das Konstrukt zwar immer noch nicht schön, aber korrigiert,
dass
a) das #define nicht auf Zeilenebene durchgesteppt werden kann im
Debugger
b) die Operatoren-Bindings verschleiert werden
Rolf Magnus schrieb:> Warum ist PORT ein uint8_t? Das hätte eigentlich eine Adresse sein> müssen.
Stimmt. Ich hatte in freudiger Erwartung des Mittagessens den längst
gelöschten Kram mal eben eingehackt. So ist es richtig:
und das Ergebnis ist mit der Makro-Version identisch.
Dann werde ich noch einmal sorgfältig nachdenken, warum ich mich damals
gegen die Inline-Funktion für das Makro entschieden habe und das ggf.
ändern.