•
•
•
•
What is DaniWeb IT Discussion Community?
You're currently browsing the Software Development category of DaniWeb, a massive community of 383,425 software developers, web developers, Internet marketers, and tech gurus who are all enthusiastic about making contacts, networking, and learning from each other. In fact, there are 2,617 IT professionals currently interacting right now! Registration is free, only takes a minute and lets you enjoy all of the interactive features of the site.
Please support our Software Development advertiser:
Sep 9th, 2006, 5:47 pm
In a number of text and other references, the author stops short of recommending good practice (a blackbird, perhaps?), and plenty of code and its programmers suffer for it. I took a stab at explaining the basics once before, but I felt like revisiting it again. Since I abandoned the use of a
I must mention, however that I am against this type of macro:
I am wholeheartedly in favor of something like this:
But as you see, that's different from delcaring an array size.
Now as much as we'd all love to believe that the software documentation we are supposed to write is supposed to tell us how everything works, these docs go largely unread and we all head straight to the source code; after all, this is always the actual current state of the code.
What happens in larger projects, at least in my experience, is that this little "shortcut" gets put in some header somewhere. Now it wouldn't be bad if it were just one simple lookup, but too often in my experience it's been too much of a hunt. Let's say I've got a line of code that I am examining:
This all looks dandy, but I have to do some searches to verify that this is doing what is intended. First I look up Rx.
Okay. What's RXTYPE? (And don't get me started on typedefs, that'll be an article on its own someday.)
Okay, now what's RX_BUFFER_SIZE?
Okay, does that match? One more lookup... What was the question again? Oh, yeah.
Aha! There's the bug.
What's a simple fix that is guaranteed to be correct?
What did the
So as the places in the code that once had these magic macros disappear, you're left with about two places left where the macro exists: the definition itself and the array definition. Now why in the world should these two related values be separate?
Hm. No reason, delete the macro and put the actual size at the array definition. Now, less code, more correct, less hunting: easier to maintain code.
But feel free to ignore my advice and take the macro approach. Many feel quite comfortable with what I just railed against. But the next time you are searching through a half-dozen or more files chasing a bug like this, do have a distant memory of reading this article. And if this is the case, spread the news.
#define macro to define an array size, I find I don't even miss it and my code is to me simpler and easier to follow, as well as being more correct. I just want to proselytize a bit more.I must mention, however that I am against this type of macro:
#define SIZE 100
#define CPU_SPEED 100000 #define TIMER_BASE ((CPU_SPEED)/1000)
Now as much as we'd all love to believe that the software documentation we are supposed to write is supposed to tell us how everything works, these docs go largely unread and we all head straight to the source code; after all, this is always the actual current state of the code.
What happens in larger projects, at least in my experience, is that this little "shortcut" gets put in some header somewhere. Now it wouldn't be bad if it were just one simple lookup, but too often in my experience it's been too much of a hunt. Let's say I've got a line of code that I am examining:
Rx.Buffer[Rx.Index++] = uart0;
if ( Rx.Index >= BUFFER_SIZE )
{
Rx.Index = 0;
}RXTYPE Rx;
typedef struct
{
unsigned char Buffer[RX_BUFFER_SIZE];
int index;
} RXTYPE;#define RX_BUFFER_SIZE 40 // must be smaller than normal
#define BUFFER_SIZE 100 // used for most buffers
What's a simple fix that is guaranteed to be correct?
Rx.Buffer[Rx.Index++] = uart0;
if ( Rx.Index >= sizeof Rx.Buffer / sizeof *Rx.Buffer )
{
Rx.Index = 0;
}#define by me? A lot of indirection and hunting through code. But now with the use of sizeof for a replacement, I don't actually need to look anywhere, I can tell by the idiom sizeof x / sizeof *x that it is correct for an array. I don't even need to care how big the actual array is.So as the places in the code that once had these magic macros disappear, you're left with about two places left where the macro exists: the definition itself and the array definition. Now why in the world should these two related values be separate?
Hm. No reason, delete the macro and put the actual size at the array definition. Now, less code, more correct, less hunting: easier to maintain code.
But feel free to ignore my advice and take the macro approach. Many feel quite comfortable with what I just railed against. But the next time you are searching through a half-dozen or more files chasing a bug like this, do have a distant memory of reading this article. And if this is the case, spread the news.
This blog entry was written by Dave Sinkula. It has received 3,274 views, 5 comments, and 6 linkbacks. 1 voter has rated this entry 5 out of 5 stars.
Comments (Newest First)
iMalc | Newbie Poster | Jul 28th, 2007
•
•
•
•
I prefer to use the following macro:
#define countof(x) (sizeof(x) / sizeof(x[0]))
#define countof(x) (sizeof(x) / sizeof(x[0]))
Dave Sinkula | long time no c | Sep 12th, 2006
jwenting | duckman | Sep 12th, 2006
•
•
•
•
You can't use sizeof to initialise the size of an array, after all sizeof what?
Sizeof that array? But that's not available early enough (before array initialisation).
There'll always be a place for symbolic constants of some sort, and in C those are #define's.
In C++ they're const, in Java they're static final.
A #define should of course exist in a headerfile with logical structure, maybe something like constant_declarations.h, and not be sprinkled around the code.
But you're effectively stating in your original post that symbolic constants are too difficult to use and should be abandoned, which is quite untrue.
Sizeof that array? But that's not available early enough (before array initialisation).
There'll always be a place for symbolic constants of some sort, and in C those are #define's.
In C++ they're const, in Java they're static final.
A #define should of course exist in a headerfile with logical structure, maybe something like constant_declarations.h, and not be sprinkled around the code.
But you're effectively stating in your original post that symbolic constants are too difficult to use and should be abandoned, which is quite untrue.
Dave Sinkula | long time no c | Sep 10th, 2006
jwenting | duckman | Sep 10th, 2006
•
•
•
•
So your advice is to go against what has been found to be best practice over the last 30 years and just hardcode magic numbers everywhere, and to abandon type definitions and put everything in one massive sourcefile because that way you'd not have to search different files for your type definitions.
Not going to fly I'm happy to say.
Not going to fly I'm happy to say.
Post Comment
•
•
•
•
Only community members can start a blog or comment on blog entries. You must register or log in to contribute.
•
•
•
•
•
•
•
•
DaniWeb Software Development Marketplace
Related Blog Entries
- LinuxWorld Caters to Developers (3 Hours Ago)
- Programmers Blog and Career (5 Hours Ago)
- Deploy .NET 3.5 Apps With No Framework Update (2 Days Ago)
- TI’s Low Power Chips Save Battery Life, Not the Planet (2 Days Ago)
- IE8 Beta Testers wanted, only great people need apply (3 Days Ago)
- Microsoft's Post-Windows Plans Revealed (7 Days Ago)
- To Heck With Vista; I'd Wait for Modori (7 Days Ago)
- Childs Case Exposes Media, City Ignorance (11 Days Ago)
- GUIdancer 2.2 Automates Failure Retires (12 Days Ago)
- Microsoft POIsed to Control an Apache Project (13 Days Ago)
Related Forum Threads
- user given array size (C++)
- User define 2D array (C++)
- string array size (C++)
- Problem with memory allocation =( (C)
- works for static need help to make it dynamic (C++)
- array question (C++)