|
| Enum Fra : Erling Østergaard |
Dato : 05-07-02 10:16 |
|
Jeg har et lille problem med en Enum. Problemet er at jeg har en reserveret
værdi på 255. Jeg vil gerne sikre mig at 255 ikke bliver brugt som en værdi
i Enum'en. Jeg kan selvfølgeligt tildele et dummyelement værdien 255, men
hvad sker der så hvis der er mere end 255 elementer før dummy??
Jeg ved godt at der er mange mere elegante løsninger på problemet
(eksempelvis at bruge en anden reserveret værdi ened 255, men dette vil
givetvis give problemer andre steder i koden...) end at lave et hack i
Enum'en, men problemet er at jeg sidder med et større projekt der består af
gammel C kode, som man ikke bare lige rydder op i....
| |
Mogens Hansen (05-07-2002)
| Kommentar Fra : Mogens Hansen |
Dato : 05-07-02 11:08 |
|
"Erling Østergaard" <ero@terma.com> wrote
> Jeg har et lille problem med en Enum. Problemet er at jeg har en
reserveret
> værdi på 255. Jeg vil gerne sikre mig at 255 ikke bliver brugt som en
værdi
> i Enum'en. Jeg kan selvfølgeligt tildele et dummyelement værdien 255, men
> hvad sker der så hvis der er mere end 255 elementer før dummy??
Du kan selv bestemme hvilke værdier de enkelte elementer skal have, og så
reservere 255:
enum some_enum
{ ONE = 1,
TWO = 2,
...
RESERVED_DO_NOT_USE = 255,
NEXT = 256,
...
};
Venlig hilsen
Mogens Hansen
| |
Erling Østergaard (05-07-2002)
| Kommentar Fra : Erling Østergaard |
Dato : 05-07-02 11:09 |
|
Ja det var også den ide jeg havde men hvad sker der hvis der er over 255
elementer før dette reserverede? som det følgende??
{ ONE = 1,
TWO = 2,
...
TWOFIVEFIVE (som vil have værdien 255)
RESERVED_DO_NOT_USE = 255,
NEXT = 256,
...
};
"Mogens Hansen" <mogens_h@dk-online.dk> wrote in message
news:ag3qt8$1e6g$1@news.cybercity.dk...
>
> "Erling Østergaard" <ero@terma.com> wrote
> > Jeg har et lille problem med en Enum. Problemet er at jeg har en
> reserveret
> > værdi på 255. Jeg vil gerne sikre mig at 255 ikke bliver brugt som en
> værdi
> > i Enum'en. Jeg kan selvfølgeligt tildele et dummyelement værdien 255,
men
> > hvad sker der så hvis der er mere end 255 elementer før dummy??
>
> Du kan selv bestemme hvilke værdier de enkelte elementer skal have, og så
> reservere 255:
>
> enum some_enum
> { ONE = 1,
> TWO = 2,
> ...
> RESERVED_DO_NOT_USE = 255,
> NEXT = 256,
> ...
> };
>
> Venlig hilsen
>
> Mogens Hansen
>
>
| |
N/A (05-07-2002)
| Kommentar Fra : N/A |
Dato : 05-07-02 11:32 |
|
| |
Erling Østergaard (05-07-2002)
| Kommentar Fra : Erling Østergaard |
Dato : 05-07-02 11:32 |
|
Det var det jeg helst ikke ville indse... Men tak for hjælpen.
"Mogens Hansen" <mogens_h@dk-online.dk> wrote in message
news:ag3rl4$1fnc$1@news.cybercity.dk...
>
> "Erling Østergaard" <ero@-PleaseDontSpam-terma.com> wrote
>
> > Ja det var også den ide jeg havde men hvad sker der hvis der er over 255
> > elementer før dette reserverede? som det følgende??
> >
> > { ONE = 1,
> > TWO = 2,
> > ...
> > TWOFIVEFIVE (som vil have værdien 255)
> > RESERVED_DO_NOT_USE = 255,
> > NEXT = 256,
> > ...
> > };
>
> Det skal man selv, manuelt holde styr på.
> Hvis man tildeler hvert element en værdi (med kommentarer om hvorvidt den
> konkrete værdi er vigtig eller ej) kan man holde styr på det.
>
> Venlig hilsen
>
> Mogens Hansen
>
>
| |
Bjarke Dahl Ebert (06-07-2002)
| Kommentar Fra : Bjarke Dahl Ebert |
Dato : 06-07-02 10:52 |
|
"Erling Østergaard" <ero@-PleaseDontSpam-terma.com> wrote in message
news:3d25707d$0$54739$edfadb0f@dspool01.news.tele.dk...
> Ja det var også den ide jeg havde men hvad sker der hvis der er over 255
> elementer før dette reserverede? som det følgende??
>
> { ONE = 1,
> TWO = 2,
> ...
> TWOFIVEFIVE (som vil have værdien 255)
> RESERVED_DO_NOT_USE = 255,
> NEXT = 256,
> ...
> };
Jeg vil foreslå at du indsætter et check, så du får compiletime-fejl den dag
du kommer til at bruge den reserverede værdi:
enum Foo
{
A = 0,
B, C, D,
/* ... */
DUMMY_CHECKCONSTANT,
RESERVED = 255,
/* fyld eventuelt flere værdier ind her, hvis du skal bruge mere end 255
*/
/* du behøver jo heller ikke at fylde området under 255 helt ud */
};
#if (DUMMY_CHECKCONSTANT >RESERVED)
#error "Too many constants in 'Foo'"
#endif
| |
Byrial Jensen (06-07-2002)
| Kommentar Fra : Byrial Jensen |
Dato : 06-07-02 11:54 |
|
Bjarke Dahl Ebert <bebert@worldonline.dk> skrev:
> Jeg vil foreslå at du indsætter et check, så du får compiletime-fejl den dag
> du kommer til at bruge den reserverede værdi:
>
> enum Foo
> {
> A = 0,
> B, C, D,
> /* ... */
>
> DUMMY_CHECKCONSTANT,
> RESERVED = 255,
> };
> #if (DUMMY_CHECKCONSTANT >RESERVED)
> #error "Too many constants in 'Foo'"
> #endif
Det virker ikke. Alle #-direktiver behandles af præprocessoren før
koden i øvrigt oversættes. Da DUMMY_CHECKCONSTANT og RESERVED ikke
er præprocessor-makroer, bliver de blot erstattet med 0 i
#if-direktivet, og da 0 ikke er større end 0, vil tjekket aldrig
give en fejlmeddelelse.
| |
Thomas Krog (06-07-2002)
| Kommentar Fra : Thomas Krog |
Dato : 06-07-02 12:24 |
|
> Det virker ikke. Alle #-direktiver behandles af præprocessoren før
> koden i øvrigt oversættes. Da DUMMY_CHECKCONSTANT og RESERVED ikke
> er præprocessor-makroer, bliver de blot erstattet med 0 i
> #if-direktivet, og da 0 ikke er større end 0, vil tjekket aldrig
> give en fejlmeddelelse.
Så kan man bruge en af teknikkerne fra "Modern c++ Design":
enum som_enum{
A=0,B,C,
Check,dummy = 3,
D,E,F
};
template<bool> struct CompileTimeError;
template<> struct CompileTimeError<true> {};
CompileTimeError<(Check <= dummy)> tooManyElementsBeforeDummyConstant;
| |
Bjarke Dahl Ebert (06-07-2002)
| Kommentar Fra : Bjarke Dahl Ebert |
Dato : 06-07-02 13:24 |
|
"Thomas Krog" <rick@kampsax.dtu.dk> wrote in message
news:ag6jvt$7k7$1@eising.k-net.dk...
> Så kan man bruge en af teknikkerne fra "Modern c++ Design":
>
> template<bool> struct CompileTimeError;
> template<> struct CompileTimeError<true> {};
> CompileTimeError<(Check <= dummy)> tooManyElementsBeforeDummyConstant;
Hvor "Modern" er det? Og vil det ikke bare give en linker-fejl?
Jeg kender godt alle disse "compile time assertion" teknikker, og
"avancerede traits"-tekniker, men jo mere jeg ser til dem, desto mere kvalme
får jeg.
Man benytter templates til noget det ikke er beregnet til. Man vrider
semantikken, à la "hvis vi skriver sådan her, så fejler det sjovt nok lige
præcis når denne betingelse er falsk". Men det er jo det rene hack. Man
benytter en "feature" i sproget således at man "tilfældigvis" får den
opførsel man er ude efter. Sådan kode er efter min mening utroligt svær at
læse, og er også meget skrøbelig (små ændringer får det hele til at brase
sammen).
Det er som om man siger "Vi har givet C++ - det er naturgivent at vi er
begrænset til at benytte dette sprog - hvordan kan vi så indkode denne her
mere avancerede mekanisme, som desværre ikke kan udtrykkes direkte i sproget
selv, v.hj.a. de primitiver vi er givet?".
Der har udviklet sig et helt "compile time sprog" i C++, og det er meget,
meget forskelligt fra runtime sproget.
Ovenstående er fx blot en "compile time assert". På samme måde kan man lave
"compile time if" og "compile time functions" (der så opererer på typer i
stedet for værdier).
Det *ville* da være klarere at kunne skrive
if check>dummy: error("blabla")
i stedet for ovenstående tre linier.
Et "Modern" sprog kendes bl.a. på hvor stort gap der er mellem ens billede
af problemet inde i hovedet, og så det man må nedfælde i source-filen.
Mit billede af problemet er netop en "Er check>dummy?".
Ikke "Findes der en instantiering af klasse-templaten CompileTimeError<t>,
hvor bool t er værdien af (Check<=Dummy)"
Bjarke
| |
Thomas Krog (06-07-2002)
| Kommentar Fra : Thomas Krog |
Dato : 06-07-02 14:13 |
|
> > Så kan man bruge en af teknikkerne fra "Modern c++ Design":
> >
> > template<bool> struct CompileTimeError;
> > template<> struct CompileTimeError<true> {};
> > CompileTimeError<(Check <= dummy)> tooManyElementsBeforeDummyConstant;
>
> Hvor "Modern" er det?
Jeg er enig med dig i at det ikke er specielt kønt. Det er dog svjv. den
eneste mulige løsningsteknik. Jeg håber der kommer nogle udvidelser til
standarden så den slags kan skrives noget pænere.
> Og vil det ikke bare give en linker-fejl?
nej, det giver en compile fejl.
| |
Thomas Krog (06-07-2002)
| Kommentar Fra : Thomas Krog |
Dato : 06-07-02 14:49 |
|
> > Og vil det ikke bare give en linker-fejl?
>
> nej, det giver en compile fejl.
Eller du mener måske hvis man ligger det i en header fil der inkluderes af
flere cpp-filer?
I så fald kunne man smide variablen ind i en inlined funktion:
template<bool> struct CompileTimeError;
template<> struct CompileTimeError<true> {};
inline void tooManyElements(){
CompileTimeError<(Check <= dummy)> tooManyElementsBeforeDummyConstant;
}
| |
Erling Østergaard (08-07-2002)
| Kommentar Fra : Erling Østergaard |
Dato : 08-07-02 07:43 |
|
"Thomas Krog" <rick@kampsax.dtu.dk> wrote in message
news:ag6jvt$7k7$1@eising.k-net.dk...
> > Det virker ikke. Alle #-direktiver behandles af præprocessoren før
> > koden i øvrigt oversættes. Da DUMMY_CHECKCONSTANT og RESERVED ikke
> > er præprocessor-makroer, bliver de blot erstattet med 0 i
> > #if-direktivet, og da 0 ikke er større end 0, vil tjekket aldrig
> > give en fejlmeddelelse.
>
> Så kan man bruge en af teknikkerne fra "Modern c++ Design":
>
> enum som_enum{
> A=0,B,C,
> Check,dummy = 3,
> D,E,F
> };
> template<bool> struct CompileTimeError;
> template<> struct CompileTimeError<true> {};
> CompileTimeError<(Check <= dummy)> tooManyElementsBeforeDummyConstant;
>
>
>
Det projekt jeg arbejder på er desværre i Ansi C så den går nok ikke.... Men
tak for svaret.
| |
Bjarke Dahl Ebert (06-07-2002)
| Kommentar Fra : Bjarke Dahl Ebert |
Dato : 06-07-02 13:11 |
|
> > #if (DUMMY_CHECKCONSTANT >RESERVED)
> > #error "Too many constants in 'Foo'"
> > #endif
"Byrial Jensen" <bjensen@nospam.dk> wrote in message
news:slrnaidj07.3cd.bjensen@ask.ask...
> Det virker ikke. Alle #-direktiver behandles af præprocessoren før
> koden i øvrigt oversættes. Da DUMMY_CHECKCONSTANT og RESERVED ikke
> er præprocessor-makroer, bliver de blot erstattet med 0 i
> #if-direktivet, og da 0 ikke er større end 0, vil tjekket aldrig
> give en fejlmeddelelse.
Ahr, ja selvfølgelig. Sørens osse
Endnu en grund til at compile time sucks. "Runtime is better than
compiletime" .
I fortolkede sprog er der slet ikke alle den slags problemer. Man får nogle
andre (fx ingen "compile time" checks), men de er IMHO meget mere til at
leve med.
I Python ville man bare lave sin egen Enum type, der springer 255 over -
hvis man da overhovedet vil have enum-talkonstanter (i stedet for fx
objekter)
Bjarke
| |
Per Abrahamsen (15-07-2002)
| Kommentar Fra : Per Abrahamsen |
Dato : 15-07-02 12:30 |
|
"Bjarke Dahl Ebert" <bebert@worldonline.dk> writes:
>> > #if (DUMMY_CHECKCONSTANT >RESERVED)
>> > #error "Too many constants in 'Foo'"
>> > #endif
> "Byrial Jensen" <bjensen@nospam.dk> wrote in message
> news:slrnaidj07.3cd.bjensen@ask.ask...
>> Det virker ikke. Alle #-direktiver behandles af præprocessoren før
>> koden i øvrigt oversættes. Da DUMMY_CHECKCONSTANT og RESERVED ikke
>> er præprocessor-makroer, bliver de blot erstattet med 0 i
>> #if-direktivet, og da 0 ikke er større end 0, vil tjekket aldrig
>> give en fejlmeddelelse.
>
> Ahr, ja selvfølgelig. Sørens osse
>
> Endnu en grund til at compile time sucks.
Snarere et eksempel på at en præprocessor der ikke er rigtigt
integreret i sproget er uheldigt.
| |
Thomas Krog (05-07-2002)
| Kommentar Fra : Thomas Krog |
Dato : 05-07-02 11:41 |
|
"Erling Østergaard" <ero@terma.com> wrote in message
news:3d2563ff$0$54742$edfadb0f@dspool01.news.tele.dk...
> Jeg har et lille problem med en Enum. Problemet er at jeg har en
reserveret
> værdi på 255. Jeg vil gerne sikre mig at 255 ikke bliver brugt som en
værdi
> i Enum'en. Jeg kan selvfølgeligt tildele et dummyelement værdien 255, men
> hvad sker der så hvis der er mere end 255 elementer før dummy??
En anden mulighed var at skrive:
enum{
dummy = 255,
A,B,C,D,E,F
}
cout << A << ", " << B << ", " << C << ", " << D << ", " << E << ", " << F
// udskriver 256,257,258,259,260,261
Så hvis dit projekt kan acceptere så store værdier ville det være en nem
løsning.
| |
Erling Østergaard (05-07-2002)
| Kommentar Fra : Erling Østergaard |
Dato : 05-07-02 12:11 |
|
"Thomas Krog" <rick@kampsax.dtu.dk> wrote in message
news:ag3t3a$ja8$1@eising.k-net.dk...
>
> "Erling Østergaard" <ero@terma.com> wrote in message
> news:3d2563ff$0$54742$edfadb0f@dspool01.news.tele.dk...
> > Jeg har et lille problem med en Enum. Problemet er at jeg har en
> reserveret
> > værdi på 255. Jeg vil gerne sikre mig at 255 ikke bliver brugt som en
> værdi
> > i Enum'en. Jeg kan selvfølgeligt tildele et dummyelement værdien 255,
men
> > hvad sker der så hvis der er mere end 255 elementer før dummy??
>
> En anden mulighed var at skrive:
>
> enum{
> dummy = 255,
> A,B,C,D,E,F
> }
> cout << A << ", " << B << ", " << C << ", " << D << ", " << E << ", " << F
> // udskriver 256,257,258,259,260,261
>
> Så hvis dit projekt kan acceptere så store værdier ville det være en nem
> løsning.
>
>
Tak for svaret, projektet kunne sådan set godt leve med de store værdier,
men dette vil måske give anledning til unødig undring ved debug senere hen.
Så jeg tror min løsning bliver at jeg tildeler de føste 256 elementer
eksplicit. På den måde undgår jeg at nogen siden hen tilføjer et enkelt
element før dummy og det hele så vælter af den grund.
Men tak for hjælpen.
| |
Thomas Krog (05-07-2002)
| Kommentar Fra : Thomas Krog |
Dato : 05-07-02 11:35 |
|
"Erling Østergaard" <ero@terma.com> wrote in message
news:3d2563ff$0$54742$edfadb0f@dspool01.news.tele.dk...
> Jeg har et lille problem med en Enum. Problemet er at jeg har en
reserveret
> værdi på 255. Jeg vil gerne sikre mig at 255 ikke bliver brugt som en
værdi
> i Enum'en. Jeg kan selvfølgeligt tildele et dummyelement værdien 255, men
> hvad sker der så hvis der er mere end 255 elementer før dummy??
Dummy løsningen er ok. Hvis det er elementer der ikke får tildelt værdier
(og du ikke gider skrive de 256+ tal) er det vigtigt at der er præcis 255
værdier for din dummy værdi. Her er et lille eksempel hvor dummy = 3 :
enum som_enum{
A,B,C,
dummy = 3,
D,E,F
};
cout << A << ", " << B << ", " << C << ", " << D << ", " << E << ", " << F
<< endl;
// Udskriver 0,1,2,4,5,6
Jeg havde egentlig troet at dummy kunne have stået i starten som her:
enum som_enum{
dummy = 3,
A=0,B,C,
D,E,F
};
cout << A << ", " << B << ", " << C << ", " << D << ", " << E << ", " << F
<< endl;
// Udskriver 0,1,2,3,4,5
Så det virker ikke med vc7 (jeg ved ikke hvad standarden siger). Dvs. du er
nødt til at placere dummy midt i det hele med 3 elementer før og de
resterende elementer efter.
| |
Bertel Lund Hansen (05-07-2002)
| Kommentar Fra : Bertel Lund Hansen |
Dato : 05-07-02 12:31 |
|
Thomas Krog skrev:
>Jeg havde egentlig troet at dummy kunne have stået i starten som her:
>enum som_enum{
> dummy = 3,
> A=0,B,C,
> D,E,F
>};
enum reserverer ikke noget som helst.
enum diverse {
a=0, b,c,d,e,f,g,
h=0,i,j,k,l,m,n,
o=0,p,q,r,s,t,u
};
Det giver tre rækker hver med tallen fra 0 til 6.
--
Bertel
http://bertel.lundhansen.dk/ FIDUSO: http://fiduso.dk/
| |
Bertel Lund Hansen (05-07-2002)
| Kommentar Fra : Bertel Lund Hansen |
Dato : 05-07-02 12:12 |
|
Erling Østergaard skrev:
>Jeg har et lille problem med en Enum. Problemet er at jeg har en reserveret
>værdi på 255.
Du kan ikke forhindre at enum genbruger en værdi. Det er lovligt
at skrive:
enum { start=20, slut=20, midti=20, lidttilhoejre=20 };
--
Bertel
http://bertel.lundhansen.dk/ FIDUSO: http://fiduso.dk/
| |
Erling Østergaard (05-07-2002)
| Kommentar Fra : Erling Østergaard |
Dato : 05-07-02 12:54 |
|
"Bertel Lund Hansen" <nospam@lundhansen.dk> wrote in message
news:hlvaiuknmbs4lbvf7f399uucdkbpo5ia0d@news.telia.dk...
> Erling Østergaard skrev:
>
> >Jeg har et lille problem med en Enum. Problemet er at jeg har en
reserveret
> >værdi på 255.
>
> Du kan ikke forhindre at enum genbruger en værdi. Det er lovligt
> at skrive:
>
> enum { start=20, slut=20, midti=20, lidttilhoejre=20 };
>
> --
> Bertel
> http://bertel.lundhansen.dk/ FIDUSO: http://fiduso.dk/
Det var lige den information jeg havde brug for, tak for det.
| |
Lars Otto (05-07-2002)
| Kommentar Fra : Lars Otto |
Dato : 05-07-02 13:06 |
|
> Du kan ikke forhindre at enum genbruger en værdi. Det er lovligt
> at skrive:
>
> enum { start=20, slut=20, midti=20, lidttilhoejre=20 };
Men udtrykket start==slut bliver så sandt og det er måske ikke så
behageligt.
/Lars
| |
Bertel Lund Hansen (06-07-2002)
| Kommentar Fra : Bertel Lund Hansen |
Dato : 06-07-02 11:58 |
|
Erling Østergaard skrev:
>Jeg har et lille problem med en Enum.
Nu er jeg blevet nysgerrig. Hvad er det *reelle* problem?
At lave kode der er afhængigt af at kun én konstant antager
værdien 255, lyder lidt ... øh, uholdbart.
--
Bertel
http://bertel.lundhansen.dk/ FIDUSO: http://fiduso.dk/
| |
Erling Østergaard (08-07-2002)
| Kommentar Fra : Erling Østergaard |
Dato : 08-07-02 07:38 |
|
"Bertel Lund Hansen" <nospam@lundhansen.dk> wrote in message
news:d7jdiukh0cjggcr16r5uovfg8tmjek9qh3@news.telia.dk...
> Erling Østergaard skrev:
>
> >Jeg har et lille problem med en Enum.
>
> Nu er jeg blevet nysgerrig. Hvad er det *reelle* problem?
>
> At lave kode der er afhængigt af at kun én konstant antager
> værdien 255, lyder lidt ... øh, uholdbart.
>
> --
> Bertel
> http://bertel.lundhansen.dk/ FIDUSO: http://fiduso.dk/
Det reelle problem er at jeg har enum, hvori der er meget mere end 255
elementer, man har nogle steder i koden anvendt en konstant der er 255 som
en unused værdi. Problemet opstår så når man indsætter unused (255) som
værdi, så kan man ikke se om noget er unused, ided unused ikke er unikt...
Jeg ved godt at jeg burde rette op på den uheldighed, men det ville være et
større oprydningsarbejde, som der desværre ikke er resourcer til lige nu, så
derfor hvis jeg kunne lave en hurtig løsning (hvilket jeg allerede har gjort
ved eksplicit at tildele værdier til de første 256 elemenenter i enumen)
ville det være at foretrække.
Jeg er fuldt ud klar over at den løsning jeg har valgt ikke er den mest
elegante, det var derfor jeg i sin tid stillede spørgsmålet her i gruppen,
idet jeg håbede på at man kunne reservere en værdi i en enum på en smartere
måde end at tildele værdierne eksplicit. Men nu jeg tænker tilbage på min
barnelærdom om enums, kan jeg klart se at det ikke er muligt...
Men tak for den fine respons på mit indlæg.
| |
Bertel Lund Hansen (08-07-2002)
| Kommentar Fra : Bertel Lund Hansen |
Dato : 08-07-02 09:08 |
|
Erling Østergaard skrev:
>Det reelle problem er at jeg har enum, hvori der er meget mere end 255
>elementer, man har nogle steder i koden anvendt en konstant der er 255 som
>en unused værdi. Problemet opstår så når man indsætter unused (255) som
>værdi, så kan man ikke se om noget er unused, ided unused ikke er unikt...
Okay. Hvad ville der ske ved at sætte unused til 65'535?
(Bortset fra at du *har* løst problemet)
--
Bertel
http://bertel.lundhansen.dk/ FIDUSO: http://fiduso.dk/
| |
Erling Østergaard (08-07-2002)
| Kommentar Fra : Erling Østergaard |
Dato : 08-07-02 09:20 |
|
"Bertel Lund Hansen" <nospam@lundhansen.dk> wrote in message
news:61iiiuc4bjcu1153lvlhusi5imj31j9t5f@news.telia.dk...
> Erling Østergaard skrev:
>
> >Det reelle problem er at jeg har enum, hvori der er meget mere end 255
> >elementer, man har nogle steder i koden anvendt en konstant der er 255
som
> >en unused værdi. Problemet opstår så når man indsætter unused (255) som
> >værdi, så kan man ikke se om noget er unused, ided unused ikke er
unikt...
>
> Okay. Hvad ville der ske ved at sætte unused til 65'535?
>
> (Bortset fra at du *har* løst problemet)
>
> --
> Bertel
> http://bertel.lundhansen.dk/ FIDUSO: http://fiduso.dk/
Problemet med en anden unused værdi er at det egentligt udspringer af nogle
8 bits værdier, så der kan jeg ikke bruge 65535. Der hvor jeg bruger unused
er det godt nok en 16 bits værdi, så jeg kunne godt lave en anden definition
af unused såsom unused16 (65535) men jeg ville så skulle gennemanalysere
alle steder hvor unused bliver brugt, idet jeg ellers risikerer at man et
sted har brugt unused (255) og et andet sted unused16 (65535), og så laver
sammenligning af dem. To forskellige definitioner gør det nok heller ikke
nemmere at forstå koden for "nye programmører", så vil jeg alligevel hellere
have det lille hack i enumen.
| |
Thomas Lykkeberg (06-07-2002)
| Kommentar Fra : Thomas Lykkeberg |
Dato : 06-07-02 14:54 |
|
On Fri, 5 Jul 2002 11:15:57 +0200, "Erling Østergaard" <ero@terma.com>
wrote:
>Jeg har et lille problem med en Enum. Problemet er at jeg har en reserveret
>værdi på 255. Jeg vil gerne sikre mig at 255 ikke bliver brugt som en værdi
>i Enum'en. Jeg kan selvfølgeligt tildele et dummyelement værdien 255, men
>hvad sker der så hvis der er mere end 255 elementer før dummy??
>
>Jeg ved godt at der er mange mere elegante løsninger på problemet
>(eksempelvis at bruge en anden reserveret værdi ened 255, men dette vil
>givetvis give problemer andre steder i koden...) end at lave et hack i
>Enum'en, men problemet er at jeg sidder med et større projekt der består af
>gammel C kode, som man ikke bare lige rydder op i....
>
Der hvor jeg arbejder, plejer vi at gøre det på følgende måde:
typedef enum EtEllerAndetIdTag
{
FIRST = 0,
SECOND,
...
...
LAST_ID,
INVALID_ID = 255
} EtEllerAndetId;
#if (LAST_ID >= INVALID_ID)
#error To many EtEllerAndetId's
#endif
Så vil compileren i hvert fald advare dig om at der er noget galt.
Håber du kan bruge det til noget
/Thomas
| |
Byrial Jensen (06-07-2002)
| Kommentar Fra : Byrial Jensen |
Dato : 06-07-02 22:01 |
|
Thomas Lykkeberg <thomasDOTlykkeberg@privatDOTdk> skrev:
> Der hvor jeg arbejder, plejer vi at gøre det på følgende måde:
>
> typedef enum EtEllerAndetIdTag
> {
> FIRST = 0,
> SECOND,
> ...
> ...
> LAST_ID,
> INVALID_ID = 255
> } EtEllerAndetId;
>
> #if (LAST_ID >= INVALID_ID)
> #error To many EtEllerAndetId's
> #endif
Det vil jeg ikke håbe at I gør. Som det allerede er forklaret,
virker det ikke.
> Så vil compileren i hvert fald advare dig om at der er noget galt.
Nej, det vil den ikke.
Hvad er der i vejen med et runtime-tjek (som med godt optimerende
oversættere sikkert alligevel i praksis bliver et compiletime-tjek):
#include <assert.h>
int main ()
{
assert (LAST_ID < INVALID_ID);
// ...
| |
Thomas Krog (06-07-2002)
| Kommentar Fra : Thomas Krog |
Dato : 06-07-02 22:45 |
|
> Hvad er der i vejen med et runtime-tjek (som med godt optimerende
> oversættere sikkert alligevel i praksis bliver et compiletime-tjek):
>
> #include <assert.h>
>
> int main ()
> {
> assert (LAST_ID < INVALID_ID);
> // ...
>
Jeg synes runtime-tjek kan være lidt upraktiske hvis det er noget generel
kode der skal bruges i flere projekter - så skal man huske at tilføje en
assert linje til alle de projekter som bruger den generelle kode.
| |
Bjarke Dahl Ebert (07-07-2002)
| Kommentar Fra : Bjarke Dahl Ebert |
Dato : 07-07-02 10:43 |
|
> > int main ()
> > {
> > assert (LAST_ID < INVALID_ID);
> > // ...
> >
>
"Thomas Krog" <rick@kampsax.dtu.dk> wrote in message
news:ag7odg$6gs$1@eising.k-net.dk...
> Jeg synes runtime-tjek kan være lidt upraktiske hvis det er noget generel
> kode der skal bruges i flere projekter - så skal man huske at tilføje en
> assert linje til alle de projekter som bruger den generelle kode.
Checket *behøver* jo ikke at være i main().
Ofte har et generelt modul en MyModule_init(...) metode - et passende sted
at lave den slags checks.
Hvis det er nogle tunge tests, kan man altid pakke den ind i noget #ifdef
_DEBUG.
(Minder mig lige om: på mit arbejde, udtales #ifndef som IFFENDEF - "Vi er
nok nødt til at iffendeffe den"
Endelig er der jo muligheden for at putte det ind i noget UnitTest.
Jeg er blevet stor fan af fortolkede sprog og dynamiske typer (for et par år
siden var jeg lige så stor fan af "alting kan checkes statisk" - jeg har
siden indset at jeg tog fejl).
De typefejl som man ikke fanger på (den nu manglende) compiletime, kan man
stort set fange med noget unittest. Jeg stoler langt mere på kode der
accepteres af en god unittest, end noget der "blot kompilerer".
Unittests tillader også meget mere generelle checks end hvad compileren
foretager, og man kan teste m.h.t. data der først findes på runtime, osv.
Bjarke
| |
Thomas Krog (07-07-2002)
| Kommentar Fra : Thomas Krog |
Dato : 07-07-02 11:18 |
|
> "Thomas Krog" <rick@kampsax.dtu.dk> wrote in message
> news:ag7odg$6gs$1@eising.k-net.dk...
> > Jeg synes runtime-tjek kan være lidt upraktiske hvis det er noget
generel
> > kode der skal bruges i flere projekter - så skal man huske at tilføje en
> > assert linje til alle de projekter som bruger den generelle kode.
>
> Checket *behøver* jo ikke at være i main().
>
> Ofte har et generelt modul en MyModule_init(...) metode - et passende sted
> at lave den slags checks.
Ja, hvis man så kunne få indrettet det sådan at programmet ikke kan startes
medmindre MyModule_init(...) bliver kaldt ville det være smart nok.
> Hvis det er nogle tunge tests, kan man altid pakke den ind i noget #ifdef
> _DEBUG.
> (Minder mig lige om: på mit arbejde, udtales #ifndef som IFFENDEF - "Vi er
> nok nødt til at iffendeffe den"
:)
[snip]
> Unittests tillader også meget mere generelle checks end hvad compileren
> foretager, og man kan teste m.h.t. data der først findes på runtime, osv.
ja, det må jeg jo give dig ret i.
| |
Thomas Lykkeberg (17-07-2002)
| Kommentar Fra : Thomas Lykkeberg |
Dato : 17-07-02 19:29 |
|
On Sat, 06 Jul 2002 21:01:19 GMT, Byrial Jensen <bjensen@nospam.dk>
wrote:
>Det vil jeg ikke håbe at I gør. Som det allerede er forklaret,
>virker det ikke.
Nå, men så benægter jeg dine "fakta". For det virker altså med
ARM's compilere.
>> Så vil compileren i hvert fald advare dig om at der er noget galt.
>
>Nej, det vil den ikke.
Joee, det ser sådan ud. Men jeg skal da fortælle dig om det den dag
det ikke gør
>Hvad er der i vejen med et runtime-tjek (som med godt optimerende
>oversættere sikkert alligevel i praksis bliver et compiletime-tjek):
>
>#include <assert.h>
>
>int main ()
>{
> assert (LAST_ID < INVALID_ID);
> // ...
>
Asserts bruger vi skam i stor stil.
/Thomas
| |
Byrial Jensen (17-07-2002)
| Kommentar Fra : Byrial Jensen |
Dato : 17-07-02 20:34 |
|
Thomas Lykkeberg <thomasDOTlykkeberg@privatDOTdk> skrev:
> On Sat, 06 Jul 2002 21:01:19 GMT, Byrial Jensen <bjensen@nospam.dk>
> wrote:
>
>>Det vil jeg ikke håbe at I gør. Som det allerede er forklaret,
>>virker det ikke.
> Nå, men så benægter jeg dine "fakta". For det virker altså med
> ARM's compilere.
Det er muligt at der findes oversættere hvor enum-konstanters værdi
kendes af præprocesseren, men de lever i givet fald ikke op til
C-standarden. Hvis man var grov, kunne man sige at de ikke er
C-oversættere, men oversættere for et andet, men lignende sprog.
Hvis ens oversætter lider af fejlen, bør man ikke benytte sig af
det, da det ville forhindre et senere skift til en mere fejlfri
oversætter.
Jeg bruger tilfældigvis en ARM-oversætter (ARM SDK 2.50)
professionelt, så jeg kan tjekke din påstand om at den lider af
den fejl når min sommerferie er forbi.
| |
Thomas Lykkeberg (19-07-2002)
| Kommentar Fra : Thomas Lykkeberg |
Dato : 19-07-02 17:24 |
|
On Wed, 17 Jul 2002 19:33:55 GMT, Byrial Jensen <bjensen@nospam.dk>
wrote:
>Jeg bruger tilfældigvis en ARM-oversætter (ARM SDK 2.50)
>professionelt, så jeg kan tjekke din påstand om at den lider af
>den fejl når min sommerferie er forbi.
Det er den samme vi bruger til MSP430 chip-sættet fra ADI.
Jeg har prøvet med både Borland og MS's compilere, de tillader det
også. ??
/Thomas
| |
Byrial Jensen (20-07-2002)
| Kommentar Fra : Byrial Jensen |
Dato : 20-07-02 23:01 |
|
Thomas Lykkeberg <thomasDOTlykkeberg@privatDOTdk> skrev:
> On Wed, 17 Jul 2002 19:33:55 GMT, Byrial Jensen <bjensen@nospam.dk>
> wrote:
>>Jeg bruger tilfældigvis en ARM-oversætter (ARM SDK 2.50)
>>professionelt, så jeg kan tjekke din påstand om at den lider af
>>den fejl når min sommerferie er forbi.
> Det er den samme vi bruger til MSP430 chip-sættet fra ADI.
>
> Jeg har prøvet med både Borland og MS's compilere, de tillader det
> også. ??
Det lyder højst besynderligt. Mener du helt alvorligt at de alle
i modstrid med korrekt opførsel stopper med fejlmmeddelelsen
"Denne oversætter er elendig" ved forsøg på at oversætte
nedenstående kode:
enum Enum
{
ENUM_KONSTANT = 5
};
#if (ENUM_KONSTANT == 0)
#error Denne oversætter bestod testen
#else
#error Denne oversætter er elendig
#endif
| |
Thomas Lykkeberg (21-07-2002)
| Kommentar Fra : Thomas Lykkeberg |
Dato : 21-07-02 14:36 |
|
On Sat, 20 Jul 2002 22:01:02 GMT, Byrial Jensen <bjensen@nospam.dk>
wrote:
>Det lyder højst besynderligt. Mener du helt alvorligt at de alle
>i modstrid med korrekt opførsel stopper med fejlmmeddelelsen
>"Denne oversætter er elendig" ved forsøg på at oversætte
>nedenstående kode:
Jeg kan ikke helt forstå hvorfor den skulle være "elendig" hvis den
gør ovenstående. Det er da blot en fordel.
/Thomas
| |
Byrial Jensen (22-07-2002)
| Kommentar Fra : Byrial Jensen |
Dato : 22-07-02 10:50 |
|
Thomas Lykkeberg <thomasDOTlykkeberg@privatDOTdk> skrev:
> On Sat, 20 Jul 2002 22:01:02 GMT, Byrial Jensen <bjensen@nospam.dk>
> wrote:
>
>>Det lyder højst besynderligt. Mener du helt alvorligt at de alle
>>i modstrid med korrekt opførsel stopper med fejlmmeddelelsen
>>"Denne oversætter er elendig" ved forsøg på at oversætte
>>nedenstående kode:
>
> Jeg kan ikke helt forstå hvorfor den skulle være "elendig" hvis den
> gør ovenstående.
Den er elendig fordi - som forklaret tidligere i tråden - at
C-sproget siger at symboler som bruges i præprocessor-direktiver,
men som ikke er præprocessor-makroer (dvs. defineret med
#define-direktiver), skal erstattes med værdien 0L.
> Det er da blot en fordel.
Nej, det er absolut ikke en fordel hvis en oversætter gør noget
andet end hvad der er specificeret i sprogdefinitionen. Det betyder
at programmet får en anden betydning end hvad man berettiget kunne
vente, eller i bedste fald (hvis man er opmærksom på fejlen) bliver
uportabel.
| |
|
|