Variable and typename naming

E

Edward Gregor

In C, if I want similar names for typename and variable,
is there any good way you can recommend me to do that?

For example, I have a struct containing a region, which
I have named it, appropriately, struct region, now when I
declare variables, I want to have the same, or a very
similar name, since I can't come up with another good name.

Now, because the different namespaces, I could declare it
struct region region.
But maybe that is obscure and bad coding practice?
Or maybe put a captial letter in the typename, like
struct Region region, or even a
typedef struct region { ... } Region. I don't know,
so I'm grateful for answers.

Thanks!
 
W

Walter Roberson

In C, if I want similar names for typename and variable,
is there any good way you can recommend me to do that?
For example, I have a struct containing a region, which
I have named it, appropriately, struct region, now when I
declare variables, I want to have the same, or a very
similar name, since I can't come up with another good name.
Now, because the different namespaces, I could declare it
struct region region.
But maybe that is obscure and bad coding practice?
Yeah.

Or maybe put a captial letter in the typename, like
struct Region region, or even a
typedef struct region { ... } Region. I don't know,
so I'm grateful for answers.

It isn't uncommon to use slightly different forms for different
logical layers. For example, some people might use

struct region_s { ... };
typedef struct region_s region_t;
region_t region;

There are different naming systems in use, especially when
it comes to procedures. For example, some people
runthenamestogether, some people CapitalizeEachWord,
some people use_underscores_between_words, some name
procedures with a suffix combination that indicates the types
it operates on; and some people impose the requirement that
a procedure name must either be a verb (e.g., die()) or else
must be a clause indicating a verb and a (possibly qualified) noun
(e.g., TotalSalaries, print_small_cheques). [People who do that
often also have particular format requirements for object identifiers.]
 
E

Edward Gregor

Walter said:
struct region_s { ... };
typedef struct region_s region_t;
region_t region;

What would the _s and _t suffices stand for in this example?

Thanks for the help!
 
K

Keith Thompson

Edward Gregor said:
What would the _s and _t suffices stand for in this example?

struct and type or typedef, respectively.

(Personally, I wouldn't bother with the typedef. "struct region" is a
perfectly good name for the type; there's little advantage in
inventing another name for it.)
 
W

Walter Roberson

struct and type or typedef, respectively.
(Personally, I wouldn't bother with the typedef. "struct region" is a
perfectly good name for the type; there's little advantage in
inventing another name for it.)

I know some people have posted along those lines in the past. I
can't say as I agree with that viewpoint, though.

A typedef can be viewed as an abstract type name: once something
has been typedef'd, one can use the type name in user code without
any consideration of what is "underneath the hood".

"struct region" on the other hand requires that one knows something
about what is under the hood -- namely that it is a struct. At
the very least, that tells you some things that the implementation
-cannot- do with it, such as arithmetic operations. That level of
knowledge is none of the business of the user code that just needs
the name of an abstract data type.

One could, I suppose, go ahead and declare that -all- abstract data
types names in a program shall be struct tags, so as to put everything
on an equal footing. It seems to me, though, that doing so would
merely increase the amount of typing, and would make it more of
a nuisance at the implementation level, since one would have to
put in a tag reference even if the underpinings turned out to be
an arithmetic type. typedef'ing a struct tag into type name
does not have those disadvantages.

But then, what do I know? My courses were way back in the days when
Aho, Hopcroft and Ullman were cutting edge.
 
K

Keith Thompson

I know some people have posted along those lines in the past. I
can't say as I agree with that viewpoint, though.

A typedef can be viewed as an abstract type name: once something
has been typedef'd, one can use the type name in user code without
any consideration of what is "underneath the hood".

"struct region" on the other hand requires that one knows something
about what is under the hood -- namely that it is a struct. At
the very least, that tells you some things that the implementation
-cannot- do with it, such as arithmetic operations. That level of
knowledge is none of the business of the user code that just needs
the name of an abstract data type.
[snip]

Yes, If you want an abstract data type, a typedef is just the thing.
(FILE in <stdio.h> is a good example of this.)

If the code using the type needs to know that it's a struct (e.g., if
it refers to its members), a typedef isn't particularly helpful.

