sizeof() style question

  • Thread starter Christopher C. Stacy
  • Start date
M

Michael Mair

Christopher said:
Some people say sizeof(type) and other say sizeof(variable).
Why?

You mean: One can apply the sizeof operator either to a
cast expression, i.e. (type), or to an expression, e.g
variable or *variable. Both are valid uses, in both cases
you get the size (in bytes) of the type of the expression.

The latter is especially convenient in conjunction with
malloc():

type *p;
p = malloc(some_number * sizeof *p);

works for arbitrary type "type", whereas sizeof (type) works
only as long guaranteed as p is a pointer to type.

Using parentheses around *p is a sign of confusion. If you
want parentheses, use: (sizeof *p).


Cheers
Michael
 
R

Robert W Hand

Some people say sizeof(type) and other say sizeof(variable).
Why?

Some people are right, and some people are wrong, I guess? ;-)

The syntax for unary operators is pretty clear -

sizeof unary-expression
sizeof(type-name)

Of course, putting an expression in parenthesis has no effect so both
forms are ok. Although I do not use parentheses for both forms, I
suspect that using parentheses probably cuts down on potential errors
of the type sizeof type.
 
M

Martin Ambuhl

Christopher said:
Some people say sizeof(type) and other say sizeof(variable).
Why?

The sizeof operator has two forms. From the standard:

The sizeof operator yields the size (in bytes) of its
operand, which may be an expression or the parenthesized
name of a type. The size is determined from the type of the
operand. The result is an integer. If the type of the
operand is a variable length array type, the operand is
evaluated; otherwise, the operand is not evaluated and the
result is an integer constant.

So either
sizeof(type)
or
sizeof expression
is correct, depending on the situation.
Some people, for reasons known only to them, insist on parenthesizing
the expression, but
sizeof(expression)
and
sizeof expression
mean exactly the same thing. Note that 'sizeof variable' is only a
special case of 'sizeof expression'.
In the real world, 'sizeof expression' is much more useful, since it can
be used in situations where the expression is not permanently tied to a
particular type.

Consider a simple situation frequently asked about here: how do you
determine the number of elements in an array declared as an array in the
present scope? The macro
#define NUMBER_OF_ELEMENTS(x) (sizeof(x)/sizeof *(x))
can take the array name without regard for the type of its elements.
BTW, the parentheses about 'x' in the macro have to do with expansion of
macros, not with the operand of sizeof.
 
P

pete

Christopher said:
Some people say sizeof(type) and other say sizeof(variable).
Why?

I prefer sizeof variable.
There's usually a variable around somewhere
of the type that you're interested in,
.... otherwise why would you be interested in that type?
 
K

Keith Thompson

Some people say sizeof(type) and other say sizeof(variable).
Why?

Some people what to know the size of a type; others want to know the
size of a variable.

Can you be more specific?
 
K

Keith Thompson

Michael Mair said:
You mean: One can apply the sizeof operator either to a
cast expression, i.e. (type), or to an expression, e.g
variable or *variable. Both are valid uses, in both cases
you get the size (in bytes) of the type of the expression.

In sizeof(type), the (type) has nothing to do with cast expressions,
it's just a type name enclosed in parentheses.
 
L

lovewar

what is the difference between the sizeof(char *) and the sizeof(const char
*) ?

and what is the mean of the const qualifier ?
 
M

Michael Mair

Keith said:
In sizeof(type), the (type) has nothing to do with cast expressions,
it's just a type name enclosed in parentheses.

You are right; I don't know where I picked up "cast expression".
My apologies for the wrong information.

Cheers
Michael
 
T

Tim Rentsch

Keith Thompson said:
In sizeof(type), the (type) has nothing to do with cast expressions,
it's just a type name enclosed in parentheses.

They have nothing to do with each other, except that a type operand of
'sizeof' and a prefix that specifies casting happen to have identical
syntax, namely '( type-name )'. I expect that's more than just a
coincidence.
 
C

Chris Croughton

Some people are right, and some people are wrong, I guess? ;-)

The syntax for unary operators is pretty clear -

sizeof unary-expression
sizeof(type-name)

Of course, putting an expression in parenthesis has no effect so both
forms are ok. Although I do not use parentheses for both forms, I
suspect that using parentheses probably cuts down on potential errors
of the type sizeof type.

I find that having a unary operator which is an identifier is a
cognitive dissonance in C (I don't use the word forms of &&, ||, ! etc.
either). And if one of them needs a parenthesis, both should. Why
(sizeof x) but not (sizeof x_t)? Putting it with parentheses at least
preserves syntax with the rest of the language (it looks like a
parameterised macro or a function call).

Chris C
 
K

Keith Thompson

Tim Rentsch said:
They have nothing to do with each other, except that a type operand of
'sizeof' and a prefix that specifies casting happen to have identical
syntax, namely '( type-name )'. I expect that's more than just a
coincidence.

I expect it's just a coincidence. Parentheses are used for enough
different things that it's not surprising a couple of them look alike
when taken out of context.
 
R

Robert W Hand

I find that having a unary operator which is an identifier is a
cognitive dissonance in C (I don't use the word forms of &&, ||, ! etc.
either). And if one of them needs a parenthesis, both should. Why
(sizeof x) but not (sizeof x_t)? Putting it with parentheses at least
preserves syntax with the rest of the language (it looks like a
parameterised macro or a function call).

Never thought that a computer language had a psychological state. ;-)

I guess I have become more flexible in old age. Of course, sizeof
expression is not a macro or function call. Why make it look like
one? Making it look like a function call or macro might lead a newbie
to ask what header to include for sizeof(). It is an operator. Let's
remember to call it an operator.

