Because you're not using a macro.
## is a preprocessor directive, which is only used within #define'd macros.
The logic is that there are a number of (logical) phases in the process of compiling from source code to file object file (or executable). One of the early phases is the preprocessor which, among other things, does text substitution (eg replacing an #include directive with he contents of the #include'd file, replacing macros with whatever those macros expand to). A subsequent phase of compilation is actually turning the preprocessed source into (typically) machine specific object code.
So, to simplify your example somewhat .... This ....
Code:
#include <iostream>
#define f(g,g2) g##g2
using namespace std;
int main()
{
int var12=100;
cout << f(var,12) << endl;
return 0;
}
will be converted by the preprocessor to something that looks like this;
Code:
// preprocessed contents of <iostream> here verbatim
using namespace std;
int main()
{
int var12=100;
cout << var12 << endl;
return 0;
}
and this preprocessed code is fed through the compilation phase which turns the preprocessed code into an object file (or something similar, depending on your compiler).
If the preprocessor sees ## outside the context of a macro, it does nothing to it. So the compilation phase would see "cout << gr##8;" exactly as is. And the compiler phase knows nothing about preprocessor directives, so complains when it sees this code.