/ Forside / Teknologi / Udvikling / C/C++ / Nyhedsindlæg
Login
Glemt dit kodeord?
Brugernavn

Kodeord


Reklame
Top 10 brugere
C/C++
#NavnPoint
BertelBra.. 2425
pmbruun 695
Master_of.. 501
jdjespers.. 500
kyllekylle 500
Bech_bb 500
scootergr.. 300
gibson 300
molokyle 287
10  strarup 270
tyedef struct
Fra : Troels Thomsen


Dato : 08-01-03 09:36


Hvorfor er det nu man af og til bruger:

typedef struct asdf_tag {
int a; int b;
}asdf;

istedet for
struct asdf {
int a; int b;
};

Jeg har hørt at det er pga parameteroverførsel ifb med gamle c-kompilere.
Har det noget på sig?
void do_something(asdf* aa); // skal være typedef versionen på gamel c
kompilere ?

Jeg synes at de gode ideér med forward references bliver ødelagt når
der står typedef ved structene. !?

mvh Troels





 
 
Igor V. Rafienko (08-01-2003)
Kommentar
Fra : Igor V. Rafienko


Dato : 08-01-03 22:36

[ Troels Thomsen ]

> Hvorfor er det nu man af og til bruger:
>
> typedef struct asdf_tag {
> int a; int b;
> }asdf;
>
> istedet for
> struct asdf {
> int a; int b;
> };


Dersom du skal definere instanser av en slik struct, så kan man i det
første tilfellet skrive:

struct asdf_tag a1;

_og_

asdf a2;

.... da 'asdf' er et synonym for typen 'struct asdf_tag'. I det andre
tilfellet kan man skrive kun

struct asdf a3;

.... da typen 'struct asdf' ikke har noen andre navn. Det kan være
praktisk dersom man ikke ønsker å dra med seg 'struct' overalt (fx.
dersom man ikke er sikker på hvorvidt en _struct_ er en passende
representasjon for en type; eller dersom type_navnet_ forteller alt
man trenger å vite og 'struct' blir redundant informasjon).


> Jeg har hørt at det er pga parameteroverførsel ifb med gamle
> c-kompilere. Har det noget på sig?


Eh? Det må da være _meget_ defekte kompilatorer som stammer fra
virkelig gamle dager.


> void do_something(asdf* aa); // skal være typedef versionen
>           // på gamel c kompilere ?


Dersom 'asdf' er et synonym for typen 'struct T', så _skal_ man kunne
bruke _både_ 'asdf' _og_ 'struct T' i denne situasjonen.


> Jeg synes at de gode ideér med forward references bliver ødelagt når
> der står typedef ved structene. !?


Eh?





ivr
--
<peder> igorr: tcl ja... det er fra de dypeste avgrunnene i helvete det...
<peder> php er bare fra foajeen
            -- pederst på irc

Troels Thomsen (09-01-2003)
Kommentar
Fra : Troels Thomsen


Dato : 09-01-03 13:22

> Eh? Det må da være _meget_ defekte kompilatorer som stammer fra
> virkelig gamle dager.

Ok, det er nok bare en And.


> > Jeg synes at de gode ideér med forward references bliver ødelagt når
> > der står typedef ved structene. !?

Jeg har problemer med flg:

#ifndef test1H
#define test1H
typedef struct
{
int a;
}sA;
#endif


#ifndef test2H
#define test2H
#include "test2.h"
//struct sA; // forward declaration
class sB
{
sA* aPtr;
};
#endif


// test.cpp
#include "test.h"
#include "test2.h"
int main(int argc, char* argv[])
{
sA aObj;
sB bObj;
return 0;
}

Hvis jeg prøver at lave en forward declaration af sA istedet for #include
får jeg: 'sA' : redefinition; different basic types

Hvis jeg ikke typedef'er sA virker det.

Hvis det bare er fordi det er pænere at der ikke står struct over det hele,
kan man vel bare lave: #define asdf struct asdf_tag ?

I mange (?) firmaers kode-standard står at "Vi bruger typdef struct", så
hvis det ødelægger forward references er man jo lidt på den.



Helge Jensen (09-01-2003)
Kommentar
Fra : Helge Jensen


Dato : 09-01-03 14:04

Troels Thomsen wrote:

> Jeg har problemer med flg:

> #include "test2.h"
> struct sA; // forward declaration
> class sB
> {
> sA* aPtr;
> };

Du har glemt at give den struct sA er et typedef for et navn :)

---- test1.h ---
typedef struct sA { ... } sA;
^^---------^^
|
her skal stå det samme, hvis du vil kunne bruge
"struct sA" og "sA" some den samme type.
----------------

BTW:
> ifndef test2H
> #define test2H
> #include "test2.h"
^^^^^^^^^^^^^^^^^^---- hvad er ideen med dette?

> Hvis jeg prøver at lave en forward declaration af sA istedet for #include
> får jeg: 'sA' : redefinition; different basic types

Hvilket er helt korrekt:

I C og C++ er to typer ækvivalente hvis de har samme definition (altså
ikke bruder one definition rule), det er liggyldigt om de har samme
værdi. f.eks er:

