Link to home
Start Free TrialLog in
Avatar of WxW
WxW

asked on

Definition of macros

I have a macro that clears a static array , defined like that :

#define clear(x) ZeroMemory(x,sizeof(x))

I also have one that clears a dynamic array :

#define cleard(x,y) ZeroMemory(x,y)

To increase performace of my application , I started to convert arrays to dynamic . When clear is used to a dynamic array , it clears only the 4 bytes of it ( sizeof(dyn.array) = size of its pointer )

I saw in the help file that i can use the sizeof() operator in conditionals ( #if , #elif etc )
My question is : How can I redefine clear() so it checks if the size of the array is 4 , and if so , generate a compiler-time error (with #error)

Thanks .
Avatar of nietod
nietod

I wouldn't recommend it.

If you wrote the dynamic array, add a clear member function to it.  (Although clearing an array with 0's is not always a safe thing to do, like if it is an array of classes.)   You might be better of using a default constructor to initialize all the items.  This will 0 the built-in types.

If you are using the STL array class (vector), you can use the clear() function to delete all the items in the array and then use the resize() function to add default constructed items to the array.

You will be much much better of with that sort of approach.
Avatar of WxW

ASKER

The array is not a STL array

Just like char* xx = new char[1000];

I talk only for arrays with char[] ( buffers )
if you don't take nietod's comment

then if you are using a char array why don't you use
clear(x) ZeroMemory(x,sizeof(char)*strlen(x))

or if you use difrrent array's write a func GetSize(...) that will get you the size of your object

and then use clear(x) ZeroMemory(x,GetSize(...))
 



Avatar of WxW

ASKER

ntdragon : strlen() wont work , 'cause the array might not be full .

How can GetSize get the size of the object ?
You could do

#define cleard(x,y) ZeroMemory(x*sizeof(*y())

but honestly, I don't think I am doing you any favor...  I would strongly consider using array classes.
Opps I got a parenthesis wrong.

#define cleard(x,y) ZeroMemory(x*sizeof(*y))
I would use a template to wrap both the new and the clear.

eg.
template <typename T> inline T* newclear(int n) {
  T* p = new T[n];
  ZeroMemory(p,n*sizeof(T));
  return p;
}
Avatar of WxW

ASKER

It seems that no one understood my question.

I KNOW what to do and how to do to make my program work at run-time .

But , instead of keeping searching and replacing all clear() with cleard() , i hope that the compiler finds them with me .

nietod : why cleard should do ZeroMemory(*sizeof(*y) , since cleard already knows the size of the array ?

The problem is in clear() . The pointer passed to clear should be a static array . If it is a dynamic one , sizeof() returns 4 . Would size of *x return the correct value in both cases that the array passed is static or dynamic ?


ASKER CERTIFIED SOLUTION
Avatar of RONSLOW
RONSLOW

Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
NOTE: there are other ways to get compiler time assert (using templates) eg.

template <bool b> class assert;
class assert<true>{};
#define CASSERT(X) assert<X>();

etc.

bascially, by using a template with a bool param, you get either something valid or invalid.  Other examples include the template param giving array dim (-ve is an error).
>>  i hope that the compiler
>> finds them with me
that is not the compiler's job.  That is a good job for a text editor.

>>  why cleard should do ZeroMemory(*sizeof(*y) ,
>> since cleard already knows the size of
>> the array ?
How does it know that?  I was assuming that x is the number of entries and  y is a pointer to the array.  How does it know the size of the array?

>> The problem is in clear() . The pointer passed to
>> clear should be a static array
If clear() is written to assume that it is passed a pointer to a static array, and it sounds like you have, then you can't expect it to work with a dynamic array.  You must take a different approach with a dynamic array.  You will have to supply the number of entries in the array and some means for it to find the size of an entry (like sizeof(*y)).

>> Would size of *x return the correct value
sizeof() always returns the correct valyue, that just might not be the value you want.  If "x" is a pointer to an array, then sizeof(*x) will return the size of a single item in the array.  You can multiple this byt he number of items in the array to get the size of the array.  That is what my code was doing.
you can use nietod comment
it one of the options for the GetSize func

to make the GetSize i should know how your array is build how can i find it's length <like in array of char i use strlen>
I can see what WxW wants here ... if sometimes he wants to use 'clear' other times 'cleard'.

He, quite legitimately, wants the compiler to tell him when he does the wrong thing.

This is a VERY sensible thing to want.

You should be able to write you code so that the compiler tells you if you do something stupid.  It is good programming paractice to do so.  Examples of this are:

Using const everywhere where it is applicable so you avoid calling functions that can modify a value that should be constant.

Using the convention:
  if (0 == value)
instead of
  if (value == 0)
so that the compiler will generate an error if you mistakenly us '=' instead of '=='.

Using #if and #error to do simple compile time assertions (eg. checking that some #defines are compatible, or the size of a variable is as expected).  Using #error is a bit limited though - hence the templated compile time assertions in my answer

Of course, one can do RUNTIME checking with ASSERT macros etc.  But this relies on having test cases in place that exercises every line of code with all possible conditions.  Such testing is a wonderful thing to have, but one's code shouldn't rely on that.

Having the compiler pick up errors for you at compiler time is always the best option.  And a request for this by WxW should be commended as common sense.