Want to win a PS4? Go Premium and enter to win our High-Tech Treats giveaway. Enter to Win


Definition of macros

Posted on 2000-04-08
Medium Priority
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 .
Question by:WxW
Welcome to Experts Exchange

Add your voice to the tech community where 5M+ people just like you are talking about what matters.

  • Help others & share knowledge
  • Earn cash & points
  • Learn & ask questions
  • 4
  • 4
  • 3
  • +1
LVL 22

Expert Comment

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.

Author Comment

ID: 2695940
The array is not a STL array

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

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

Expert Comment

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(...))

Concerto Cloud for Software Providers & ISVs

Can Concerto Cloud Services help you focus on evolving your application offerings, while delivering the best cloud experience to your customers? From DevOps to revenue models and customer support, the answer is yes!

Learn how Concerto can help you.


Author Comment

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

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

Expert Comment

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.
LVL 22

Expert Comment

ID: 2695979
Opps I got a parenthesis wrong.

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

Expert Comment

ID: 2696051
I would use a template to wrap both the new and the clear.

template <typename T> inline T* newclear(int n) {
  T* p = new T[n];
  return p;

Author Comment

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 ?

LVL 10

Accepted Solution

RONSLOW earned 90 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.

LVL 10

Expert Comment

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>();


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).
LVL 22

Expert Comment

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.

Expert Comment

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>
LVL 10

Expert Comment

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.

Featured Post

Independent Software Vendors: We Want Your Opinion

We value your feedback.

Take our survey and automatically be enter to win anyone of the following:
Yeti Cooler, Amazon eGift Card, and Movie eGift Card!

Question has a verified solution.

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

Go is an acronym of golang, is a programming language developed Google in 2007. Go is a new language that is mostly in the C family, with significant input from Pascal/Modula/Oberon family. Hence Go arisen as low-level language with fast compilation…
Article by: evilrix
Looking for a way to avoid searching through large data sets for data that doesn't exist? A Bloom Filter might be what you need. This data structure is a probabilistic filter that allows you to avoid unnecessary searches when you know the data defin…
The viewer will learn how to user default arguments when defining functions. This method of defining functions will be contrasted with the non-default-argument of defining functions.
The viewer will learn how to clear a vector as well as how to detect empty vectors in C++.
Suggested Courses

610 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