typedef "byte", "word" etc.

M

Mark

Hello

reading the article
http://www.ibm.com/developerworks/power/library/pa-ctypes4/index.html?S_TACT=105AGX16&S_CMP=EDU
by Peter Seebach, I stuck with his disapproval of typedef'ing bytes or
words.

Quoting:
"...many programmers will come up with typedefs with names such as "byte" or
"word," then use those for everything, and change only the typedefs when
going to a new platform. This is an exceptionally bad idea.
It might not seem immediately obvious why this is such a bad idea. Part of
the problem is that why it's a bad idea depends on how you're using it. If
you're using "word" to refer to "an object that is exactly the native word
size of our first platform," then on other platforms, you have a typedef
"word" that represents something which isn't a native word..."

I don't quite understand his point, what's so wrong about defining bytes or
words in its native representation for *each* platform, except that the
names are quite lame IMHO?
 
N

Nick Keighley

reading the articlehttp://www.ibm.com/developerworks/power/library/pa-ctypes4/index.html...
by Peter Seebach, I stuck with his disapproval  of typedef'ing bytes or
words.

Quoting:
"...many programmers will come up with typedefs with names such as "byte" or
"word," then use those for everything, and change only the typedefs when
going to a new platform. This is an exceptionally bad idea.

well it's a bad idea...

