notebook/notes/c17/macros.md

10 KiB

title TARGET DECK FILE TAGS tags
Macros Obsidian::STEM c17::macro
c17

Overview

Macros refer to #define directives that specify terms that should be textually replaced by the preprocessor during compilation:

#define NAME ...

For types that don't have literals that describe their constants, we can use compound literals on the replacement side of the macro:

#define NAME (T){ INIT }

%%ANKI Basic What preprocessor directive is used to define macros? Back: #define Reference: Jens Gustedt, Modern C (Shelter Island, NY: Manning Publications Co, 2020).

END%%

%%ANKI Basic How are compound literals specified in a macro definition, say MACRO? Back:

#define MACRO (T){ INIT }

Reference: Jens Gustedt, Modern C (Shelter Island, NY: Manning Publications Co, 2020).

END%%

%%ANKI Basic What term is used to refer to the replacement side of the following macro?

#define MACRO (T){ INIT }

Back: A compound literal. Reference: Jens Gustedt, Modern C (Shelter Island, NY: Manning Publications Co, 2020).

END%%

%%ANKI Basic What is the difference between the following two lines?

#define MACRO (T){ INIT }
# define MACRO (T){ INIT }

Back: N/A. They are equivalent. Reference: Jens Gustedt, Modern C (Shelter Island, NY: Manning Publications Co, 2020).

END%%

%%ANKI Basic What is the difference between the following two lines?

#define MACRO (T){ INIT }
#define MACRO(T){ INIT }

Back: The first defines a compound literal. The latter defines a function-like macro. Reference: Jens Gustedt, Modern C (Shelter Island, NY: Manning Publications Co, 2020).

END%%

%%ANKI Basic What is T a reference to in the following compound literal?

#define MACRO (T){ INIT }

Back: A type-specifier. Reference: Jens Gustedt, Modern C (Shelter Island, NY: Manning Publications Co, 2020).

END%%

%%ANKI Basic What is INIT a reference to in the following compound literal?

#define MACRO (T){ INIT }

Back: An initializer. Reference: Jens Gustedt, Modern C (Shelter Island, NY: Manning Publications Co, 2020).

END%%

%%ANKI Basic Why aren't compound literals suitable for ICE? Back: They are objects, not constants. Reference: Jens Gustedt, Modern C (Shelter Island, NY: Manning Publications Co, 2020).

END%%

%%ANKI Basic How can the following be rewritten so that MACRO is an object?

#define MACRO 5

Back:

#define MACRO (int){5}

Reference: Jens Gustedt, Modern C (Shelter Island, NY: Manning Publications Co, 2020).

END%%

%%ANKI Basic What is the difference between the following two lines?

#define MACRO 5
#define MACRO (int){5}

Back: The former is a literal whereas the latter is a compound literal. Reference: Jens Gustedt, Modern C (Shelter Island, NY: Manning Publications Co, 2020).

END%%

%%ANKI Basic Why should compound literals be, generally speaking, const-qualified? Back: Doing so gives the optimizer more room to generate good binary code. Reference: Jens Gustedt, Modern C (Shelter Island, NY: Manning Publications Co, 2020).

END%%

%%ANKI Basic How do we write macro definitions that span more than one line? Back: Ending all but the last line with a \ character. Reference: Jens Gustedt, Modern C (Shelter Island, NY: Manning Publications Co, 2020).

END%%

%%ANKI Basic Generally speaking, what character should not be specified at the end of a macro definition? Back: ; Reference: Jens Gustedt, Modern C (Shelter Island, NY: Manning Publications Co, 2020).

END%%

Operators

The # operator is used to stringify an argument. For example, calling foo(bar) in the following yields "bar".

#define foo(T) #T

%%ANKI Basic In what context is the # operator found? Back: Macros. Reference: Jens Gustedt, Modern C (Shelter Island, NY: Manning Publications Co, 2020).

END%%

%%ANKI Basic What does the # operator do? Back: Stringify arguments. Reference: Jens Gustedt, Modern C (Shelter Island, NY: Manning Publications Co, 2020).

END%%

%%ANKI Basic Given the following definition, what is the result of foo(bar)?

#define foo(T) #T

Back: "bar" Reference: Jens Gustedt, Modern C (Shelter Island, NY: Manning Publications Co, 2020).

END%%

%%ANKI Basic Given the following translation unit, what is output to stdout?

#define foo(T) #T

int main(void) { printf("%s\n", foo(123)); }

Back: 123 Reference: Jens Gustedt, Modern C (Shelter Island, NY: Manning Publications Co, 2020).

END%%

%%ANKI Basic Given the following translation unit, what is output to stdout?

#define foo(T) #T

int main(void) { printf("%s\n", foo("world")); }

Back: "world" (with quotations). Reference: Jens Gustedt, Modern C (Shelter Island, NY: Manning Publications Co, 2020).

END%%

%%ANKI Basic Given the following translation unit, what is output to stdout?

