Function-like macros without body but different names of argument - c++

The following code:
#define MYDEF(x)
#define MYDEF(y)
int main() {}
gives me an error (or warning if pedantic-errors is disabled):
'MYDEF' macro redefined
The reason is different names for unused argument (more over, there is no body in macro). But why? In which situations it can be a problem?

Because macros are not functions. They are textual replacements done by the preprocessor and can't be overloaded.
It is (almost) similar to find and replace in your editor. Find all the occurences of MYDEF and replace it with (empty string in your case). It's more complicated, of course, but the idea is the same.
And you can't overload this find and replace, can you? :)

The macro can be redefined, and the macro is uniquely determined by the macro name. For example, code like this :
#define MYDEF(x) //the name of the macro is 'MYDEF'
#define MYDEF(x, y) //the name of the macro is 'MYDEF' too
MYDEF(x) will be redifined(or covered) by MYDEF(x, y), you can't write code MYDEF(x) any more after defining MYDEF(x, y)
so, if you write code :
#define MYDEF(x)
#define MYDEF(y) //(There compiler will give warning). You can write
//`#undef MYDEF` before `#define MYDEF(y)` to avoid it.
MYDEF(x) will be redifined by MYDEF(y).

Related

What does this C++ define macro do?

What does this define macro do? I assumed that this will print the given string to the standard output, but it just not printed out nothing. Am I wrong about this?
#define SCOPE_LOGGER(...)
...
void someClass::someFunction() { SCOPE_LOGGER("someClass::someFunction()"); ... }
As per KamilCuk's answer, that macro expands to nothing.
However, most likely it does expand to something through some other preprocessing conditional path, i.e. imho that line appears in the code like this:
#ifdef DEBUG
#define SCOPE_LOGGER(...) something real that does the logging
#else
#define SCOPE_LOGGER(...)
#endif
That's the only way that line can make sense.
What does this define macro do?
Defines a macro function that takes any number of arguments and expands to nothing.
Am I wrong about this?
Because the macro expands to nothing, SCOPE_LOGGER("someClass::someFunction()") is removed from the code. Fun fact: the trailing ; stays.

A macro defined with brackets and without brackets - redefinition error

