Skip to content

Instantly share code, notes, and snippets.

@kinchungwong
Created February 27, 2019 00:05
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save kinchungwong/c162bc163237319774d864c1763fdb40 to your computer and use it in GitHub Desktop.
Save kinchungwong/c162bc163237319774d864c1763fdb40 to your computer and use it in GitHub Desktop.
Main conflict between c++ expressions and preprocessor token operator techniques

Log message tag struct (optional)

Purpose

  • To allow passing in the tag name and the filtering threshold via one macro argument.
  • If we give up the dual purpose then it would simplify handling of the tag argument.
  • Its usage is open to design ideas, but it must be tolerant of current usage as well as incorrect usage.

Interpretation of logging macro argument

  • Option 1: as-is. The argument is a C++ expression that evaluates to the pointer of a struct.
  • Option 2: name modification. The argument must be a valid substring of C++ identifiers; The argument must be unquoted; prefix and suffix might be applied (via token pasting); the result of concatenation (token pasting) might be subject to repeated C++ macro expansion if the result matches an existing macro.
  • Option 3: macro name, unmodified. The argument will be expand as-is, and its result needs to be [[TBD]].

How to sort out these synergistic yet conflicting ideas of interpreting the tag argument?

  • Reminder: Preprocessor macro expansion is omnipresent; whenever the argument constitutes a valid preprocessor token (which can look like a C++ identifier token), and if a preprocessor macro of same name is defined, expansion will happen, subject to the number of forced macro expansions.
  • Preprocessor macro expansion can act on what looks like a C++ function call: if any C++ token matches an existing preprocessor macro, that token is replaced.
  • Preprocessor token pasting can be used to modify an unquoted preprocessor token.
  • Preprocessor stringification can convert an unquoted preprocessor token into a string.
  • A C++ expression can be a variable, pointer, reference, function call, etc.

What is the main conflict between C++ expressions and preprocessor operator techniques?

  • Usage of caller-specified C++ expressions that involve symbol characters (such as brackets, ampersand, asterisk, etc) is generally incompatible with preprocessor token pasting, as the end result will likely be malformed.
  • If symbol characters occur on only one side of a C++ identifier (either preceding or following), it is possible to apply token-pasting on the other side to generate a valid result after macro expansion.

Example of well-formed usage

  • C++ expression
  • Macro --> C++ expression
  • Macro --> Macro --> ... --> C++ expression
  • Macro --> C++ expression containing a token that matches a macro --> C++ expression
  • Valid token substring, without any "punctuations" --> Modified token (applied prefix and/or suffix, via token-pasting) --> C++ identifier name
  • Valid token substring, without any "punctuations" --> Modified token (applied prefix and/or suffix, via token-pasting) --> Macro --> C++ expression
  • Valid token substring, followed by "punctuations" (such as method call or member) --> Modified token (applied prefix to token substring; no suffix) --> C++ expression
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment