Solved

Definition of macros

Posted on 2000-04-08
13
384 Views
Last Modified: 2012-08-13
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 .
0
Comment
Question by:WxW
  • 4
  • 4
  • 3
  • +1
13 Comments
 
LVL 22

Expert Comment

by:nietod
ID: 2695923
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.
0
 
LVL 6

Author Comment

by:WxW
ID: 2695940
The array is not a STL array

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

I talk only for arrays with char[] ( buffers )
0
 
LVL 1

Expert Comment

by:ntdragon
ID: 2695945
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(...))
 



0
 
LVL 6

Author Comment

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

How can GetSize get the size of the object ?
0
 
LVL 22

Expert Comment

by:nietod
ID: 2695978
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.
0
 
LVL 22

Expert Comment

by:nietod
ID: 2695979
Opps I got a parenthesis wrong.

#define cleard(x,y) ZeroMemory(x*sizeof(*y))
0
Is Your Active Directory as Secure as You Think?

More than 75% of all records are compromised because of the loss or theft of a privileged credential. Experts have been exploring Active Directory infrastructure to identify key threats and establish best practices for keeping data safe. Attend this month’s webinar to learn more.

 
LVL 10

Expert Comment

by:RONSLOW
ID: 2696051
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;
}
0
 
LVL 6

Author Comment

by:WxW
ID: 2696100
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 ?


0
 
LVL 10

Accepted Solution

by:
RONSLOW earned 30 total points
ID: 2696134
well .. if you want to have the compiler find all the clears for you, just remove the definition. Although a text editor would be better :-)

What you want is COMPILE time assertions.  You can do these with templates.

template <bool> struct tassert { typedef int assertion; };
template <> struct tassert<false> {};

#define CASSERT(X) typedef typename tassert<X>::assertion failed;

Now you can say

#define clear(X) { CASSERT(sizeof(X)>4); ZeroMemory(X,sizeof(X); }

This will fail at compile time (ie you'll get an error) if the sizeof X is 4 (ie it is a pointer and not an array variables.

0
 
LVL 10

Expert Comment

by:RONSLOW
ID: 2696146
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).
0
 
LVL 22

Expert Comment

by:nietod
ID: 2696233
>>  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.
0
 
LVL 1

Expert Comment

by:ntdragon
ID: 2696239
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>
0
 
LVL 10

Expert Comment

by:RONSLOW
ID: 2698688
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.
0

Featured Post

Is Your Active Directory as Secure as You Think?

More than 75% of all records are compromised because of the loss or theft of a privileged credential. Experts have been exploring Active Directory infrastructure to identify key threats and establish best practices for keeping data safe. Attend this month’s webinar to learn more.

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

In days of old, returning something by value from a function in C++ was necessarily avoided because it would, invariably, involve one or even two copies of the object being created and potentially costly calls to a copy-constructor and destructor. A…
What is C++ STL?: STL stands for Standard Template Library and is a part of standard C++ libraries. It contains many useful data structures (containers) and algorithms, which can spare you a lot of the time. Today we will look at the STL Vector. …
The goal of the tutorial is to teach the user how to use functions in C++. The video will cover how to define functions, how to call functions and how to create functions prototypes. Microsoft Visual C++ 2010 Express will be used as a text editor an…
The viewer will be introduced to the technique of using vectors in C++. The video will cover how to define a vector, store values in the vector and retrieve data from the values stored in the vector.

895 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question

Need Help in Real-Time?

Connect with top rated Experts

15 Experts available now in Live!

Get 1:1 Help Now