473,799 Members | 3,270 Online
Bytes | Software Development & Data Engineering Community
+ Post

Home Posts Topics Members FAQ

Question about a struct declaration

In C, if i want to declare a struct, there are 3 methods to do so:

1: struct dummy { ... };
2: typedef struct { ... } dummy;
3: typedef struct _dummy { ... } dummy;

Usually i use the first method to declare my structs, but in many open
source projects (such as libxml2), the third method is used. I am just
curious about the difference.. Would somebody tell me which method is
recommended, and why? Thanks in advance.

ZHENG Zhong
Jun 27 '08
21 2012
Andrey Tarasevich said:
Richard Heathfield wrote:
>...
Er... I disagree.

Well, then, can you come up with a different implementation hiding
technique that would satisfy the following two requirements:

1) Client code can define objects of type 'T'
2) Client code doesn't see the implementation details of the concept
type 'T' represents
?
Yes, by carefully interpreting your words in a way convenient to myself. I
choose to interpret 'define' as meaning 'create via a function' (which is
completely at odds with our usual meaning of 'define', as you don't have
to remind me), and I choose not to count structness as an implementation
detail. Given those weasel words, I can do it:

Interface:

struct T_;

typedef struct T_ T;

T *t_create(whate ver);
void t_destroy(T **);
int t_use(T *, whatever);
etc

Implementation: hidden :-)
Hide the pointeriness? No, it actually _doesn't_ hide the pointeriness.
The pointeriness will be clearly visible in the interface header, in the
typedef.
Right, so you gain nothing in terms of information hiding, but lose the
convenience to the user-programmer of being reminded through usage that
he's dealing with a here-be-dragons pointer.
>>a pointer
hidden in a typedef is a standard, widely used and accepted idiom.
Yeah, well, I've only got one pair of 'ands, ain't I?

I don't know what to say...
Translation: it's going to take me a long time to persuade everyone /not/
to accept that idiom, working alone. (Especially as I'm not actually all
that fussed about it, certainly not enough to commit my declining years to
a one-man anti-hiding-pointers-in-typedefs crusade.)

--
Richard Heathfield <http://www.cpax.org.uk >
Email: -http://www. +rjh@
Google users: <http://www.cpax.org.uk/prg/writings/googly.php>
"Usenet is a strange place" - dmr 29 July 1999
Jun 27 '08 #11
Andrey wrote:
) Richard Heathfield wrote:
)...
)Er... I disagree.
)
) Well, then, can you come up with a different implementation hiding
) technique that would satisfy the following two requirements:

Richard doesn't want you not to use typedef'd pointers like that,
he wants you to typedef the pointer as typedef T <something>
and then have the client code use it as *T

In other words: hide the type, but don't hide the pointeryness.
At least I think that's what he means.
SaSW, Willem
--
Disclaimer: I am in no way responsible for any of the statements
made in the above text. For all I know I might be
drugged or something..
No I'm not paranoid. You all think I'm paranoid, don't you !
#EOT
Jun 27 '08 #12
Andrey Tarasevich <an************ **@hotmail.comw rites:
Richard Heathfield wrote:
>...
Er... I disagree.

Well, then, can you come up with a different implementation hiding
technique that would satisfy the following two requirements:

1) Client code can define objects of type 'T'
2) Client code doesn't see the implementation details of the concept
type 'T' represents
?

I actually can do that, but one alternative technique I know is no
better then a typedef-ed pointer.
>>If want to use the type as a pointer (i.e. keep its pointer nature
exposed to the client), then hiding the fact that it is a pointer in a
typedef is indeed a pretty useless idea.

However, if you want to declare a generic "handle" type, whose specific
nature is not supposed to be exploited by the user in any way,

...it's *still* a bad idea to hide pointeriness from the user - in
my opinion, of course. This is, however, not a matter of C
correctness.

Hide the pointeriness? No, it actually _doesn't_ hide the
pointeriness. The pointeriness will be clearly visible in the
interface header, in the typedef.
Exactly. Its not clearly indicated at the line its used. Its one of the
few times I would agree with Heathfield on a style issue. In the same
vein I despise C++ for allowing operator overloading - its nigh on
impossible to "read" the code unless you have the brain the size of a
planet and have memorized all the class subtleties. its also why I
always "read" code in a debugger by stepping through. Those nice little
"variable changed" indicators are a great help.