struct A {};
struct A {};

U gyldig kode, da det indeholder 2 "forskellige" (jf. definitionen af
type-ækvivalens) definitioner af struct A.

I din kode har du jo sagt:

test1.h: A er typedef for denne anonyme struct
test2.h: Der findes en struct der heder A

Og det betyder, at A har to definitioner, hvilket både C og C++ forbyder.

> Hvis jeg ikke typedef'er sA virker det.

Aaaarh, det er vist ikke helt rigtigt. Hvis du skriver:

struct A { ... };

i stedet for

typedef struct { ... } A;

Så virker det, men at "ikke typdef'e" ville blive til:

struct { ... }; /* intet A */

Det illustrerer iøvrigt meget godt hvad der går galt med dit eksempel :)

> Hvis det bare er fordi det er pænere at der ikke står struct over det hele,
> kan man vel bare lave: #define asdf struct asdf_tag ?

Uhadada, #define er en farlig ting:

1. #define respekterer defines ikke scope
2. #define af typer introducerer problemer

---- x.hpp ----
struct asdf_tag {
int x;
}
#define asdf struct asdf_tag

---- y.hpp ----
struct asdf; /* dont include x.h, just declare the type as existing */

void foo(asfd*);

Nu afhænger typen af foo af om man inkluderer x.hpp før eller efter y.hpp!

3. #define gør ofte compilerens fejlmeddelelser misledende

Husk, at #define ikke behøves for at erklære tal-konstanter

#define FOO 1234763 /* oh no, BAD */
enum { FOO = 1234763; } /* Aaaah, good */

Du kan endda:

int foo[FOO];

Da FOO er en konstant!

Og streng-konstanter, hvis det ikke er BYDENDE nødvendigt at konkatenere
dem på compile-time:

#define FOO "yapyap" /* oh no, BAD */
static const char *foo = "yapyap" /* Aaah, good */

> I mange (?) firmaers kode-standard står at "Vi bruger typdef struct", så
> hvis det ødelægger forward references er man jo lidt på den.

1. Det gør det ikke.
2. kode-standarder bøjer sig forhåbentlig for godt design
(3. kode-standarder er ofte laver af folk der ikke selv kan finde ud af
at benytte sproget, heraf behovet for en standard :)

--
Helge


Troels Thomsen (10-01-2003)
Kommentar
Fra : Troels Thomsen


Dato : 10-01-03 10:11


Hvis man skriver struct sA { ........ } saObj1, saObj2; laver man instanser
af structet. Men det gør typedef struct sA_tag { ........ } sA; vel ikke?

sA obj1 // Ok?
struct sA_tag obj2 // Ok?
void func(sA* asdf); // Ok?
void func(struct sA_tag* asdf); // Ok?


> f.eks. er
> struct A {};
> struct A {};
>U gyldig kode, da det indeholder 2 "forskellige" (jf. definitionen af
>type-ækvivalens) definitioner af struct A.

???



>> Hvis jeg ikke typedef'er sA virker det.
>Aaaarh, det er vist ikke helt rigtigt. Hvis du skriver:
Dårligt formuleret, jeg mente det du skriver.


>Uhadada, #define er en farlig ting:
Det var nok bare et udtryk for min irritation over drilleriet.


>> I mange (?) firmaers kode-standard står at "Vi bruger typdef struct", så
>> hvis det ødelægger forward references er man jo lidt på den.

>1. Det gør det ikke.
Nej, med typedef struct sA { ........ } sA; virker forward declarations
igen.

>2. kode-standarder bøjer sig forhåbentlig for godt design
Du har ret, det burde de ...........

>(3. kode-standarder er ofte laver af folk der ikke selv kan finde ud af
>at benytte sproget, heraf behovet for en standard :)
CC: teamleder )




Helge Jensen (11-01-2003)
Kommentar
Fra : Helge Jensen


Dato : 11-01-03 19:56

Troels Thomsen wrote:

> Hvis man skriver struct sA { ........ } saObj1, saObj2; laver man instanser
> af structet.

Ja syntax'en for struct instantiering er:

TYPE a, ...;

Hvor TYPE i overstående er en struct sA, der er erklæret på stedet.

> Men det gør typedef struct sA_tag { ........ } sA; vel ikke?

Nej syntaksen for typedef er

typedef TYPE NAME;

Der gør NAME til et andet navn for TYPE

> sA obj1 // Ok?
> struct sA_tag obj2 // Ok?
> void func(sA* asdf); // Ok?
> void func(struct sA_tag* asdf); // Ok?

OK alt sammen, men jeg ville normalt foretrække:

typdef struct A { ... } A;

Da man så kan bruge navnene "A" eller "struct A" ækvivalent. Der er ikke
nogen grund til at benytte "A_tag".

Med denne definition kan man nemt predeclare'e A, når man kun har brug
for deklarationen, men ikke definitionen, f.eks. i header-filer, hvor
man blot deklarerer (ikke definerer) funktioner der benytter A:

---- foo.h ----
typedef struct A A; // refrain from including the definition of A
void foo(A a); // declare foo that accepts A, by value!

