In C++, what are few ways to using macros such as #define? Like I understand that it is an easier way similar to variables, but how do I understand how to use #define?

Database System Concepts
7th Edition
ISBN:9780078022159
Author:Abraham Silberschatz Professor, Henry F. Korth, S. Sudarshan
Publisher:Abraham Silberschatz Professor, Henry F. Korth, S. Sudarshan
Chapter1: Introduction
Section: Chapter Questions
Problem 1PE
icon
Related questions
Question
100%
In C++, what are few ways to using macros such as #define? Like I understand that it is an easier way similar to variables, but how do I understand how to use #define?
Expert Solution
Step 1: Few ways to using macros

1. In defining a macro, the single most important rule is to let it do as little by itself as possible and to forward it to a "real" entity as quickly as possible (function, class). For visitable classes, we describe the macro as follows:

#define DEFINE_VISITABLES() \
   virtual ReturnType Accept(BaseVisitor& theguest) \
   { return AcceptImpl(*this, guest); }

2. In modern C++, there are at least two times where you type something in the code twice, and where it would be more nice, both for the writer and for the code readers, if the phrase is more succinct by writing it once. In such situations, Macros will help. 

FWD

The first one is the FWD macro by Vittorio Romeo. We also use std::forward since C++11 in template code to transfer values along without sacrificing the fact that they are references to l-value or r-value:

template<typename MyType, typename MyOtherType>
void f(MyType&& myValue, MyOtherType&& myOtherValue)
{
    g(std::forward<MyType>(myValue), std::forward<MyOtherType>(myOtherValue));
}

The && in this template code means that, depending on whether the values they attach to are l-values or r-values, the values may be l-value or r-value references. Std::forward enables this data to be transferred to g.

But to express that, it's a lot of code, it's frustrating to type each time, and it takes up some space while reading.

Vittorio proposes to use the following macro such are:

#define FWD(...) ::std::forward<decltype(__VA_ARGS__)>(__VA_ARGS__)

Here is that  how the previous code now looks like by using it:

template<typename MyType, typename MyOtherType>
void f(MyType&& myValue, MyOtherType&& myOtherValue)
{
    g(FWD(myValue), FWD(myOtherValue));
}

The macro made it simpler to type and read the code.

noexcept(noexcept(

Basically, if you declare a function with the specifier noexcept, it means that no exception is thrown at the function, period:

void f() noexcept; // no exceptions, period.

But sometimes it's not all black or white, and only if a certain condition is met can the feature promise not to throw exceptions:

void f() noexcept(condition); // no exceptions if condition is met.

A another condition is that if another expression (for instance one that f uses) is itself noexcept. For that we can use the noexcept operator: for example that  noexcept(T{}) returns true if the expression T{} is itself noexcept.

Combining the noexcept specifier with the noexcept operator will give the following information:;

void f() noexcept(noexcept(T{})); // no exceptions if T{} doesn't throw.

When you break it down, it makes sense, but, as a whole,

noexcept(noexcept(T{}))

You've got a strange look. Maybe you're totally good and used to it. Or maybe you'd like the code to be a little more straightforward, and then a macro will modify the expression. For eg, the SFME project uses noexcept-if (and one of its authors told me he saw it in the work of Vittorio), and I guess we could also call it noexcept-like:

#define noexcept_like(expression)  noexcept(noexcept(expression))

Which converts our code in this way:

void f() noexcept_like(T{}); // no exceptions if T{} doesn't throw.

3. Yeah, it is possible to use Macros for polymorphism. Except for a very special kind of polymorphism: that which is resolved at the time of pre-processing, which occurs well before the time of compilation. Therefore, before compilation time, the input must be there to address the sort of polymorphism. 

How is this functioning? You specify the compilation parameters starting with -D, and you can verify the presence of #ifdef directives in the code for those parameters. You may use various #defines depending on their nature to give different definitions to an expression in the code.

There are at least two kinds of knowledge that you can transfer on this way to your program:

  • The type of OS that allows device calls to be portable (UNIX vs. Windows)
  • Accessible versions of C++ (C++98, C++03, C++11, C++14, C++17, etc.).

 

steps

Step by step

Solved in 2 steps

Blurred answer
Knowledge Booster
ADT and Class
Learn more about
Need a deep-dive on the concept behind this application? Look no further. Learn more about this topic, computer-science and related others by exploring similar questions and additional content below.
Similar questions
  • SEE MORE QUESTIONS
Recommended textbooks for you
Database System Concepts
Database System Concepts
Computer Science
ISBN:
9780078022159
Author:
Abraham Silberschatz Professor, Henry F. Korth, S. Sudarshan
Publisher:
McGraw-Hill Education
Starting Out with Python (4th Edition)
Starting Out with Python (4th Edition)
Computer Science
ISBN:
9780134444321
Author:
Tony Gaddis
Publisher:
PEARSON
Digital Fundamentals (11th Edition)
Digital Fundamentals (11th Edition)
Computer Science
ISBN:
9780132737968
Author:
Thomas L. Floyd
Publisher:
PEARSON
C How to Program (8th Edition)
C How to Program (8th Edition)
Computer Science
ISBN:
9780133976892
Author:
Paul J. Deitel, Harvey Deitel
Publisher:
PEARSON
Database Systems: Design, Implementation, & Manag…
Database Systems: Design, Implementation, & Manag…
Computer Science
ISBN:
9781337627900
Author:
Carlos Coronel, Steven Morris
Publisher:
Cengage Learning
Programmable Logic Controllers
Programmable Logic Controllers
Computer Science
ISBN:
9780073373843
Author:
Frank D. Petruzella
Publisher:
McGraw-Hill Education