Jun 27 '08 #13
Willem said:
Andrey wrote:
) Richard Heathfield wrote:
)...
)Er... I disagree.
)
) Well, then, can you come up with a different implementation hiding
) technique that would satisfy the following two requirements:

Richard doesn't want you not to use typedef'd pointers like that,
he wants you to typedef the pointer as typedef T <something>
and then have the client code use it as *T
Um, not quite. I *don't* want to typedef the pointer in any way at all.
Rather, I want to expose the pointeriness (or, if you prefer,
pointeryness), by leaving the * out of the typedef altogether, and letting
the user-programmer stick it in instead.
In other words: hide the type, but don't hide the pointeryness.
Right, that's a fair description.
At least I think that's what he means.
So does he (well, the "in other words" bit, anyway).

--
Richard Heathfield <http://www.cpax.org.uk >
Email: -http://www. +rjh@
Google users: <http://www.cpax.org.uk/prg/writings/googly.php>
"Usenet is a strange place" - dmr 29 July 1999
Jun 27 '08 #14
Richard Heathfield wrote:
) Um, not quite. I *don't* want to typedef the pointer in any way at all.
) Rather, I want to expose the pointeriness (or, if you prefer,
) pointeryness), by leaving the * out of the typedef altogether, and letting
) the user-programmer stick it in instead.

Er, yes, that was poorly worded of me. I meant to say what you just said.
SaSW, Willem
--
Disclaimer: I am in no way responsible for any of the statements
made in the above text. For all I know I might be
drugged or something..
No I'm not paranoid. You all think I'm paranoid, don't you !
#EOT
Jun 27 '08 #15
Richard Heathfield wrote:
>Well, then, can you come up with a different implementation hiding
technique that would satisfy the following two requirements:
...
Yes, by carefully interpreting your words in a way convenient to myself.
...
Sigh...
>Hide the pointeriness? No, it actually _doesn't_ hide the pointeriness.
The pointeriness will be clearly visible in the interface header, in the
typedef.

Right, so you gain nothing in terms of information hiding,
Of course, I don't. The point is to actually _lose_ a little bit of that
information hiding, unhide it in a reasonably controlled fashion.
"Informatio n hiding" is not always as black-and-white as "hide
everything" vs. "expose everything", you know.
but lose the
convenience to the user-programmer of being reminded through usage that
he's dealing with a here-be-dragons pointer.
Reminded through usage? How? A pointer to an undefined type cannot be
used in any truly pointer-specific way, i.e. it can't be meaningfully
dereferenced. Whatever usage I mentioned before is not really
pointer-specific, in a sense that it can also be applied to an integer type.
Translation: it's going to take me a long time to persuade everyone /not/
to accept that idiom, working alone.
I'd say you'd have to spend more effort fighting the "prior art",
including but not limited to the aforementioned pthreads library and
standard library implementations that typedef our beloved 'va_list' as a
pointer type.

--
Best regards,
Andrey Tarasevich
Jun 27 '08 #16
Richard wrote:
>Hide the pointeriness? No, it actually _doesn't_ hide the
pointeriness . The pointeriness will be clearly visible in the
interface header, in the typedef.

Exactly. Its not clearly indicated at the line its used. Its one of the
few times I would agree with Heathfield on a style issue.
It is not a style issue. It is an issue of implementing a given abstract
specification. Some abstract specification of some library exposes type
'T' and objects of type 'T' have to be user-definable and at the same
the inner workings of what's really hiding behind 'T' needs (is
preferred) to be hidden from the user (I already provided examples:
'pthread_t' in 'ptherads', or simply 'va_list' in our standard library).
The perfectly viable approach in this case is to use a typedef-ed
pointer to an undefined struct. There's no style issues here, and even
if someone is still inclined to see "style issues" here for some reason,
they are largely secondary.

--
Best regards,
Andrey Tarasevich
Jun 27 '08 #17
Andrey Tarasevich <an************ **@hotmail.comw rites:
Richard wrote:
>>Hide the pointeriness? No, it actually _doesn't_ hide the
pointerines s. The pointeriness will be clearly visible in the
interface header, in the typedef.

Exactly. Its not clearly indicated at the line its used. Its one of the
few times I would agree with Heathfield on a style issue.

