--
Mark
From whom?
> I understand that it's not safe to
> rely on. for example, 'sizeof(short)' or similar, because these values
> may differ on different platforms.
Isn't that a reason *too* use sizeof?
> But are there other reasons stopping from using sizeof in everyday's code?
No
--
Ian Collins
> I once heard that use of 'sizeof' operator is frowned upon by the followers
> of defensive programming.
sounds like some sort of cult. Presumably they surround their code
with little pointy sticks.
> I understand that it's not safe to rely on.
it reliably evaluates to the size of its argument. In what way is this
unreliable?
> for
> example, 'sizeof(short)' or similar, because these values may differ on
> different platforms.
sizeof(short) may yeild different values on different platforms. In
what way would it be better to use a fixed but incorrect value?
> But are there other reasons stopping from using sizeof
> in everyday's code?
I haven't heard a reason not to use it non-everyday code (feast day
code?) yet
printf("%d\n", (int) sizeof(short) );
will usually print out the digit '2'. Occasionally you will get a '1'
or a '4', and other numbers are theoreticaly possible.
Just occasionally a difference like this will break programs.
However if you want an array of, say, 20 shorts in dynamic memory
ptr = malloc(20 * sizeof(short));
will get you a memory buffer of the right size. You don't care whether
it is 20 bytes, 40 bytes or 80 bytes. All you care is that it can hold
20 shorts. You might say "I want a 16-bit integer, not a short".
Generally, you don't. If short isn't 16 bits, then there will be a
good reason for it, eg the computer has oceans of memory, and 32 bit
reads are faster than 16 bit reads.
I once heard that if you looked at the full Moon over
your left shoulder you would be struck dead on the spot.
> I understand that it's not safe to
> rely on. for example, 'sizeof(short)' or similar, because these values
> may differ on different platforms.
Can't resist: "This is obviously some strange usage of the
word 'safe' that I wasn't previously aware of."
Seriously: One *advantage* of sizeof(short) is that it
reports the number of bytes in the implementation's version of
`short', no matter what that number might be. You cannot
"safely" write `2' lest your code find itself running on a
platform with a different-sized `short', and the `2' would be
wrong. If you write `sizeof(short)', on the other hand, you
will always get the right answer -- the answer may be different
on different platforms, but you'll get the value that's right
for the platform at hand.
Another advantage shows up when you deal with types that
are more intricate than `short' or `double' or whatever. In
`struct foo {int a; char *b; double c; short d[MAX]; }', for
example, how many bytes does a `struct foo' instance occupy?
`sizeof(struct foo)' is always right -- hence "safe" -- while
`(4+4+8+2*MAX+2+7)/8*8' is at best a guess, with lots of
opportunity for error.
> But are there other reasons stopping
> from using sizeof in everyday's code?
C has three sizeof-related traps I'm aware of. Two require
vigilance, and the other can be avoided with simple discipline.
The first is that a function parameter declared as an array
is not actually an array, but a pointer to the array's element
type. In `size_t bar(char array[42]) { return sizeof array; }'
might expect the function to return 42, the number of bytes in a
42-char array. What it actually returns, though, is the number of
bytes in a char*, a pointer to the element type; this is usually
4 or 8 (but *could* be almost anything, even 42).
The second is that until fairly recently `sizeof' never
evaluated its argument. But the C99 Standard introduced the
"variable-length array," an array whose size is given by a non-
constant run-time expression. If you apply `sizeof' to such an
array, it *does* evaluate, at least enough to figure out the
value of the size-controlling expression. And if that expression
has side-effects, re-evaluating it may be problematic.
The third is that the compiler doesn't always know that a
size is being used inappropriately. You might try to allocate
a `struct foo' instance (see above) with
struct foo *ptr;
...
ptr = malloc(sizeof(struct gizmo));
... having written the wrong type (and size) on the right-hand
side. The compiler will seldom detect this misuse. Hence, the
recommended discipline (relying on non-evaluation):
ptr = malloc(sizeof *ptr);
... and all's well again.
--
Eric Sosman
eso...@ieee-dot-org.invalid
> I once heard that use of 'sizeof' operator is frowned upon by the followers
> of defensive programming.
You heard wrong.
> I understand that it's not safe to rely on. for example, 'sizeof(short)' or
> similar, because these values may differ on different platforms.
This is exactly why you use sizeof (short), rather than a hard-coded 3.
Even better is not using sizeof (<some-type>), but sizeof <object> -
which in most practical cases boils down to sizeof *<pointer>. For
example, in
some_type *pointer1, *pointer2;
pointer1 = malloc(AMOUNT * sizeof (some_type));
pointer2 = malloc(AMOUNT * sizeof *pointer2);
both lines (try to!) allocate memory for AMOUNT objects of some_type,
but if I change the first line to
some_better_type *pointer1, *pointer2;
(for example, if I notice that my linked list is getting too slow, and I
want to change to using a balanced tree), the allocation of pointer1 is
now wrong, while that of pointer2 remains correct. Hence, using sizeof
<object> or usually sizeof *<pointer> is more sturdy and easily
maintainable than using sizeof (<type>) directly.
Richard
I don't think that's an actual problem.
Consider:
int len = 42;
double vla[len];
len ++;
The length of the VLA is determined when it's created, and the length
expression is magically stored somewhere. Changing the value of len
doesn't change the length of the array, and computing ``sizeof vla''
doesn't re-compute the expression that determined its size; it just
retrieves the stored value. If you have:
double vla[func()];
computing ``sizeof vla'' doesn't call func() again.
The C99 standard says that the argument to sizeof is evaluated if it's
a variable-length array. I can't think of a case where this actually
matters.
--
Keith Thompson (The_Other_Keith) 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"
As a shunner of VLA's I might be wrong about this, but I
think that if you apply sizeof to a VLA type rather than to an
actual array object, it can make a difference:
int len = 42;
size_t s1 = sizeof(double[len++]);
size_t s2 = sizeof(int[len++]);
assert (len == 44);
(Have I tried this? No; I haven't even compiled it.)
--
Eric Sosman
eso...@ieee-dot-org.invalid
I think I'd say the third is sizeof('a') not being sizeof(char).
Phil
--
I find the easiest thing to do is to k/f myself and just troll away
-- David Melville on r.a.s.f1
--
Mark
On related news, in some other language which shall not be named,
sizeof('a') equals sizeof(char) (which is 1).
--
Best regards, _ _
.o. | Liege of Serenly Enlightened Majesty of o' \,=./ `o
..o | Computer Science, Michal "mina86" Nazarewicz (o o)
ooo +--<mina86-tlen.pl>--<jid:mina86-jabber.org>--ooO--(_)--Ooo--
I wonder who actually writes practical programs which depends on the value
of sizeof('a').
Go find the guy who told you that and slap him silly.
> I understand that it's not safe to rely on. for
> example, 'sizeof(short)' or similar, because these values may differ on
> different platforms.
What is not safe is using 'sizeof(short)' as a substitute for 2.
Assumptions will always get you in trouble. sizeof will help you with
that, also.
> But are there other reasons stopping from using sizeof
> in everyday's code?
No. None. Zero.
Have you ever seen a macro which took the sizeof one of its object-
type arguments? The person who writes that macro is independent of
the person who finally invokes sizeof('a').
Have you ever seen such a macro invoked with a character constant
as its argument? I'm not saying it never happens, or even that
it's particularly unlikely, but I don't recall ever seeing it myself.
I don't think I've ever seen *any* real (i.e., non-contrived) code
that's broken by the difference in the semantics of sizeof('a')
between C and C++.
I like to be protected from the innards of macros, I wouldn't
necesarily recognise such an invocation were I to see one, simply
as I wouldn't tie the use of sizeof with the use of a literal char.
> I don't think I've ever seen *any* real (i.e., non-contrived) code
> that's broken by the difference in the semantics of sizeof('a')
> between C and C++.
I wouldn't find such code entirely unexpected were I to encounter
it though. However, If you look at my recently Morton-accepted
patches, for example, you'd be right to conclude that I'm not
surprised by much any more, there's a lot of messed up C out there.
(I found those using a static code analysis tool called 'grep'.)