podstawy języka - makra i definicje

0

Witam

Dlaczego tak zdefiniowane definicje:

#define SPI_PORT (B)
#define SPI_SCK (PB5)
#define SPI_SCK_OUT (DDR##SPI_PORT |= (1 << SPI_SCK))

wołane tak:

SPI_SCK_OUT;

nie rozwijają się do:

DDRB |= (1 << PB5);

?

Oraz dlaczego taki kod:

#define SPI_PORT (B)
#define SPI_SCK (PB5)
#define DDR(x) (SDDR(x))
#define SDDR(x) (DDR##x)
#define SPI_SCK_OUT (DDR(SPI_PORT) |= (1 << SPI_SCK))

wołane tak:

SPI_SCK_OUT;

nie rozwija się do tego samego co poprzednio?
Dodam tylko że w tym ostatnim przypadku wyskakuje błąd : "lvalue required as left operand of assignment"...

Pomożecie?

0

Bo powinny być zadeklarowane chyba tak:

#define SPI_SCK_OUT(port,sck)  DDR##port |= (1 << (sck))

Wtedy używasz tego tak:

SPI_SCK_OUT(B,PB5);
0

To wiem, ale nie bardzo podoba mi się tworzyć z tego makro.
Może postawię pytanie inaczej:

Dlaczego preprocesor mając taką definicję:

#define X (B)

i instrukcję:

DDR(X) |= (1 << 1);

nie rozwija tego do:

DDRB |= (1 << 1);

tylko do:

DDRX |= (1 << 1);

Jak zmusić preprocesor do wywołania makra z argumentem podmienianym na etapie preprocesingu definicją?

0

No nie do końca, rozwija to raczej tak:

DDR((B)) |= 1;

Doczytaj jak działa preprocesor.

1

Działanie preprocesora możesz przetestować używając np. -E w gcc.

Twój ostatni kod u mnie rozwijany jest do:

DDR((B)) |= (1 << 1)
2

Jeżeli jesteś początkującym i zaczynasz od makr, zmień książkę/kurs. Dalsza część na temat.

Adamos19 napisał(a):

Witam

Dlaczego tak zdefiniowane definicje:

#define SPI_PORT (B)
#define SPI_SCK (PB5)
#define SPI_SCK_OUT (DDR##SPI_PORT |= (1 << SPI_SCK))

wołane tak:

SPI_SCK_OUT;

nie rozwijają się do:

DDRB |= (1 << PB5);

?

Bo makra tak nie działają, bo tak naprawdę nic nie wołasz. Makro to po prostu zamiana jednego tekstu na drugi, jak zapiszesz nawiasy po prawej stronie to one też zostaną wklejone. Twoje przykładowe marko rozwinie się do (DDR(B) |= (1 << (PB5))); (to na oko, nie sprawdzałem kompilatorem). Usuń nawiasy to powinno rozwinąć się tak jak chcesz. Nawiasów używasz jeśli chcesz, żeby Twoje makro zachowywało się jak funkcja - przykład.

Doradzałbym jednak skasowanie tego kodu i rozwiązanie Twojego problemu inaczej, obecnie w C++ problemów do których makra są najlepszym rozwiązaniem jest bardzo mało, założę się o spodnie, że nie natknąłeś się na żaden z nich.
EDIT Nie zauważyłem, że temat jest otagowany jako C, a nie C++.

0

Dzięki za odpowiedzi. Poradziłem sobie już.
Zrobiłem tak:

#define DDR(x) (SDDR(x))
#define SDDR(x) (DDR##x)
#define SPI_PORT B
#define SPI_SCK (PB5)
#define SPI_PIN_OUT(x) (PIN_OUT(SPI_PORT, x))
#define PIN_OUT(x, y)  (DDR(x) |= (1 << y))

i piszę sobie potem tak:

SPI_PIN_OUT(SPI_SCK);

Działa to tak jak chcę żeby działało.
W odpowiedzi do kolegi @several : nie, nie natknąłem się na żaden z tych problemów o których piszesz to racja, jednak nie piszę w C++ tylko w C na mikrokontrolery.
Potrzebuję takich cyrków do tego żeby mi się ładnie sam komentował kod. Nie jestem jakimś urodzonym programistą ale pragnę aby mój kod wyglądał dokładnie tak jak wygląda teraz.
Także dzięki za pomoc. Pozdrawiam.

1 użytkowników online, w tym zalogowanych: 0, gości: 1