-
May 13th, 2010, 08:18 AM
#1
#define vs const - where to use #define?
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?
Thanks!
-
May 13th, 2010, 08:28 AM
#2
Re: #define vs const - where to use #define?
#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.
-
May 13th, 2010, 08:29 AM
#3
Re: #define vs const - where to use #define?
Ok thanks, and is it good practice to use uppercase names for const ints or only #defines?
-
May 13th, 2010, 08:46 AM
#4
Re: #define vs const - where to use #define?
Uppercase for both is usually the accepted practice for values, but you can use lowercase in #defines if it's not a value.
Common example:
Code:
#define foreach(iterator, container)\
for (typeof(container.begin()) iterator = container.begin, iterator##_end = container.end; iterator != iterator##_end; ++iterator)
#include <iostream>
#include <string>
int main(){
std::string test("Hello World");
foreach(it, test){
std::cout << *it << std::endl;
}
}
There is a case where you are defining something other than a value.
Last edited by ninja9578; May 13th, 2010 at 08:49 AM.
-
May 13th, 2010, 08:58 AM
#5
Re: #define vs const - where to use #define?
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.
-
May 13th, 2010, 11:10 AM
#6
Re: #define vs const - where to use #define?
#define is also incredibly useful for macros.
I frequently use them to allocate common pointers, like char*. For example:
Code:
#define malstr(str,size) \
str = (char*)malloc(sizeof(char)*size);
int main(){
char* myString;
malstr(myString, 256);
}
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.
-
May 13th, 2010, 11:18 AM
#7
Re: #define vs const - where to use #define?
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.
-
May 13th, 2010, 11:27 AM
#8
Re: #define vs const - where to use #define?
Originally Posted by Russco
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.
-
May 13th, 2010, 11:30 AM
#9
Re: #define vs const - where to use #define?
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.
-
May 13th, 2010, 12:57 PM
#10
Re: #define vs const - where to use #define?
Originally Posted by Hoobs
I've never had stdlib get lost with such a macro
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.
-
May 13th, 2010, 06:04 PM
#11
Re: #define vs const - where to use #define?
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
Code:
#define THROW_MYEXCEPTION(msg) throw MyException(msg, __FILE__, __LINE__)
so that throwing a "MyException" is simplified down to just using
Code:
THROW_MYEXCEPTION("Something bad happened!");
-
May 13th, 2010, 07:07 PM
#12
Re: #define vs const - where to use #define?
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....
Code:
namespace CompressConfig
{
enum InnerValue : unsigned char
{
Default = 0,
Low = 1,
Medium = 2,
High = 3
};
}
typedef CompressConfig::InnerValue Compress_Config;
-
May 13th, 2010, 08:56 PM
#13
Re: #define vs const - where to use #define?
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.
-
May 14th, 2010, 02:42 AM
#14
Re: #define vs const - where to use #define?
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
Tags for this Thread
Posting Permissions
- You may not post new threads
- You may not post replies
- You may not post attachments
- You may not edit your posts
-
Forum Rules
|
Click Here to Expand Forum to Full Width
|