Take the 2-minute tour ×
Programmers Stack Exchange is a question and answer site for professional programmers interested in conceptual questions about software development. It's 100% free, no registration required.

I've seen two styles of using sizeof for memory-related operations (such as in memset or malloc):

  • sizeof(type), and
  • sizeof variable or sizeof(variable)

Which one would you prefer, or would you use a mix of the two styles, and when would you use each style? What are the pros and cons of each style and when you use them?

As an example, I can see the following pair of situations where one style helps and the other doesn't:

When you get the pointer indirection wrong:

type *var;
...
memset(var, 0, sizeof var);    /* oops */

When the type changes:

new_type var;    /* changed from old_type to new_type */
...
memset(&var, 0, sizeof(old_type));    /* oops */
share|improve this question
add comment

6 Answers

up vote 14 down vote accepted

I perfer sizeof(variable) over sizeof(type). Consider:

int a1;
float a2;
memset(&a1,0,sizeof(a1));
memset(&a2,0,sizeof(a2));

vs.

int a1;
float a2;
memset(&a1,0,sizeof(int));
memset(&a2,0,sizeof(float));

In the first case, it's easy to verify that the right sizes are being passed to memset. In the second case, you need to constantly review top and bottom sections to make sure you are consistent.

share|improve this answer
2  
Also, if you change the type of the variable, code that assumes the type will have to change. I think it's preferable to right code with as little dependence on the type as possible. (I am influenced by a large 16 bit to 32 bit conversion project back in the day.) –  Steven Burnap Jun 11 '13 at 3:58
    
This is preferable for working with C arrays where it is not common to create a typedef, but use things like char array[MAX_SIZE]; –  mattnz Jun 11 '13 at 9:30
    
Unfortunately sizeof(array) does NOT return the size of the array, but the size of the pointer to the array. That's because arrays don't actually exist in C; they are simply syntactic sugar for pointers. –  vy32 May 22 at 13:00
add comment

I would vastly prefer sizeof(type) over sizeof variable. Even though it forces you to worry more about the type and make more changes, it helps you avoid pointer indirection mistakes, which rank among the most common cause of bugs in C.

I would not worry so much about bugs where the type in sizeof(type) gets changed; whenever you change the type of a variable, you should do a quick scan to see where that variable is used and if you need to change any sizeof(type) statements. Even though there is always a chance of getting this wrong, it has a much lower risk than pointer indirection mistakes.

One advantage of sizeof variable is for arrays, but in practice I've found that passing arrays as pairs of first/len is much more common (in which case just use the length), plus it is also very easy to get the size wrong due to array/pointer decay, as in this example:

ID_INLINE mat3_t::mat3_t( float src[ 3 ][ 3 ] ) {
  memcpy( mat, src, sizeof( src ) );    /* NOT the same as 3*3*sizeof(float) */
}
share|improve this answer
1  
"Quick scan to see where that variable is used.... there is always a chance of getting this wrong" - to me this is the biggest danger of doing sizeof(type), which is why I always do sizeof(variable). Because the end-result of this danger is that everything might still compile and even if you make one mistake, it might take you more than a year or random crashes and buffer corruptions before you catch it. And I couldn't make the connection (obviously my time window per question is about 30 sec) between this question and "pointer indirection mistakes". –  DXM Jun 11 '13 at 3:23
    
@DXM With the sizeof operand, if it's a value then it's sizeof var; if it's a pointer it's sizeof *var. This is also something that people can get wrong, and the compiler will happily take it without complaint. I argue that these mistakes are much harder to spot, and are more common, than mistakes with the sizeof(type) form. –  congusbongus Jun 11 '13 at 4:46
1  
Your both right - C types and sizeof operator are fundamentally broken and will never be reliable, nothing you do as a programmer can fix it. –  mattnz Jun 11 '13 at 9:26
add comment

The preference (as always) is to reflect your intention as directly as possible.

Is the intention to operate against an existing variable's memory? If so, then use sizeof(variable), as this shows as closely as possible that it's the variable itself's memory that you care about.

Is the intention to perform some calculation on the type, for example to determine how much memory should be allocated for a new instance? If so, then use sizeof(type).

That is, I prefer

struct foo *bar;
bar = (struct foo *) malloc(sizeof(struct foo));

over

bar = (struct foo *) malloc(sizeof(*bar));

as the latter case looks like you're trying to access a variable that doesn't exist, yet.

On the other hand, I prefer

char Buffer[256];
memset(Buffer, 0, sizeof(Buffer));

over

char Buffer[256];
memset(Buffer, 0, 256 * sizeof(char));

as the intention is clearly to zero-fill the contents of the variable, so it's the variable we should operate against. Trying to use the type metadata just confuses things, here.

share|improve this answer
add comment

The aim is to remove redundancy. If you use sizeof for an operation related to a variable, then obviously you shall reflect that in the sizeof. Yes, you can mess up like in the first example, but the cure is not use type, but *var, correctly matching the aim.

To mitigate such problems it's usual to use macros, templates and similar tools trained for the use case rather than naked sizeof.

See my CLEAR macro that is used exclusively instead of naked memset. Saved my ass several times in cases of indirection typo or when a struct content picked up a vector or string...

share|improve this answer
    
Macros such as that are what gave C's Macro programming a bad name...... –  mattnz Jun 11 '13 at 9:28
    
@mattnz: please show the better alternative. It's way easier to talk abstract stuff than create actually working programs –  Balog Pal Jun 11 '13 at 9:33
    
The linked Macro is C++, and this post is tagged 'C' (They are different languages), Ada would be my suggestion. –  mattnz Jun 12 '13 at 0:46
    
@mattnz: and the same topic shows how to enforce in similar ways for C. You appear to completely miss the point, that is not the actual content implementation but safer usage compared to raw stuff. Btw ways readable too. –  Balog Pal Jun 12 '13 at 0:54
add comment

Business logic defines your choice.

  1. If your code refers to a particular variable and without this variable your code makes no sense - choose sizeof(var)

  2. If you code deals with a set of variables with particular type - choose sizeof(type). Usually you need this if you have a typedef which defines many variables which you process differently based on their type (e.g. serialization). You may not know which of these variables will remain in future code versions so choosing type as an argument is logically correct. Even changing of such typedef will not affect your sizeof line.

share|improve this answer
add comment

Depending on the purpose sizeof(variable) could be the best solution. In that way, you can change your variable type if necessary, without correcting all entries for the type. But again, it depends on your objective.

share|improve this answer
add comment

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.