(Possibly a lot of things *should* be abstract types that aren't.)
 
A

August Karlstrom

Edward said:
In C, if I want similar names for typename and variable,
is there any good way you can recommend me to do that?

For example, I have a struct containing a region, which
I have named it, appropriately, struct region, now when I
declare variables, I want to have the same, or a very
similar name, since I can't come up with another good name.

What's wrong with `r'?
Now, because the different namespaces, I could declare it
struct region region.
But maybe that is obscure and bad coding practice?
Or maybe put a captial letter in the typename, like
struct Region region, or even a
typedef struct region { ... } Region. I don't know,
so I'm grateful for answers.

I would do

typedef struct region Region;
struct region
{
...
};


August
 
B

Bill Pursell

Walter said:
It isn't uncommon to use slightly different forms for different
logical layers. For example, some people might use

struct region_s { ... };
typedef struct region_s region_t;
region_t region;
From the info page for libc:
"Some additional classes of identifier names are reserved for future
extensions to the C language or the POSIX.1 environment. While using
these names for your own purposes right now might not cause a problem,
they do raise the possibility of conflict with future versions of the C
or POSIX standards, so you should avoid these names.
[snip]
* Names that end with `_t' are reserved for additional type names."

Does this state that you should not roll your own type def with a
suffix
"_t", or by "additional type names" is it in fact referring to your own
additional type names and recommending "_t" as a suffix?

Is that info page relevant to the standard? (I'm getting it from a
stock Fedora installation.)
 
C

Chris Torek

I know some people have posted along those lines in the past. I
can't say as I agree with that viewpoint, though.

A typedef can be viewed as an abstract type name: once something
has been typedef'd, one can use the type name in user code without
any consideration of what is "underneath the hood".

But so can a "struct". After all, "struct" stands for "STRange
spelling for User-defined abstraCt Type", as you can see from the
uppercased letters in the phrase. :)

Note that "struct <identifier> {" actually *does* define a new
type (typedef does not -- in the sequence "typedef struct <id> {"
it is the "struct ... {" part that defines the type). This new
type is different from, and incompatible with, all other
differently-named types:

struct time { double val; };
struct temperature { double val; };
struct money { double val; };

gives you three incompatible types, so that you cannot assign a
"temperature" to a "time", for instance.

In addition, structs allow (but do not require) you to make the
type completely opaque, by omitting the "{ <contents> }" part:

struct schedule;

Now "schedule" is an opaque type; none of its members can be
modified. This enforces the abstract-ness: not only *should*
you not inspect the innards, you *can*not.

The one big flaw in this technique occurs in C89, where it is
impossible to create constants that have a structure type. This
is fixed in C99, with its "compound literals".
"struct region" on the other hand requires that one knows something
about what is under the hood -- namely that it is a struct. At
the very least, that tells you some things that the implementation
-cannot- do with it, such as arithmetic operations. That level of
knowledge is none of the business of the user code that just needs
the name of an abstract data type.

One could, I suppose, go ahead and declare that -all- abstract data
types names in a program shall be struct tags, so as to put everything
on an equal footing.

Yes; and I tend to argue for this, except where the convenience of
exposing the hidden mechanisms underlying the type (so that it is
*not* an "abstract" type after all) is sufficiently compelling.
If the user is allowed to "know" that the type is integral,
floating-point, pointer-y, or similar, and make use of that knowledge
(e.g., by incrementing variables of that type), then -- and only
then -- does it really become a candidate for "typedef"ing.
It seems to me, though, that doing so would
merely increase the amount of typing, and would make it more of
a nuisance at the implementation level, since one would have to
put in a tag reference even if the underpinings turned out to be
an arithmetic type. typedef'ing a struct tag into type name
does not have those disadvantages.

If you write, e.g.:

temperature_type x, y, z;
...
z = x + y;

you have demonstrated that "temperatures" are not abstract after
all and can simply be summed (which is not generally true of
temperatures, except if expressed in Kelvin or Rankine or similar).
So I would say, instead, "using a struct tag does not have that
disadvantage". :)
 
P

pete

Bill said:
Walter said:
It isn't uncommon to use slightly different forms for different
logical layers. For example, some people might use

struct region_s { ... };
typedef struct region_s region_t;
region_t region;
From the info page for libc:
"Some additional classes of identifier names are reserved for future
extensions to the C language or the POSIX.1 environment. While using
these names for your own purposes right now might not cause a problem,
they do raise the possibility of conflict with future versions of the C
or POSIX standards, so you should avoid these names.
[snip]
* Names that end with `_t' are reserved for additional type names."

Does this state that you should not roll your own type def with a
suffix
"_t", or by "additional type names" is it in fact referring to your own
additional type names and recommending "_t" as a suffix?

Is that info page relevant to the standard? (I'm getting it from a
stock Fedora installation.)

I have enough respect for POSIX
to use a more spelled out "_type" suffix instead,
as in e_type or d_type, even though I don't anticipate
writing any code for POSIX in the forseeable future.
 
H

Herbert Rosenau

In C, if I want similar names for typename and variable,
is there any good way you can recommend me to do that?

For example, I have a struct containing a region, which
I have named it, appropriately, struct region, now when I
declare variables, I want to have the same, or a very
similar name, since I can't come up with another good name.

Now, because the different namespaces, I could declare it
struct region region.
But maybe that is obscure and bad coding practice?
Or maybe put a captial letter in the typename, like
struct Region region, or even a
typedef struct region { ... } Region. I don't know,
so I'm grateful for answers.

I'm trained in to use only capital letters for macro names and self
defined types.


--
Tschau/Bye
Herbert

Visit http://www.ecomstation.de the home of german eComStation
eComStation 1.2 Deutsch ist da!
 
P

pemo

In addition, structs allow (but do not require) you to make the
type completely opaque, by omitting the "{ <contents> }" part:

struct schedule;

Now "schedule" is an opaque type; none of its members can be
modified. This enforces the abstract-ness: not only *should*
you not inspect the innards, you *can*not.

<snip>

In APIs such as those provided for Windows, opaque types were at one time
*not* defined as /empty structs/ - in the end-user's header files - but
rather as unsigned longs, e.g., a HANDLE type was typically defined as:
typedef unsigned long HANDLE;

Now, when some OS API put some value into one of these HANDLEs the
programmer had no idea as to its /meaning/, i.e., it could have been an
index into some internal OS table, a pointer to a struct, some just a
number, ... whatever: being /just/ a long gave very little clue as to its
use/implmentation.

However, nowadays, I think, MS exposes most of its HANDLEs like this:

#define DECLARE_HANDLE(name) struct name##__ { int unused; }; typedef struct
name##__ *name

Laying that out a little clearer [yes I know about the excess spaces in the
macro!]

#define DECLARE_HANDLE(name) \
\
struct name##__ \
{ \
int unused; \
\
}; \
\
typedef struct name##__ * name

So, nowadays they/you use this like this:

DECLARE_HANDLE(HANDLE);

HANDLE hThingmy;

Two questions from this then.

1. Although a Windows' API can still return any of the list above [an index
into some internal OS table, a pointer to a struct, some just a number, ...]
in the /guise/ of *this* type of HANDLE, it does seem to me that it
encourage the consumer to at least /initially think/ of some handle type as
[probably] some sort of struct pointer - and thus, it /perhaps/ encourages
the same person to explore [hack] these - so, why drop the simple /disguise/
of using an unsigned long [or some other /plain/ type capable of holding as
pointer] in favour of an opaque struct?

