Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

What type is a macro considered? [duplicate]

Tags:

c++

macros

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?

like image 802
Noobgineer Avatar asked Feb 13 '16 01:02

Noobgineer


People also ask

Can you duplicate a macro?

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.


2 Answers

C++ macros are simple text replacements.

At the time the compiler starts, your LOGIC_ONE has already been replaced by 1by the precompiler. Its just the same as if you would have written 1right 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 n const char”, where n is the size of the string as defined below, and has static storage duration (3.7).

like image 56
Anedar Avatar answered Sep 29 '22 13:09

Anedar


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.

like image 31
IanJ Avatar answered Sep 29 '22 13:09

IanJ