Expand MACro Inside String Literal

Expand macro inside string literal

#define STRINGIFY2(X) #X
#define STRINGIFY(X) STRINGIFY2(X)
#define A 2

Then STRINGIFY(A) will give you "2". You can concatenate it with other string literals by putting them side by side.

"I have the number " STRINGIFY(A) "." gives you "I have the number 2.".

Expand macros inside quoted string

You can't expand macros in strings, but you can write

#define COLOR "#00ff00"

f("abc "COLOR);

Remember that this concatenation is done by the C preprocessor, and is only a feature to concatenate plain strings, not variables or so.

C Macro should expand as char* in one place and wchar* in another place with L character

A quick and easy solution, with no extra macros:

  • Use MACRO_STRING directly when you need char *.
  • Use L"" MACRO_STRING when you need wchar_t *.

Expanding macro inside raw string

If you want to debug your crazy macros, you'd probably get more mileage out of directly examining the preprocessed output. Any C/C++ compiler will have an option for this. In GCC it's -E; for MSVC, I don't recall where it is exactly, but one of the properties sections has "keep preprocessed output". When you do this, keep your #includes to a minimum, especially standard-library #includes; these can add hundreds or thousands of lines of code to the top of the preprocessed output.

Expand integer macro inside quoted string

The right way to do this is to use a * in your format string, which will cause it to take the value from your argument list. For example:

printf("%.*s\n", 3, "abcde");

This is equivalent to:

printf("%.3s\n", "abcde");

That way you can use PATH_MAX or any other value to control the format without having to worry about how they're defined (e.g., whether they contain parentheses or addition operators, etc.)

Do preprocessors expand macros surrounded by quotation marks?

Do common preprocessors like cpp and fpp expand macros surrounded by a
pair of quotation marks?

The C language specification describes the behavior of conforming C preprocessors. The actual standards for C are not freely available, but you can get copies of late drafts. For C18, for example, you could refer to N2176. In particular, you should have a look at sections 5.1.1.2 and 6.10.3. Of particular relevance is footnote 173 in section 6.10.3:

Since, by macro-replacement time, all character constants and string
literals are preprocessing tokens, not sequences possibly containing
identifier-like subsequences (see 5.1.1.2, translation phases), they
are never scanned for macro names or parameters.

(Substantially the same text appears in earlier versions of the standard, too.)

The bottom line for C, then, is that no, a conforming C preprocessor does not perform macro replacement on the contents of string literals or character constants.


The situation for Fortran is less clear cut, because the Fortran language specification does not define preprocessing facilities. There is an include statement built in to the language itself, but Fortran practitioners generally would not consider its use to involve preprocessing. Fortran source code rarely relies on preprocessing features such as macro expansion or conditional compilation.

Some Fortran implementations nevertheless do provide a preprocessing facility, sometimes available as a standalone program named fpp. You would need to consult the documentation of your specific fpp for details, but generally these are adaptations of the C preprocessor to Fortran syntax. As such, no, I would not expect a Fortran preprocessor to perform macro expansion on the contents of character literals. I am not aware of any implementations that defy my expectations in that regard.

Expand X macro inside another macro

main.c:7:5: warning: implicit declaration of function ‘X’ [-Wimplicit-function-declaration]

Well, yes. At line 18, where macro STUFF appears, it is first expanded to

TABLE

, then that is rescanned. TABLE being defined as a macro, it, too, is expanded, resulting in

X("abc", "123", "ddd") X("def", "456", "aaa") X("ghi", "789", "ddd")

, then that is rescanned. But X is not defined as a macro (or as anything else) at that point, because you previously undefined it. That leaves you with code that resembles three calls to an unknown function, without any kind of operator or separator between. It is invalid.

Your X macro has to be defined appropriately at the place where it is expanded. It does not need to be defined at all at the place where it appears in another macro's expansion text. You seem to have that backward.


As discussed in comments, the objective is to be able to define separate macros, for example STUFF and STUFF2 that expand TABLE to consistent results that differ from each other. This is as opposed to causing STUFF to expand as wanted by manipulating the definition of X.

This can be accomplished by changing the definition of TABLE so that it is a function-like macro taking another macro name as an argument:

#define TABLE(m) \
m("abc", "123", "ddd") \
m("def", "456", "aaa") \
m("ghi", "789", "ddd")

The macros STUFF and STUFF2 can then control the expansion by their choice of which macro name to pass to TABLE():

#define X(_a, _b, _c) _a
#define Y(_a, _b, _c) _b
#define STUFF TABLE(X)
#define STUFF2 TABLE(Y)

How to use Macro argument as string literal?

Use the preprocessor # operator:

#define CALL_DO_SOMETHING(VAR) do_something(#VAR, VAR);

extract macro argument inside string

You probably need concat!() for this. It would concatenate literals to yield a &'static str:

macro_rules! update_user {
($tx:ident, $id:expr, $key:expr, $val:expr) => {
sqlx::query!(
concat!("UPDATE users SET $key = ", $key, " WHERE id = ", $id),
$val
).execute(&mut $tx).await?;

};
}

A similar example: Playground



Related Topics



Leave a reply



Submit