If I define a macro as #define LOGIC_ONE 1
and want to use the LOGIC_ONE
in a case statement, what type is LOGIC_ONE
considered?
Is it recognized as an int
since I am defining it for value 1?
Open both the workbook that contains the macro you want to copy, and the workbook where you want to copy it. On the Developer tab, click Visual Basic to open the Visual Basic Editor. , or press CTRL+R . In the Project Explorer pane, drag the module containing the macro you want to copy to the destination workbook.
C++ macros are simple text replacements.
At the time the compiler starts, your LOGIC_ONE
has already been replaced by 1
by the precompiler. Its just the same as if you would have written 1
right away. (Which, in this case, is an int literal...)
Edit to include the discussion in the comments:
If you (or someone else with access to your code) changes your #define LOGIC_ONE 1
to #define LOGIC_ONE "1"
it would change its behaviour in your program and become a const char[]
literal.
Edit:
Since this post got more attention than i expected, i thought i add the references to the C++ 14 Standard for those curious:
2.2 Phases of translation [lex.phases]
(...)
4. Preprocessing directives are executed, macro invocations are expanded, and _Pragma unary operator expressions are executed. (...) All preprocessing directives are then deleted.
(...)
7. White-space characters separating tokens are no longer significant. Each preprocessing token is converted into a token. (2.6). The resulting tokens are syntactically and semantically analyzed and translated as a translation unit.
As stated, macros are replaced in phase 4 and no longer present afterwards. "Syntactical and semantical" analysation take place in phase 7, where the code gets compiled ("translated").
Integer literals are specified in
2.13.2 Integer literals [lex.icon]
(...)
An integer literal is a sequence of digits that has no period or exponent part, with optional separating single quotes that are ignored when determining its value. An integer literal may have a prefix that specifies its base and a suffix that specifies its type.
(...)Table 5 — Types of integer literals
Suffix | Decimal literal | Binary, octal, or hexadecimal literal ----------------------------------------------------------------------------- none | int | int | long int | unsigned int | long long int | long int | | unsigned long int | | long long int | | unsigned long long int ----------------------------------------------------------------------------- u or U | unsigned int | unsigned int | unsigned long int | unsigned long int | unsigned long long int | unsigned long long int ----------------------------------------------------------------------------- l or L | long int | long int | long long int | unsigned long int | | long long int | | unsigned long long int ----------------------------------------------------------------------------- Both u or U | unsigned long int | unsigned long int and l or L | unsigned long long int | unsigned long long int ----------------------------------------------------------------------------- ll or LL | long long int | long long int | unsigned long long int ----------------------------------------------------------------------------- Both u or U |unsigned long long int | unsigned long long int and ll or LL | |
String literals are specified in
2.13.5 String literals [lex.string]
(...)
1 A string-literal is a sequence of characters (as defined in 2.13.3) surrounded by double quotes, optionally prefixed by R, u8, u8R, u, uR, U, UR, L, rLR, as in "...", R"(...)", u8"...", u8R"**(...)**", u"...", uR"*~(...)*~", U"...", UR"zzz(...)zzz", L"...", or LR"(...)", respectively.
(...)
6 After translation phase 6, a string-literal that does not begin with an encoding-prefix is an ordinary string literal, and is initialized with the given characters.
7 A string-literal that begins with u8, such as u8"asdf", is a UTF-8 string literal.
8 Ordinary string literals and UTF-8 string literals are also referred to as narrow string literals. A narrow string literal has type “array of nconst char
”, where n is the size of the string as defined below, and has static storage duration (3.7).
Preprocessor defines have no type - they are fundamentally just "pasted" in to the code where they appear. If for example, you use it in the statement;
int foo = LOGIC_ONE;
Then it'll be interpreted as integer. (The compiler, which runs after the preprocessor, just sees that code as int foo = 1;
) You can even use it in a grotty statement such as;
int foo##LOGIC_ONE;
Then you'll be creating a variable foo1
. Yuk!
Take an alternative example of macro definition;
#define LOGIC_ONE hello
int LOGIC_ONE = 5;
printf("%d\n", hello);
That's perfectly valid, and declares an int called hello, but shows that there is no "type" for defines - hello
was merely substituted wherever LOGIC_ONE
was encountered in the code.
Avoid using preprocessor macros unless absolutely necessary. Professional coding standards often prohibit or severely restrict the use of the preprocessor. There are generally always better ways to do things than use macros. For example, consider these alternatives;
static const int LOGIC_ONE = 1;
enum { LOGIC_ONE = 1 };
The preprocessor is a quick way for a learner to get in a real mess in C.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With