---- foo.c ----
#include "foo.h"
#include "A.h" // Get the definition of A
void foo(A a) { ... } // define foo

>>f.eks. er
>> struct A {};
>> struct A {};
>>U gyldig kode, da det indeholder 2 "forskellige" (jf. definitionen af
>>type-ækvivalens) definitioner af struct A.

> ???

Prøv at køre det igennem compileren, den vil ikke spise det :)

>>Uhadada, #define er en farlig ting:
> Det var nok bare et udtryk for min irritation over drilleriet.

En preprocessor er selvf. en rar ting, da C og C++ ikke har noget
meta-sprog eller reflection.

Men alt for tit har jeg haft kode i hånden der har _mærkelig_ opførsel
pga. defines, og som lige så godt kunne have brugt C's almindelige
mekanismer.

--
Helge


René Allan Larsen (09-01-2003)
Kommentar
Fra : René Allan Larsen


Dato : 09-01-03 10:54

In article <3e1be242$0$71707$edfadb0f@dread11.news.tele.dk>, Troels Thomsen
wrote:
> From: "Troels Thomsen" <nej@tak.dk>
> Newsgroups: dk.edb.programmering.c
> Subject: tyedef struct
> Date: Wed, 8 Jan 2003 09:35:42 +0100
>
>
> Hvorfor er det nu man af og til bruger:
>
> typedef struct asdf_tag {
> int a; int b;
> }asdf;
>
> istedet for
> struct asdf {
> int a; int b;
> };

Fordi man i nogle compilere i det andet tilfælde er nødt til at skrive
"struct asdf" hver gang man skulle bruge typen. Et lille eksempel:

struct asdf1 {
int a;
int b;
};
typedef struct {
int a;
int b;
} asdf2;

void do_something1(struct asdf1* aa);
void do_something2(asdf2* aa);

Er metoden med typedef ikke "smukkere"?

MVH, René


Jesper Wolf Jesperse~ (09-01-2003)
Kommentar
Fra : Jesper Wolf Jesperse~


Dato : 09-01-03 12:34

Hej Troels.

"Troels Thomsen" <nej@tak.dk> wrote in message
news:3e1be242$0$71707$edfadb0f@dread11.news.tele.dk...
>
> Hvorfor er det nu man af og til bruger:
>
> typedef struct asdf_tag {
> int a; int b;
> }asdf;
>
> istedet for
> struct asdf {
> int a; int b;
> };
>

I ren C er der tre namespaces, variable namespace, structure namespace og
type namespace.
i C++ er det to sidste kortsluttet.

Det vil sige at i ren C skal man bruge typedef konstruktionen for at kunne
tilgå din asdf struktur som en type, det behøver man ikke i C++ da
structures automatisk er typer.

Hvis man kun har brugt struct erklæringen i C skal man for at instantiere en
variable af denne skrive noget ala.
--
struct asdf min_struct;
--
Har man brugt typedef erklæringen i C eller benyttet C++ kan man skrive:
--
asdf min_struct;
--

> Jeg har hørt at det er pga parameteroverførsel ifb med gamle c-kompilere.
> Har det noget på sig?
> void do_something(asdf* aa); // skal være typedef versionen på gamel c
> kompilere ?

Ja er asdf ikke typedefet skal der stå:
--
void do_something (struct asdf *aa);
--
Den slags kode ser man masser af i unix kildetekster.

Der er det heller ikke uset at man har både en struktur, en type og en
variabel med samme navn.
Så er mulighederne for misforståelser nemlig størst

med venlig hilsen
Jesper Wolf Jespersen



Byrial Jensen (09-01-2003)
Kommentar
Fra : Byrial Jensen


Dato : 09-01-03 19:33

Jesper Wolf Jespersen <oz8ace@qsl.net.spam> skrev:

> I ren C er der tre namespaces, variable namespace, structure namespace og
> type namespace.

Det er ikke helt korrekt. I C er der følgende namespaces:

- ét for navne på labels
- ét for navne (såkaldte tags) for struct's, union's og enum's
- ét for hver eneste struct og union til medlemmerne af pågældende
struct hhv. union
- ét for alle øvrige identifikatorer (typenavne, simple variabler,
arrays, enum-konstanter)

Dertil kommer makronavne og makroparametre som behandles særskilt
af præprocessoren.

Helge Jensen (09-01-2003)
Kommentar
Fra : Helge Jensen


Dato : 09-01-03 14:09

Troels Thomsen wrote:
> Hvorfor er det nu man af og til bruger:
>
> typedef struct asdf_tag {
> int a; int b;
> }asdf;

Fordi nogen ikke ved, at man kan skrive?

typedef struct asdf { ... } asdf;
^^^^---------^^^^

for herefter:

1. predeclare "struct adsf" i C/C++ kode
2. bruge adsf som navn for typen "struct adsf", så man slipper for at
skrive "foo(struct adsf)" i C kode

--
Helge


Søg
Reklame
Statistik
Spørgsmål : 177500
Tips : 31968
Nyheder : 719565
Indlæg : 6408518
Brugere : 218887

Månedens bedste
Årets bedste
Sidste års bedste