Reputation: 1027
#define dItemName L"CellPhone"
Upvotes: 7
Views: 11691
Reputation: 405
Pointing to define doing what they where invented for as a failure is - well blaming a knife for cutting.
If you dont not properly Name your defines with UPPERCASE_NAMES you will have troubles, but you will have those troubles anyway in C if you can not self-discipline your working style.
You can not use const to generate dynamically rearranging systems, so its not suited for any embedded Application that is tailored pre-compile to usage.Const can only be assigned pre-evaluation constants, so not even other const Expressions.
Just because a Tool doese not bow to the OO-Paradigm its does not suddenly become useless. Const is not equal replacement regarding functionality.
Upvotes: 2
Reputation: 62073
One major problem with #define
is that it is outside of the language itself and therefore is not limited to a given scope. You will replace dItemName
anywhere in the translation unit, in all namespaces, classes, functions, etc.
I'd replace it with const std::wstring dItemName = L"CellPhone";
Upvotes: 6
Reputation: 5980
Define it as a constant variable. It is a good programming practice.
const wchar_t *dItemName = L"CellPhone";
In case you need to know the lenght of your string somewhere later, then define it as an array:
const wchar_t dItemName[] = L"CellPhone";
Also, why #define is bad: It transforms all places where you use word dItemName to L"CellPhone". Example:
struct {
int dItemName;
} SomeStruct;
will become invalid:
struct {
int L"CellPhone";
} SomeStruct;
Upvotes: 16
Reputation: 299820
Amusingly I could not find a single question pointing all the disadvantages, even the subject has certainly been discussed before.
First of all, not that in C
(not C++) this is the way to declare a constant. This also explains why so many C++ developers still use it: when they come from C background or have been taught by / learned from people with C background, they tend to reproduce this C-ish behavior.
In C++, however, we have superior facilities.
#define
does not define a constant, it defines a macro
A macro knows no scope:
They are preprocessing facilities: the preprocessor is not aware of the rules of the underlying language (whether asm, C or C++) and will always expand the symbols it has in stock with no regard for scope.
For this reason, it is usually recommended to use a specific set of symbols to set macros apart. People generally use ALL_CAPS
symbols, though you need to remember that:
in order to be compliant with the C++ standard.
A macro is not type safe.
As I said, the preprocessor ignores the underlying language rules, therefore the following does not strike it as strange:
#define FOO "foo"
int main(int argc, char* argv[])
{
if (FOO) { ... }
return 0;
}
On the other hand, using a proper type would prevent this unintentional mistake:
std::string const Foo = "foo";
Conclusion ?
You can use a #define
if you wish, it's just you doing the extra work instead of the compiler, but that's your call. Personally: I am lazy :)
Upvotes: 6
Reputation: 40859
Because preprocessor macros, which you've just made, pollute every name scope. They are available everywhere and do not follow standard naming scope rules. Thus, with a macro like that, code like int dItemName = 5;
instead gets f'ed over by the preprocessor to instead be int L"CellPhone" = 5;
. A constant, global variable would not do this.
All other issues aside, this is IMNSHO the worse issue with macro definitions.
Upvotes: 1
Reputation: 26060
#define
is a preprocessor instruction that defines a macro. In your case macro dItemName
with value L"CellPhone"
.
Macros are bad mostly because they are processed before the actual code is. This means that they aren't subjected to scopes and to the rules of C++ syntax. If you've got a variable somewhere called dItemName
, things won't probably work: you'll get hard-to-understand compilation errors due to that.
The solution is to declare dItemName
as a variable (in this case a const
variable).
Upvotes: 2