0

In other words, how can I redefine a macro based on it's previous definition? Specifically, I want to add a string to the end of a string macro in C++. This is what I've tried so far:

#define FOO "bla"
// code here will read FOO as "bla"
#define FOO FOO ## "dder"
// code here will read FOO as "bladder"

In C++, this returns error: FOO was not declared in this scope. How would I do this without getting this error?

EDIT: I've read the comments and found out what an "XY problem" is. What I want to do is make a library for C but the library is written in C++. Because the library requires Classes to function (because it uses other C++ libraries), I wanted to make an empty class that the C program using the library can add custom properties to using Macro functions. Something like this:

// lib.h

#define PROPERTIES ""
#define NEW_PROPERTY(X) // add X + ";\n" to PROPERTIES (somehow)

#ifdef __cplusplus
Class myclass
{
    public:
        PROPERTIES
}
#endif

_

// c code
#include <lib.h>

NEW_PROPERTY(int id);
NEW_PROPERTY(int color);

int main(){
...

The c program won't need to access the properties because they only exist so that a third-party library that is a dependency for my library can use them.

  • The C and C++ standards do not provide any such feature. Why do you want to do this? – Eric Postpischil May 11 '22 at 17:05
  • You can't redefine a macro without undefining it first. – Barmar May 11 '22 at 17:06
  • 1
    I think we are looking at a https://meta.stackexchange.com/questions/66377/what-is-the-xy-problem Tell us what you really want to achieve by doing this and let us help with that. – Yunnosch May 11 '22 at 17:07
  • You can't do that directly. But you can have the same effect with **2** macros `FOO1` and `FOO2`. Also note that `##` is **not** to concatenate literal strings (just separate them with a space), but to concatenate *tokens*. So: `#define FOO1 "bla"` `#define FOO2 FOO1 "dder"` – prapin May 11 '22 at 17:22
  • It is not a good idea! Your `FOO` definition will blow up quickly with some bad includes!!! And you won't be able to find the problem ever!!! But is it an XY problem? Why do you need it? I think it makes no sense... – simre May 11 '22 at 17:25
  • You have a misunderstanding of how the langauge works. The macros are just a shorthand to avoid writing something you could write manually. Moreover, TUs (translation units) are compiled separately, so you can't write a macro in a .c file, and expect an unrelated .cpp file to be affected. – HolyBlackCat May 11 '22 at 17:49
  • 1
    note that you already got an answer for Y and X is a somewhat different question. I would consider to post a new question for X – 463035818_is_not_an_ai May 11 '22 at 17:49
  • In addition, what you try is not to concatenate *literal string*, but some code. Typically for code, the line return is not needed, and the semi colon should be the one after the macro use. – prapin May 11 '22 at 17:52
  • 1
    To get the behavior your edit descirbes, I think the "right" way would be to define a struct on the c side with the properties you desire, and then extend that struct in c++. Refer to https://stackoverflow.com/questions/17454536/c-class-wrapper-for-c-struct – Carson May 11 '22 at 17:53

1 Answers1

2

This is not possible.

From the gcc documentation (emphasis is mine):

However, if an identifier which is currently a macro is redefined, then the new definition must be effectively the same as the old one. Two macro definitions are effectively the same if:

  • Both are the same type of macro (object- or function-like).
  • All the tokens of the replacement list are the same.
  • If there are any parameters, they are the same.
  • Whitespace appears in the same places in both. It need not be exactly the same amount of whitespace, though. Remember that comments count as whitespace.

These definitions are effectively the same:

#define FOUR (2 + 2)
#define FOUR         (2    +    2)
#define FOUR (2 /* two */ + 2)

but these are not:

#define FOUR (2 + 2)
#define FOUR ( 2+2 )
#define FOUR (2 * 2)
#define FOUR(score,and,seven,years,ago) (2 + 2)

If a macro is redefined with a definition that is not effectively the same as the old one, the preprocessor issues a warning and changes the macro to use the new definition. If the new definition is effectively the same, the redefinition is silently ignored. This allows, for instance, two different headers to define a common macro. The preprocessor will only complain if the definitions do not match.

Carson
  • 2,700
  • 11
  • 24
  • the docs you quote dont exclude to `#undef` then `#define` as something else – 463035818_is_not_an_ai May 11 '22 at 17:51
  • 1
    @463035818_is_not_a_number true, but to move information out of a previous macro def into a new one is not possible given the c macro semantics without redefining. https://pastebin.com/8LSSPN9s is invalid under section 3.1 of those docs – Carson May 11 '22 at 17:56