As a newcomer to programming and C++, I wondered what the difference between:
#define SIZE 10
and
const int SIZE=10
From doing my own research, I understand the differences between the 2 (one is done by pre-processor, one by compiler, etc) and it seems in every case the "const int" method is preferable.
So I'm now wondering when should #define be used, if ever?
#define can be used to define anything, const ints are just variables. I'm not sure if it's preferred, but define is actually used a lot more than const ints.
Avoid using define for plain constants as much as possible. You get additional type safety when const "type" is used.
Your example indicate the typical construct
Code:
#define SIZE 10
int myArr[SIZE];
and that's more a plain C notation. If possible replace such stuff with STL containers instead.
I would say that using uppercase letters for defines is pretty much standard. When using const 'type' I use the same notation as for any other variable.
Debugging is twice as hard as writing the code in the first place.
Therefore, if you write the code as cleverly as possible, you are, by
definition, not smart enough to debug it.
- Brian W. Kernighan
The advantage to using a define in this case, as opposed to a function, is that it's significantly simpler to do this than it is to create a malstr(char**) function and return the right addresses. This is more familiar and easy to understand as a novice programmer.
If thats C, then you dont cast the return value of malloc, as doing so may hide stdlib.h not getting included. If its C++ then an inline function is almost certainly a better idea than a macro which has no respect for scope.
Get Microsoft Visual C++ Express here or CodeBlocks here.
Get STLFilt here to radically improve error messages when using the STL.
Get these two can't live without C++ libraries, BOOST here and Loki here.
Check your code with the Comeau Compiler and FlexeLint for standards compliance and some subtle errors.
Always use [code] code tags [/code] to make code legible and preserve indentation.
Do not ask for help writing destructive software such as viruses, gamehacks, keyloggers and the suchlike.
If thats C, then you dont cast the return value of malloc, as doing so may hide stdlib.h not getting included. If its C++ then an inline function is almost certainly a better idea than a macro which has no respect for scope.
I've never had stdlib get lost with such a macro, and scope is only an issue if you poorly separate your classes.
I don't see how that macro helps anything. It merely obfuscates the well-known malloc call into something that anyone reading the code would need to go look up.
If its C++ then an inline function is almost certainly a better idea than a macro which has no respect for scope.
If it's C++, then using std::string is certainly a better idea than mallocing a char array in the first place.
It is not the macro: it is the cast. If <stdlib.h> is not included (or a prototype otherwise provided), then malloc would not have been declared, which means that in C it would be assumed to have a return type of int. This can prove problematic, but if you do not cast the return value of malloc, a compiler is likely to complain, and this serves as a warning to rectify what you forgot.
But removing the cast creates another potential pitfall: if say you later change myString from char* to wchar_t*, but forget to change the malloc, then you might end up allocating insufficient memory. You should thus write:
Code:
str = malloc(sizeof(*str) * size);
That would make more sense than writing sizeof(char) anyway, since sizeof(char) is always 1. But this is a common idiom that beginners should learn, rather than hiding it in a macro that they (and everyone else) would also have to learn, as Lindley pointed out.
Originally Posted by Hoobs
and scope is only an issue if you poorly separate your classes.
It is not scope that is the issue: it is the lack of scope that is the issue, i.e., macro names do not obey the rules of scope. If you followed the common convention of fully capitalising macro names and named your macro MALSTR then this problem would be somewhat mitigated, but you did not.
C + C++ Compiler: MinGW port of GCC
Build + Version Control System: SCons + Bazaar
So I'm now wondering when should #define be used, if ever?
In the case of constants, pretty much never. You'll really only use it for macros in cases where an inline function won't work. For example, it's common for exception classes to take the filename and line number where the error occurred in addition to a message. So you might have something like
I typically don't use defines for much, however I have had a few cases where they have been useful.
In C++ (not C) enums do not have automatic intrinsic bit operators, so I defined a macro that would define the bit operators for a specific enum type.
Also, to enforce full scope resolution and get around non-standard extension accessing a union member by fully qualified name, and to avoid clashing names in unions (Default is one that happens with me a lot) I defined a macro to start an enum definition in a namespace, and a macro that ends the enum definition and typedef's the inner type to the specified.
Code:
DefineEnum(NamespaceName,BaseType) // Yes I know BaseType being unsigned char, int, etc.. is MS specific
Default = 0,
Low = 1,
Medium = 2,
High = 3
EndEnum(NamespaceName,TypeName);
So DefineEnum(CompressConfig,unsigned char), followed by values, and EndEnum(CompressConfig,Compress_Config) turns out to be....
One case when I've found macros to be "superior" to inline functions is when one of the arguments isn't just a statement, but an entire chunk of code. If you've got several bits of code which are almost identical but need to do difficult-to-parameterize things differently in one specific place, a macro taking the code snippet might be appropriate.
Of course, the utility of that is reduced now that C++1x has incorperated boost::function and lambda expressions into the standard.
There are only three situations where I use a macro.
Header inclusion guards
Conditional compilation
Code generation, when templates just can't do what's required. (Rare)
"It doesn't matter how beautiful your theory is, it doesn't matter how smart you are. If it doesn't agree with experiment, it's wrong."
Richard P. Feynman
Bookmarks