#define foo(T) #T

int main(void) { printf("%s\n", foo(hello)); }

Back: hello Reference: Jens Gustedt, Modern C (Shelter Island, NY: Manning Publications Co, 2020).

END%%

%%ANKI Basic Given the following translation unit, what is output to stdout?

#define foo(T, U) #T

int main(void) { printf("%d\n", foo(123)); }

Back: N/A. The foo function macro invocation returns a string, not an integer. Reference: Jens Gustedt, Modern C (Shelter Island, NY: Manning Publications Co, 2020).

END%%

%%ANKI Basic Given the following translation unit, what is output to stdout?

#define foo(T, U) #T #U

int main(void) { printf("%s\n", foo(123, 456)); }

Back: 123456 Reference: Jens Gustedt, Modern C (Shelter Island, NY: Manning Publications Co, 2020).

END%%

%%ANKI Basic Given the following translation unit, what is output to stdout?

#define foo(T, U) #T " " #U

int main(void) { printf("%s\n", foo("123", "456")); }

Back: "123" "456" Reference: Jens Gustedt, Modern C (Shelter Island, NY: Manning Publications Co, 2020).

END%%

The ## operator is used to concatenate tokens. For example, calling foo(bar) in the following yields bar_init.

#define foo(T) T ## _init

%%ANKI Basic In what context is the ## operator found? Back: Macros. Reference: Jens Gustedt, Modern C (Shelter Island, NY: Manning Publications Co, 2020).

END%%

%%ANKI Basic What does the ## operator do? Back: Concatenate tokens together. Reference: Jens Gustedt, Modern C (Shelter Island, NY: Manning Publications Co, 2020).

END%%

%%ANKI Basic Given the following definition, what is the result of foo(bar)?

#define foo(T) T ## _init

Back: bar_init Reference: Jens Gustedt, Modern C (Shelter Island, NY: Manning Publications Co, 2020).

END%%

%%ANKI Basic Given the following translation unit, what is output to stdout?

#define foo(T, U) #T ## #U

int main(void) { printf("%s\n", foo(123, 456)); }

Back: N/A. Pasting formed "123""456", an invalid preprocessing token. Reference: Jens Gustedt, Modern C (Shelter Island, NY: Manning Publications Co, 2020).

END%%

%%ANKI Basic Given the following translation unit, what is output to stdout?

#define foo(T, U) T ## U

int main(void) { printf("%s\n", foo("123", "456")); }

Back: N/A. Pasting formed "123""456", an invalid preprocessing token. Reference: Jens Gustedt, Modern C (Shelter Island, NY: Manning Publications Co, 2020).

END%%

%%ANKI Basic Given the following translation unit, what is output to stdout?

#define foo(T, U) T ## U

int main(void) { printf("%s\n", foo(123, 456)); }

Back: N/A. The foo function macro invocation returns an integer, not a string. Reference: Jens Gustedt, Modern C (Shelter Island, NY: Manning Publications Co, 2020).

END%%

Variable Argument Lists

The construct ... provides an argument list of variable length. This set of arguments is then accessible inside the macro expansion as __VA_ARGS__.

%%ANKI Basic How is a variable argument list denoted in the macro function declaration? Back: As .... Reference: Jens Gustedt, Modern C (Shelter Island, NY: Manning Publications Co, 2020).

END%%

%%ANKI Basic How is a variable argument list denoted in the macro function expansion? Back: As __VA_ARGS__. Reference: Jens Gustedt, Modern C (Shelter Island, NY: Manning Publications Co, 2020).

END%%

%%ANKI Cloze Within macros, {...} corresponds to {__VA_ARGS__}. Reference: Jens Gustedt, Modern C (Shelter Island, NY: Manning Publications Co, 2020).

END%%

%%ANKI Basic Given the following translation unit, what is output to stdout?

#define foo(T, ...) #T #__VA_ARGS__

int main(void) { printf("%s\n", foo(123, 456, 789)); }

Back: 123456, 789 Reference: Jens Gustedt, Modern C (Shelter Island, NY: Manning Publications Co, 2020).

END%%

%%ANKI Basic Given the following translation unit, what is output to stdout?

#define foo(T, ...) T ## __VA_ARGS__

int main(void) { printf("%s\n", foo(123, 456, 789)); }

Back: N/A. The foo function macro invocation returns integers, not a string. Reference: Jens Gustedt, Modern C (Shelter Island, NY: Manning Publications Co, 2020).

END%%

%%ANKI Basic Given the following translation unit, what is output to stdout?

#define foo(T, ...) T ## __VA_ARGS__

int main(void) { printf("%d\n", foo(123, 456, 789)); }

Back: 123456 Reference: Jens Gustedt, Modern C (Shelter Island, NY: Manning Publications Co, 2020).

END%%

Bibliography

  • Jens Gustedt, Modern C (Shelter Island, NY: Manning Publications Co, 2020).