I quite like Byte (or Octet if I'm being really retentive) because I
deal with bytes a lot and unsigned char is a lot of typeing and not
really domain specific. I also usually stick an assert or runtime
equivalent
in to handle the remote possibility that the code gets ported to
something
where unsigned char isn't 8-bits.

But I *hate* Udword and similar stuff (I originally used a shorter
word
than "stuff").

This bit me once

CellNumber readDT (FILE *source)
{
CellNumber cell_number;
fscanf (source, "%d", &cell_number);
return cell_number;
}

there was error handling. CellNumber is a small integer. So what is
the
problem? CellNumber was actually a short.
It might not seem immediately obvious why this is such a bad idea.

It's uneccessarily obscure without buying you anything in the way of
making it more domain specific.
Part of
the problem is that why it's a bad idea depends on how you're using it. If
you're using "word" to refer to "an object that is exactly the native word
size of our first platform," then on other platforms, you have a typedef
"word" that represents something which isn't a native word..."

I don't quite understand his point, what's so wrong about defining bytes or
words in its native representation for *each* platform, except that the
names are quite lame IMHO?

I use the rules (when I don't have a standard imposed on me)

if it's a small (<10000) integer use int
if it's a large (ie. not small) integer use long
in theory a small integer where space is tight use short
(but in reality this rule never gets used)
if it's a floating point variable use double
if it's a character use char
if it's an octet that escapes into the real world use unsigned
char

Byte/Octet and Bool are typedefs

The typedef everything to Udward/int32 is just pushing implementaion
details
into what should be application specific code.

I even worked on a project where you couldn't check stuff in if
it used basic C types
 
B

Beej Jorgensen

Mark said:
http://www.ibm.com/developerworks/power/library/pa-ctypes4/index.html?S_TACT=105AGX16&S_CMP=EDU

I don't quite understand his point, what's so wrong about defining bytes or
words in its native representation for *each* platform, except that the
names are quite lame IMHO?

I think his issue (and I think he has a point) is that the definition of
WORD is so imprecise. He seems fine with the other types, like
int_least16_t and int32_t. As for BYTE, we can probably just typedef it
from "unsigned char" and be portably done with it, as the C standard is
pretty clear about that one.

Now to derail this thread, the author of that article also states:

One key aspect of the C type system is its extensibility. You can
declare a new type using the typedef keyword, and then use it
transparently thereafter. Unfortunately, most compilers do not give
you any extra type checking from the use of typedef. For instance,
if you define two types which are both equivalent to int, the
compiler probably won't warn you if you mix them.

typedef int foo;
typedef int bar;
foo *a;
bar b;
a = &b;

This code is semantically incorrect, but it is likely to compile
without warnings. Don't count on the compiler's type-checking to
catch mistakes like this.

I think he might have made a mistake here. He says, "You can declare a
new type using the typedef keyword", however, the Standard explicitly
states:

# C99 6.7.7p3
# A typedef declaration does not introduce a new type, only a synonym
# for the type so specified.

If both foo and bar are synonyms for int, I don't see why a complier
should even begin to think about complaining in the author's example, as
he implies it should.

Discussion welcomed.

-Beej
 
P

Paul N

(snip)
Now to derail this thread, the author of that article also states:

    One key aspect of the C type system is its extensibility. You can
    declare a new type using the typedef keyword, and then use it
    transparently thereafter. Unfortunately, most compilers do not give
    you any extra type checking from the use of typedef. For instance,
    if you define two types which are both equivalent to int, the
    compiler probably won't warn you if you mix them.

        typedef int foo;
        typedef int bar;
        foo *a;
        bar b;
        a = &b;

    This code is semantically incorrect, but it is likely to compile
    without warnings. Don't count on the compiler's type-checking to
    catch mistakes like this.

I think he might have made a mistake here.  He says, "You can declare a
new type using the typedef keyword", however, the Standard explicitly
states:

# C99 6.7.7p3
# A typedef declaration does not introduce a new type, only a synonym
# for the type so specified.

If both foo and bar are synonyms for int, I don't see why a complier
should even begin to think about complaining in the author's example, as
he implies it should.

I think the author is talking about a "semantic" or "conceptual" new
type, while the standard is pointing out that syntactically there
isn't actually a new type. In the same way that he says his example
code is "semantically incorrect" when it is actually valid C code. The
fact that the standard needs to point out that a new type is not
introduced suggests that they think some readers would expect that a
genuine new type was created.

It might be nice if the compiler could take a typedef as being an
indication that the programmer is trying to create a new (conceptual)
type, and perhaps to warn if the programmer seems to be messing his
types up. But this might give a lot of false positives, so the idea
would need some thinking through. I don't see it as a daft objective,
though, which you seem to.

Further discussion welcome...

Paul.
 
N

Nick Keighley

well it's a bad idea...

I quite like Byte (or Octet if I'm being really retentive) because I
deal with bytes a lot and unsigned char is a lot of typeing and not
really domain specific. I also usually stick an assert or runtime
equivalent
in to handle the remote possibility that the code gets ported to
something
where unsigned char isn't 8-bits.

But I *hate* Udword and similar stuff (I originally used a shorter
word
than "stuff").

This bit me once

CellNumber readDT (FILE *source)
{
   CellNumber cell_number;
   fscanf (source, "%d", &cell_number);
   return cell_number;

}

there was error handling. CellNumber is a small integer. So what is
the
problem? CellNumber was actually a short.


It's uneccessarily obscure without buying you anything in the way of
making it more domain specific.



I use the rules (when I don't have a standard imposed on me)

   if it's a small (<10000) integer use int
<1000

:-(

   if it's a large (ie. not small) integer use long
   in theory a small integer where space is tight use short
     (but in reality this rule never gets used)
   if it's a floating point variable use double
   if it's a character use char
   if it's an octet that escapes into the real world use unsigned
char

Byte/Octet and Bool are typedefs

The typedef everything to Udward/int32 is just pushing implementaion
details
into what should be application specific code.

I even worked on a project where you couldn't check stuff in if
it used basic C types
 
R

Rafael Anschau

I don't quite understand his point, what's so wrong about defining bytes or
words in its native representation for *each* platform, except that the
names are quite lame IMHO?

The problem is that those names are very likely to collide with names
already existing in other systems. So it´s a bad name choice to call
your own structs byte and so on because they are likely to already
exist somewhere else. In most OOP languages you can create namespaces
to avoid it, but that´s not possible in C as far as I know.
 

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

Forum statistics

Threads
473,769
Messages
2,569,582
Members
45,058
Latest member
QQXCharlot

Latest Threads

Top