I have heard the argument from reasonable and experienced programmers
that using parentheses on expressions would cut down on newbie errors
when sizeof(int) is wanted (less likely to write sizeof int). I
understand the argument, but I do not use it.
 
D

Dik T. Winter

> The sizeof operator has two forms. From the standard:
>
> The sizeof operator yields the size (in bytes) of its
> operand, which may be an expression or the parenthesized
> name of a type. The size is determined from the type of the
> operand. The result is an integer. If the type of the
> operand is a variable length array type, the operand is
> evaluated; otherwise, the operand is not evaluated and the
> result is an integer constant. ....
> Some people, for reasons known only to them, insist on parenthesizing
> the expression, but
> sizeof(expression)
> and
> sizeof expression
> mean exactly the same thing.

Except when expression is a cast expression.
 
E

Emmanuel Delahaye

Christopher C. Stacy wrote on 10/06/05 :
Some people say sizeof(type) and other say sizeof(variable).
Why?

It depends on the situaton. If you have an object or a typed pointer,
better to use sizeof object or sizeof *p_object (no parens needed). But
if you only have the type, use sizeof (type) (parens required).

--
Emmanuel
The C-FAQ: http://www.eskimo.com/~scs/C-faq/faq.html
The C-library: http://www.dinkumware.com/refxc.html

"Clearly your code does not meet the original spec."
"You are sentenced to 30 lashes with a wet noodle."
-- Jerry Coffin in a.l.c.c++
 
L

Lawrence Kirby

However things like sizeof array + 1 can look awkward. sizeof(array) + 1
looks neater and perhaos clearer. You can write (sizeof array) + 1 but
that still isn't quite as natural
Except when expression is a cast expression.

Well expression has to be syntactically valid as an operand to sizeof. 1+1
isn't e.g. sizeof 1+1 isn't the same thing as sizeof(1+1). A cast
expression isn't a syntactically valid operand of sizeof.

Lawrence
 
M

Malcolm

Chris Croughton said:
I find that having a unary operator which is an identifier is a
cognitive dissonance in C (I don't use the word forms of &&, ||, ! etc.
either). And if one of them needs a parenthesis, both should. Why
(sizeof x) but not (sizeof x_t)? Putting it with parentheses at least
preserves syntax with the rest of the language (it looks like a
parameterised macro or a function call).
I agree. sizeof is a function, so it sould take its argument in parentheses
like other C functions.
It is a function of the type rather than the value of its argument, so
sizeof(int) is preferable to sizeof(x).
Personally I'm sceptical of the argument that sizeof *ptr is robust to
changes in the type of ptr - anyone who changes the type of a pointer should
scan through all code that references it as a matter of course. However it
is a legitimate point..
 
K

Keith Thompson

Malcolm said:
I agree. sizeof is a function, so it sould take its argument in parentheses
like other C functions.

Would you also argue that return is a function call, so its argument
should be in parentheses? (If so, you're being consistent, but I
disagree; it would also imply that a return with no expression should
be written as "return();", but the language doesn't allow that.)

sizeof is an operator, not a function. It happens to be the only (?)
operator in C whose name is a keyword rather than a symbol composed of
punctuation characters, but there's no fundamental reason operators in
general can't use either form. I've used other languages where some
operators are puncuation symbols, and others are keywords; there's no
real distinction between them other than the way their names are
spelled.

"sizeof" and "&" are both operators; when the operand is an
expression, there's no need to use parentheses unless they're
necessary for grouping or clarity. I'm almost sympathetic to using
"sizeof(*x)" because it looks too much like a multiplication without
the parentheses, but I find that proper spacing, as in "sizeof *x", is
sufficient to get the point across.

Pretending that sizeof is a function will eventually lead to
confusion; for example, it can cause you to forget that the operand
isn't evaluated (unless it's a VLA), and it can make it difficult to
read code written by people who don't choose to pretend that it's a
function. Just remember that operator names don't have to be composed
of punctuation marks, and that sizeof(type) is a special case, and
everything becomes clear.
 
C

Chris Croughton

I agree. sizeof is a function, so it sould take its argument in parentheses
like other C functions.

Except that it's a compile-time function. But I agree that in a
mathematical sense the result is a function of the (type of the)
parameter. I don't think that it's really an operator, it doesn't
operate on anything.
It is a function of the type rather than the value of its argument, so
sizeof(int) is preferable to sizeof(x).

IMO, yes. It also ensures that it avoids ambiguity:

malloc(sizeof x * y)

is visually ambiguous, since unlike the ordinary operators the
precedence is not obvious (OK, the precedence of bit operators is odd as
well, so I always fully parenthesise those).
Personally I'm sceptical of the argument that sizeof *ptr is robust to
changes in the type of ptr - anyone who changes the type of a pointer should
scan through all code that references it as a matter of course. However it
is a legitimate point..

If one uses sizeof(*p) then it is less to change, thus there is less
chance of errors getting in by accident. Why make changes more
error-prone than they have to be? For instance, take a typical use of
an allocated array:

int func(size_t n, ...)
{
float *arr = malloc(n * sizeof(*arr));
int i;
if (!arr)
return -1;
for (i = 0; i < n; ++i)
arr = 0.0;
/* use array for calculations */
free(arr);
return result;
}

If I decide to do the calculations in double or long double instead, I
only have one place to change, so I won't be in danger of getting te
wrong amount of memory. If the type were specified also in the malloc
then it would be easy to overlook the change.

Chris C
 

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,774
Messages
2,569,599
Members
45,175
Latest member
Vinay Kumar_ Nevatia
Top