It is not a style issue. It is an issue of implementing a given
abstract specification. Some abstract specification of some library
exposes type 'T' and objects of type 'T' have to be user-definable and
at the same the inner workings of what's really hiding behind 'T'
needs (is preferred) to be hidden from the user (I already provided
examples: 'pthread_t' in 'ptherads', or simply 'va_list' in our
standard library). The perfectly viable approach in this case is to
use a typedef-ed pointer to an undefined struct. There's no style
issues here, and even if someone is still inclined to see "style
issues" here for some reason, they are largely secondary.
Aha. I follow you now. Thanks for the explanation.
Jun 27 '08 #18
Richard Heathfield <rj*@see.sig.in validwrites:
Andrey Tarasevich said:
<snip>

However, if one day you'll need to do something like that

typedef struct dummy *dummy;

Please don't hide pointers in typedefs.
and use it as a dual-language header (C and C++) you'll run into
problems with C++, wince in C++ the latter declaration is illegal. If
this is an issue in your case, then it is a good idea to choose
different identifiers for struct tag and the typedef name. Otherwise,
the same identifier can safely be used (unless I'm missing some other
issue).
[...]

Hiding pointers in typedefs is *usually* a bad idea. The only
exception is when you want the type to be opaque, meaning that client
code will never treat it as a pointer. A more common approach is to
export a pointer to an opaque type, such as stdio's FILE*, but making
the pointer type itself opaque isn't necessarily evil.

(I suppose "isn't necessarily evil" might not be the highest praise I
could have offered.)

But the real problem with

typedef struct dummy *dummy;

is that the identifier "dummy" is used both for the struct tag and for
a *pointer to* the struct type. It's common to use the same identifier
for a struct tag and a pointer to the struct, as in:

typedef struct dummy dummy;

But making "struct dummy" a struct and "dummy" a pointer will only
cause confusion, whether you're trying to write dual-language code or
not. Pick two different names.

I think the generic word "dummy" obscured the problem in this case.
In real life, the name(s) would be more descriptive, perhaps something
like:

typedef struct widget_info *handle;

--
Keith Thompson (The_Other_Keit h) ks***@mib.org <http://www.ghoti.net/~kst>
Nokia
"We must do something. This is something. Therefore, we must do this."
-- Antony Jay and Jonathan Lynn, "Yes Minister"
Jun 27 '08 #19
In article <lz************ @stalkings.ghot i.net>,
Keith Thompson <ks*@cts.comwro te:
>Hiding pointers in typedefs is *usually* a bad idea.
Nonsense!
>The only
exception is when you want the type to be opaque, meaning that client
code will never treat it as a pointer.
Much more reasonable.

In my experience, creating opaque types is the *usual* reason for
typedefing pointers, so it is *usually* a good idea...
>But the real problem with

typedef struct dummy *dummy;

is that the identifier "dummy" is used both for the struct tag and for
a *pointer to* the struct type.
I don't see that as a problem - "dummy" is the pointer type and
"struct dummy" is the struct type. Used consistently, that would be a
perfectly reasonable convention. The usual, opaque, use has the short
name, and the rare, struct, use has "struct" to draw attention to it.
>It's common to use the same identifier
for a struct tag and a pointer to the struct, as in:

typedef struct dummy dummy;
Again, I don't find that "common". Increasingly libraries export
mostly-opaque types, and client programs rarely have occasion to
use the struct type itself.

-- Richard
--
:wq
Jun 27 '08 #20

This thread has been closed and replies have been disabled. Please start a new discussion.

Similar topics

