Makrot, pakotettu evaluointi

Makrot, pakotettu evaluointi

Tässä pätkä C -koodia:

#define add(j,k) (j k)

#define offset(elem) ( ( (PChar)&oma.elem ) - (p0) )
#define esize(elem) ( sizeof(oma.elem) )

#define einfo(elem) printf("'elem', %d, %d\n", offset(elem), esize(elem) );

void showIt()
{
BlobInfo oma;

PChar p0 = (PChar)&oma;
PChar _mapped = (PChar)&oma.mapped;
PChar _data = (PChar)&oma.data;

int x,y,z, xs,ys,zs;

x = _mapped - p0;
y = _data - p0;

z = 67;

x = offset(length);
y = offset(extent);
z = offset(quantum);

xs = esize(length);
ys = esize(data);
zs = esize(signature);

printf("x=%d y=%d z=%d ok.\n",x, y, z);

printf("xs=%d ys=%d zs=%d ok.\n",xs, ys, zs);

einfo(signature);

};


tuo viimeinen einfo(signature);
tulostaa tämän:

'elem', 24, 8

mutta tietenkin haluaisin sen tulostavan:

'signature', 24, 8

Eli miten pakotan tuon makron evaluoimaan tuon elem:n arvon myös (kaksinkertaisten) lainausmerkkienm sisällä ?

Tuossahan siis lainausmerkit ( " ) rajaavat merkkijonon ja heitomerkit ( ' ) on tarkoitettu olemaan osana tulostetta.
11528
Äänestä

Muut lukivat myös

Vastaukset 11

Vanhimmat

En ole aivan varma haluatko tätä, mutta jos vastasin väärin, osaat selittää paremmin :-)

Jos jokin makron argumentti halutaan muuttaa merkkijonoksi, standardi-C:ssä voi käyttää preprocessorin (pp tästä lähtien) #-operaatiota.

Siispä seuraava makro ei muuta elem-arvoa miksikään, koska siihen ei viitata.

#define a(elem) printf("se on elem")

Tämä taas muuttaa argumentin merkkijonoksi. Huomaa, että se lisää itse "-merkit, joten niitä ei saa olla sen ympärillä.

#define b(elem) printf("se on " #elem)

Nämä toiminnassa:
-----------------

#include

#define a(elem) printf("se on elem")
#define b(elem) printf("se on " #elem)

int main (void){
a(makkara);
b(peruna);
return 0;
}
-----------------

Ajo:
se on elemse on peruna

Rivinvaihto mokoma unohtui! No, kuitenkin näet, että makkara ei mennyt läpi, mutta peruna meni.

Tuo risuaita parametrin nimen edessä siis ohjastaa PP:tä tekemään sen muutoksen merkkijonoksi, ja kääntäjä puolestaan näkee vain "-merkkien sisässä olevan merkkijonon, aivan kuin ohjelmoijan suoraan kirjoittaman. Peräkkäiset merkkijonot yhdistetään automaattisesti yhdeksi, joten risuaitaargumentteja voi latoa muun tekstin sekaan ilman ongelmia, kunhan lopullinen tulos on järkevä. Argumentin voisi siis ympäröidä puolilaunausmerkeillä vaikkapa näin:

"'" #elem "'..."

Missä ... on loput tekstistä.

PP ei saa katoa merkkijonojen sisään (määritelmän mukaan), joten sinne laitetut argumentin nimet eivät sitä hetkauta.

Sinulla on muuten einfo:n määritelmän lopussa mahdollisesti turha ;. Tämä ei ole vakava virhe, koska tuskin ahluat einfo:a käyttää esim. if-testin sisässä.

P

