Skip to content

Commit

Permalink
Start mentionning macros arguments expansion rules
Browse files Browse the repository at this point in the history
  • Loading branch information
agagniere committed Aug 19, 2024
1 parent e998dc0 commit d77668b
Show file tree
Hide file tree
Showing 3 changed files with 47 additions and 0 deletions.
26 changes: 26 additions & 0 deletions book/pages/03_log.md
Original file line number Diff line number Diff line change
Expand Up @@ -327,3 +327,29 @@ Let's finish this feature and integrate it with the logging macros:
:::{preprocessed} 03_eval3
:output: markdown
:::

## Convert the line number to a string literal

Currently, the line number of each log entry is placed at run-time, using the `"%i"`{l=C} printf format.

But why do it at run-time ? `__LINE__` is a macro that expands to an integer literal, meaning its value is accessible at compile-time. It just isn't a string, so we cannot concatenate it as-is.

We've just seen how the `#` operator can create a string literal from arbitrary code, let's use it !

`__LINE__` is not an argument of our `log_log` macro, so we can't write `# __LINE__` directly. Instead we'll define a `STRINGIZE` macro that applies `#` to its argument:

:::{preprocessed} 03_stringline1
:no-compiler-view:
:::

Wait, that is not what we wanted ! We wanted `__LINE__` to be expanded to `8` __before__ being converted to a string !

> Macro arguments are completely macro-expanded before they are substituted into a macro body, __unless they are stringized or pasted with other tokens__.

:::{preprocessed} 03_stringline2
:no-compiler-view:
:::

Success !

10 changes: 10 additions & 0 deletions book/samples/03_stringline1.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
#include <stdio.h> // printf

#define STRINGIZE(ARG) # ARG

int main(int arg_count, char** arg_values)
{
printf("Line as integer: %i\n", __LINE__);
printf("Line as string: %s\n", STRINGIZE(__LINE__));
printf("Concatenated: " STRINGIZE(__LINE__) "\n");
}
11 changes: 11 additions & 0 deletions book/samples/03_stringline2.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
#include <stdio.h> // printf

#define STRINGIZE(ARG) # ARG
#define STRINGIZE_WRAPPER(ARG) STRINGIZE(ARG)

int main(int arg_count, char** arg_values)
{
printf("Line as integer: %i\n", __LINE__);
printf("Line as string: %s\n", STRINGIZE_WRAPPER(__LINE__));
printf("Concatenated: " STRINGIZE_WRAPPER(__LINE__) "\n");
}

0 comments on commit d77668b

Please sign in to comment.