2. Why does MS use an int unused member when they could simply leave the
struct empty - compatibility of some sort?
 
C

Chris Torek

In APIs such as those provided for Windows, opaque types were at one time
*not* defined as /empty structs/ - in the end-user's header files - but
rather as unsigned longs, e.g., a HANDLE type was typically defined as:
typedef unsigned long HANDLE;

Now, when some OS API put some value into one of these HANDLEs the
programmer had no idea as to its /meaning/, i.e., it could have been an
index into some internal OS table, a pointer to a struct, some just a
number, ... whatever: being /just/ a long gave very little clue as to its
use/implmentation.

However, nowadays, I think, MS exposes most of its HANDLEs like this: [edited slightly]
#define DECLARE_HANDLE(name) struct name##__ { int unused; }; \
typedef struct name##__ *name ...
So, nowadays they/you use this like this:

DECLARE_HANDLE(HANDLE);

HANDLE hThingmy;

Two questions from this then.

I have a third one: why bother appending the double underscore? :)
1. [snippage ...] why drop the simple /disguise/
of using an unsigned long [or some other /plain/ type capable of holding as
pointer] in favour of an opaque struct?

I cannot answer for them, but there is no guarantee that there is
any appropriate integer type (even C99 does not require that there
*be* an "intptr_t"), and if there is, why do a lot of work to
dig it out when you can just use "struct opaque *"?
2. Why does MS use an int unused member when they could simply leave the
struct empty - compatibility of some sort?

This one is easy enough: an empty struct -- struct foo {} -- is not
syntactically valid. If you meant "why not just leave the type
incomplete", that I cannot answer.
 
D

Dave Thompson

However, nowadays, I think, MS exposes most of its HANDLEs like this:

#define DECLARE_HANDLE(name) struct name##__ { int unused; }; typedef struct
name##__ *name
So, nowadays they/you use this like this:

DECLARE_HANDLE(HANDLE);

HANDLE hThingmy;

Two questions from this then.

1. Although a Windows' API can still return any of the list above [an index
into some internal OS table, a pointer to a struct, some just a number, ...]
in the /guise/ of *this* type of HANDLE, it does seem to me that it
encourage the consumer to at least /initially think/ of some handle type as
[probably] some sort of struct pointer - and thus, it /perhaps/ encourages
the same person to explore [hack] these - so, why drop the simple /disguise/
of using an unsigned long [or some other /plain/ type capable of holding as
pointer] in favour of an opaque struct?
Perhaps because struct uniquetag ... is a new type in C, whereas
typedef anything is not. This allows/requires the compiler to detect
if you try to misuse one type of handle (pointer) to a different one.
2. Why does MS use an int unused member when they could simply leave the
struct empty - compatibility of some sort?

Standard C doesn't allow a struct (or union) with no members. <OT>C++
does, and has sensible uses for struct/class with no explicit members
and/or no data members at all.</> They don't need or want
Windows-specific declarations portable to other systems, but might
want them to work on other Windows-targetable compiler(s) like GCC.

- David.Thompson1 at worldnet.att.net
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
474,183
Messages
2,570,965
Members
47,511
Latest member
svareza

Latest Threads

Top