Äänestä
  • PP ei tietenkään osaa evaluoida tuota argumenttia itse mitenkään. Esim. b(3 5) siis tuottaa merkkijonon "3 5", eikä merkkijonoa "8" (edellisen viestin mukaisella määrittelyllä).

    Äänestä

  • Sama mies_ kirjoitti:

    PP ei tietenkään osaa evaluoida tuota argumenttia itse mitenkään. Esim. b(3 5) siis tuottaa merkkijonon "3 5", eikä merkkijonoa "8" (edellisen viestin mukaisella määrittelyllä).

    periaatteessa merkki siittä, että se koodaaja ei oo oikein jyvällä siittä, mitä sen niinkö alunperinkään olis siinä pitänny tehä?

    Äänestä

  • Hello World without Macro kirjoitti:

    periaatteessa merkki siittä, että se koodaaja ei oo oikein jyvällä siittä, mitä sen niinkö alunperinkään olis siinä pitänny tehä?

    Eivät ne ole. Makroja on aivan perusteltua käyttää, jos ne lyhentävät ja selkeyttävät koodia.

    Äänestä

  • Opiksi kirjoitti:

    Eivät ne ole. Makroja on aivan perusteltua käyttää, jos ne lyhentävät ja selkeyttävät koodia.

    joita pitää käyttää selkiyttään sit koodii? Makrot on koodin selkiyttämismielessäkin helkkarin pahasta -sano mun sanoneen- ja niitä tulee käyttää äärimmäisessä hädässä ja vain ja ainoastansa pikapurkkakoodissa.

    Äänestä

  • Hello World without Macro kirjoitti:

    joita pitää käyttää selkiyttään sit koodii? Makrot on koodin selkiyttämismielessäkin helkkarin pahasta -sano mun sanoneen- ja niitä tulee käyttää äärimmäisessä hädässä ja vain ja ainoastansa pikapurkkakoodissa.

    Makroilla on oma paikkansa eri yhteyksissä. On turhaa uhoamista väittää, että niiden käyttäminen on yksiselitteisesti pahasta. Esim. yleinen esimerkki makrosta, joka valitsee suuremman kokonaislukuargumenteistaan on varsin hyödyllinen ja selkeä kapistus. Vai pitäisikö sama koodinpätkä tunkea joka väliin? Tai ehkä tehdä aliohjelma sitä varten?

    Äänestä

  • täällä... kirjoitti:

    Makroilla on oma paikkansa eri yhteyksissä. On turhaa uhoamista väittää, että niiden käyttäminen on yksiselitteisesti pahasta. Esim. yleinen esimerkki makrosta, joka valitsee suuremman kokonaislukuargumenteistaan on varsin hyödyllinen ja selkeä kapistus. Vai pitäisikö sama koodinpätkä tunkea joka väliin? Tai ehkä tehdä aliohjelma sitä varten?

    aina: inlinenä pelittää globaalisti ihan hyvin, kunhan muistaa kommentoida senkin koodin. Ei täällä mitään mesoamista ole. Pelkkiä faktoja vaan.

    Äänestä

  • Hello World without Macro kirjoitti:

    aina: inlinenä pelittää globaalisti ihan hyvin, kunhan muistaa kommentoida senkin koodin. Ei täällä mitään mesoamista ole. Pelkkiä faktoja vaan.

    hiffaa nyt se ensin, sitten ehkä ymmärrät

    Äänestä

  • Opiksi kirjoitti:

    Eivät ne ole. Makroja on aivan perusteltua käyttää, jos ne lyhentävät ja selkeyttävät koodia.

    Makrot harvoin selkeyttävät koodia. Niillä vaikutus on usemmiten aivan päin vastainen.

    Makroja ei juurikaan pitäisi käyttää

    Äänestä

  • lkhkjjk kirjoitti:

    hiffaa nyt se ensin, sitten ehkä ymmärrät

    ;-)

    Äänestä

  • Hello World without Macro kirjoitti:

    ;-)

    tuo toinen tyypähdys tuskin on tehnyt yhtään toimivaa ohjelmaa helloworldin lisäksi.

    Äänestä

Kommentoi aloitusta


Mika0800 kirjoitti:

Makrot, pakotettu evaluointi

Tässä pätkä C -koodia:

#define add(j,k) (j k)

#define offset(elem) ( ( (PChar)&oma.elem ) - (p0) )
#define esize(elem) ( sizeof(oma.elem) )

#define einfo(elem) printf("'elem', %d, %d\n", offset(elem), esize(elem) );

void showIt()
{
BlobInfo oma;

PChar p0 = (PChar)&oma;
PChar _mapped = (PChar)&oma.mapped;
PChar _data = (PChar)&oma.data;

int x,y,z, xs,ys,zs;

x = _mapped - p0;
y = _data - p0;

z = 67;

x = offset(length);
y = offset(extent);
z = offset(quantum);

xs = esize(length);
ys = esize(data);
zs = esize(signature);

printf("x=%d y=%d z=%d ok.\n",x, y, z);

printf("xs=%d ys=%d zs=%d ok.\n",xs, ys, zs);

einfo(signature);

};


tuo viimeinen einfo(signature);
tulostaa tämän:

'elem', 24, 8

mutta tietenkin haluaisin sen tulostavan:

'signature', 24, 8

Eli miten pakotan tuon makron evaluoimaan tuon elem:n arvon myös (kaksinkertaisten) lainausmerkkienm sisällä ?

Tuossahan siis lainausmerkit ( " ) rajaavat merkkijonon ja heitomerkit ( ' ) on tarkoitettu olemaan osana tulostetta.

Anonyymi
5000

Ilmoita asiaton sisältö

  • Sisältää materiaalia, joka on loukkaavaa, herjaavaa, rasistista, uhkailevaa tai ahdistelevaa.

  • Materiaali sisältää nimiä, yhteystietoja tai muita henkilökohtaisia tietoja. Julkisuuden henkilöistä, julkisissa viroissa toimivista ihmisistä sekä yritysten vastuuhenkilöistä saa keskustella työhön liittyen. Myös yksityiselämään liittyvistä asioista voi keskustella siltä osin, kuin niistä on julkisesti kerrottu.

  • Sisältää lapsille haitallista tai heiltä kiellettyä materiaalia. Seksuaalinen sisältö on sallittua aiheeseen tarkoitetuilla palstoilla, joiden ikäraja on 18 vuotta.

  • Lainvastaista sisältöä voi olla mm. yksityiselämää loukkaavan tiedon levitys, kiihottaminen kansanryhmää vastaan, laiton uhkaaminen, alaikäisiin liittyvä seksuaalinen sisältö/grooming, petokset, identiteettivarkaudet, kunnianloukkaukset ja tekijänoikeusrikkomukset.

  • Sisältö ei liity palstan tai keskusteluketjun aiheeseen.

  • Viesti ei ole suomea tai ruotsia (pl. International Forums), se sisältää mainontaa, se sisältää tekijänoikeuksin suojattua materiaalia, se on massapostitus tai jokin muu syy.

Jaa keskustelu