What is the difference between #define WITHBRACKETS (1) and #define WITHBRACKETS 1?
I have macros defined in two places with same name (I know it's a bad thing that likely results in a redefinition warning) but they are defined differently.
So when I compile the code base, why does the compiler say, #define WITHBRACKETS (1) is an incompatible redefinition of #define WITHBRACKETS 1?
The preprocessor complains it's an incompatible redefinition because it is!
A macro is a token that the preprocessor replaces by a sequence of 0 or more other tokens whenever it encounters it.
#define WITHBRACKETS 1 Will define a token that will be replaced by a single other token.
#define WITHBRACKETS (1) Will define a token to be replaced by three other tokens.
Those aren't compatible things. The preprocessor doesn't know or care that their semantic meaning in the source is the same. All it cares about is the sequence of tokens.
It's a good idea to add the brackets sometimes, for example with something like this :
#define EXAMPLE (1 + 2)
the brackets here can be useful against operator priority errors ...
In your example, the compiler says there is a redefinition because the preprocessor does not know that 1 is the same as (1), it just sees that there are two different sequences of characters.
In simple words: Macros are merely about textual replacement.
If you have those two macros:
#define WITH (1)
#define WITHOUT 1
Then this:
foo( WITHOUT );
foo WITH ;
will expand to
foo( 1 );
foo (1);
So the two defines are indeed different. You can use the -E flag on gcc to see the output after the preprocessing.
PS: Dont use macros (if you dont need to ;).

Why 2 levels of indirection in definition of macro ## operation

In the macro definitions below, there're 2 levels of indirection before the real pasting operation:
#define MACRO_JOIN(a, b) MACRO_JOIN1(a, b)
#define MACRO_JOIN1(a, b) MACRO_JOIN2(a, b)
#define MACRO_JOIN2(a, b) a##b
I know that we need MACRO_JOIN1 because it has no pasting or stringifying so that its arguments can be expanded first.
But what exactly is the purpose of the second indirection MACRO_JOIN? In what situations MACRO_JOIN will work but MACRO_JOIN1 will fail?
Forcing an additional expansion can make a difference where the initial expansion results in something that can be expanded further. A trivial example, given:
#define MACRO(x) x
#define EXPAND(x) x
#define NOEXPAND()
is:
MACRO NOEXPAND() (123)
This expands to MACRO (123). On the other hand, if you force an additional expansion, like so:
EXPAND(MACRO NOEXPAND() (123))
results in:
123
Normally, forcing additional expansions like this is unnecessary: any macro definitions that would cause this to make any difference are generally considered poor style anyway. But with certain specific inputs, it may be useful.
So for a concrete example with your MACRO_JOIN:
MACRO_JOIN(123, MACRO NOEXPAND() (456)) // expands to 123456
MACRO_JOIN1(123, MACRO NOEXPAND() (456)) // expands to 123MACRO (456)

c++ pound define with only one argument

I see a strange use of pound define (#define) in a cpp code such as:
#define FUNCTION
Yeah, this is it.
and for all function definitions.
the code is like
FUNCTION int foo_add(int a, int b) {}
what is the purpose this, and what is this?
Thanks!
Since FUNCTION expands to nothing, it looks like some sort of annotation for some other tool than C++ compiler.
#define identifier token-string
A #define without a token-string removes occurrences of identifier from the source file. The identifier remains defined and can be tested by using the #if defined and #ifdef directives.

C++: How to create enum within a function?

I want to simplify things, by not creating a list of enum separately, but create the enums along the function call which creates the data where i point with those enums.
I tried to make #define which would create another #define, but it didnt work:
int defcounter = 0;
#define make_def(enumname, somedata) \
#define enumname defcounter \
defcounter++; \
func_call(somedata); \
void createstuff(){
make_def(MY_ENUM_NAME, mydata);
make_def(MY_OTHER_ENUMNAME, mydata);
}
void dostuff(){
somefunc_call(MY_ENUM_NAME);
somefunc_call(MY_OTHER_ENUMNAME);
}
But this will create error at the #define enumname:
error C2162: expected macro formal parameter
How can I make this work?
It is impossible to create new types (classes, enums, unions, whatever) at runtime in C++. One of the major features of C++ is that it is statically typed - all types must be known at compile time.
Preprocessor commands (#define, #if, #pragma, #include, ...) cannot appear in macros / defines. The problem is, that the CPP (C-Preprocessor) seperates commands by newlines, while C and C++ are unaware of newlines. In C/C++ you can write everything on one line, for preprocessor commands, you can't.
#define MY_MACRO(name) \
#define name##_macro something_cool \
enum name{ \
.... \
}
// somewhere else
void myfunc(){
MY_MACRO(myfunc_enum);
}
Now, at preprocessing time, those lines all get glued into one big line, thanks to the \ backslash:
#define MY_MACRO(name) #define name##_macro something_cool enum name{....}
Now, how would that macro look at usage?
void myfunc(){
#define name##_macro something_cool enum name{....};
}
Now, the preprocessor has to run over that #define again. But exactly what belongs to the #define, and what doesn't? For the coder it was clear when the macro was written in seperate lines, but now it isn't anymore.
What exactly is your desired output? You need to explain what you think you might get as output from the C preprocessor.
You have scope problems and an attempt to define a macro inside the replacement text of another macro.
Scope
The macro make_def() invokes an undefined function 'func_call'. The createstuff() function uses an undefined variable mydata. And function dostuff() seems to call an undefined function somefunc_call() with an enum that might, perhaps, have been defined inside a separate function.
If an enumeration is defined inside one function, that enumeration is not available to code outside that function, and specifically is not available to either called functions or calling functions. That alone limits the utility of what you seem to be attempting to do. (Yes, the enumeration values might be implicitly converted to int or some similar type, but it is not really the enumeration type that is being used.)
Defining macros in macros
You cannot create a macro that itself contains #define or any other preprocessor directive in its replacement text.
If the outer macro is invoked, the expansion does not interpret the inner #define as being a preprocessor directive, so it almost always ends up as an error, In context the # must be a stringize operator, and the word 'define' after it would have to be the name of an argument to the outer macro to have a chance of working.
// Does not work as intended
#define macro(define, prefix) #define another(name) foo(prefix ## name)
macro(something, other);
Generates:
"something" another(name) foo(othername);
The _Pragma in C99 is a partial exception to the 'a macro expansion cannot contain a preprocessor directive', but it (_Pragma) does not start with #.
Your macro is incorrect, since you cannot use a macro to create another macro, unfortunately, as the toke # has special meaning in the expansion-list: it can either quote a macro argument, or expand another macro. One easy (albeit poorly designed) way you could do this is just to use old c-style #define MY_ENUM_NAME valueas c macro do not respect scope, but this would not be good design. Another possibility is to pass in string arguments and hash on them, but all depends on what you want to do.