24
2111
by: ark | last post by:
Hello group, Could you help me with this: static const int x; ............ something ............. static const int x = 17; It looks perfectly legal to me but MSVC/C++ 6.0 gives, on the first line, "warning C4132: 'x' : const object should be initialized" yet generates correct code.
5
3307
by: PCHOME | last post by:
Hello! I am working on dividing a single C file into several files. Now I encounter a problem about the global variables and can not find a way to solve it. All global variables and codes used to be in that single file, that worked OK. But when I divdie that file into several ones, I have many "invalid use of undefined type" errors. The four files are main.c, main.h, readLP.h, and readLP.c. In readLP.h
6
2692
by: S.Tobias | last post by:
I'm trying to understand how structure type completion works. # A structure or union type of unknown # content (as described in 6.7.2.3) is an incomplete type. It # is completed, for all declarations of that type, by ^^^ # declaring the same structure or union tag with its defining # content later in the same scope. ^^^^^ (6.2.5#23)
10
5828
by: James Brown | last post by:
I have the following enum declared: enum TOKEN { TOK_ID = 1000, TOK_NUMBER, TOK_STRING }; (it goes on and on like that) This is what I would like to do: TOKEN t1 = TOK_ID; // ok TOKEN t2 = 5; // compile error (cannot convert from
15
1859
by: sethukr | last post by:
Hi everybody, While running the following program in GCC, i'm very much screwed. main() { char *ptr1; char arr; int i; char *ptr2;
4
2090
by: Marcin Kasprzak | last post by:
Hello Guys, Silly question - what is the most elegant way of compiling a code similar to this one? <code> typedef struct a { b_t *b; } a_t; typedef struct b {
10
2245
by: Raman | last post by:
Hi All, Is it valid: struct test{ }; I mean, Can we have a struct containing no members? Is this a an
8
1574
by: Chad | last post by:
Given the following..... #include <stdlib.h> #include <stdio.h> struct node { int data; struct node *next; };
4
1499
by: Richard Harter | last post by:
I have a couple of questions about the following code fragment: struct list_info { void * first; void * last; }; struct pipe_data_list { void * data; struct agent_port_list * dest;
0
9544
by: Hystou | last post by:
Most computers default to English, but sometimes we require a different language, especially when relocating. Forgot to request a specific language before your computer shipped? No problem! You can effortlessly switch the default language on Windows 10 without reinstalling. I'll walk you through it. First, let's disable language synchronization. With a Microsoft account, language settings sync across devices. To prevent any complications,...
0
10490
Oralloy
by: Oralloy | last post by:
Hello folks, I am unable to find appropriate documentation on the type promotion of bit-fields when using the generalised comparison operator "<=>". The problem is that using the GNU compilers, it seems that the internal comparison operator "<=>" tries to promote arguments from unsigned to signed. This is as boiled down as I can make it. Here is my compilation command: g++-12 -std=c++20 -Wnarrowing bit_field.cpp Here is the code in...
0
10259
jinu1996
by: jinu1996 | last post by:
In today's digital age, having a compelling online presence is paramount for businesses aiming to thrive in a competitive landscape. At the heart of this digital strategy lies an intricately woven tapestry of website design and digital marketing. It's not merely about having a website; it's about crafting an immersive digital experience that captivates audiences and drives business growth. The Art of Business Website Design Your website is...
0
10030
tracyyun
by: tracyyun | last post by:
Dear forum friends, With the development of smart home technology, a variety of wireless communication protocols have appeared on the market, such as Zigbee, Z-Wave, Wi-Fi, Bluetooth, etc. Each protocol has its own unique characteristics and advantages, but as a user who is planning to build a smart home system, I am a bit confused by the choice of these technologies. I'm particularly interested in Zigbee because I've heard it does some...
0
9077
agi2029
by: agi2029 | last post by:
Let's talk about the concept of autonomous AI software engineers and no-code agents. These AIs are designed to manage the entire lifecycle of a software development project—planning, coding, testing, and deployment—without human intervention. Imagine an AI that can take a project description, break it down, write the code, debug it, and then launch it, all on its own.... Now, this would greatly impact the work of software developers. The idea...
0
6809
by: conductexam | last post by:
I have .net C# application in which I am extracting data from word file and save it in database particularly. To store word all data as it is I am converting the whole word file firstly in HTML and then checking html paragraph one by one. At the time of converting from word file to html my equations which are in the word document file was convert into image. Globals.ThisAddIn.Application.ActiveDocument.Select();...
0
5467
by: TSSRALBI | last post by:
Hello I'm a network technician in training and I need your help. I am currently learning how to create and manage the different types of VPNs and I have a question about LAN-to-LAN VPNs. The last exercise I practiced was to create a LAN-to-LAN VPN between two Pfsense firewalls, by using IPSEC protocols. I succeeded, with both firewalls in the same network. But I'm wondering if it's possible to do the same thing, with 2 Pfsense firewalls...
0
5589
by: adsilva | last post by:
A Windows Forms form does not have the event Unload, like VB6. What one acts like?
3
2941
bsmnconsultancy
by: bsmnconsultancy | last post by:
In today's digital era, a well-designed website is crucial for businesses looking to succeed. Whether you're a small business owner or a large corporation in Toronto, having a strong online presence can significantly impact your brand's success. BSMN Consultancy, a leader in Website Development in Toronto offers valuable insights into creating effective websites that not only look great but also perform exceptionally well. In this comprehensive...

By using Bytes.com and it's services, you agree to our Privacy Policy and Terms of Use.

To disable or enable advertisements and analytics tracking please visit the manage ads & tracking page.