Why is #define bad and what is the proper substitu

2020-01-27 08:12发布

#define dItemName        L"CellPhone"

标签: c++
6条回答
▲ chillily
2楼-- · 2020-01-27 08:13

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;
查看更多
兄弟一词,经得起流年.
3楼-- · 2020-01-27 08:19

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";

查看更多
Juvenile、少年°
4楼-- · 2020-01-27 08:19

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.

查看更多
smile是对你的礼貌
5楼-- · 2020-01-27 08:31

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

查看更多
手持菜刀,她持情操
6楼-- · 2020-01-27 08:31

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.

查看更多
一纸荒年 Trace。
7楼-- · 2020-01-27 08:39

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

  1. A macro knows no scope
  2. A macro is not type safe

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:

  • they should not contain two consecutive underscores
  • they should not begin by an underscore

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 :)

查看更多
登录 后发表回答