
The C++ preprocessor doesn’t understand anything about C++, including templates - cow9
https://devblogs.microsoft.com/oldnewthing/20200508-52/?p=103735
======
Wowfunhappy
> The C and C++ preprocessors are like the Windows command prompt batch
> language: They implement a very simple language that people still use for
> some reason.

I can tell you exactly why I use batch scripts—they're the only type of script
that will run on double click in a stock Windows install.

Powershell scripts won't by default for security reasons, but for some reason
for batch it's okay. So I use batch.

~~~
pjmlp
Because tons of legacy applications rely on it and it would be a major outcry
to change them to the way Powershell works.

Locking down batch files, vbs and js scripts can be easily done at AD level
and let people be pissed off with IT instead.

~~~
Wowfunhappy
Okay, but then Microsoft needn't act surprised when people use batch. And
security-wise, I have to question whether that's really a useful outcome
versus letting Powershell scripts run by default.

~~~
pjmlp
Yeah, but it is hardly different than the "curl | sh" fashion I guess.

Here how to disable it,
[https://www.computerhope.com/issues/ch001005.htm](https://www.computerhope.com/issues/ch001005.htm)

------
Robadob
We've come across this problem. The major testing frameworks seem to rely
heavily on macros for tests. In particular, we were struggling to handle tests
of thrown exceptions, as we couldn't trivially capture the result in a
variable and place that inside the macro instead. The most versatile solution
we found was to use a function pointer, so that the templating wasn't required
when the function was called.

~~~
rightbyte
If you want the name of a variable in eg. an assert you need the # operator
unless you require the programmer to manually write the name as a string.

~~~
sesuximo
You could also

1) parse the source file

2) find the debug info and read it

3) hack the compiler to do this for you

------
adrianN
The preprocessor is a really horrible hack of a macro system. I wish we could
get rid of it and replace it with something sensible, but I doubt that will
ever happen.

~~~
pjmlp
In C++ there is very little that we still need it for.

Even for conditional compilation I have always been a fan of using
module_os_arch.cpp than dealing with pre-processor spaghetti.

The tools are there, the problem is getting people to use them instead of
doing C like coding, assuming access to C++17/20 compilers.

As for C, well I don't have high hopes that when WG14 doesn't care about
improving security, they will ever do anything regarding the pre-processor,
specially since it is such a crucial part of C development.

~~~
knorker
> I have always been a fan of using module_os_arch.cpp

Oh no, I found that to work very very poorly. It's an antipatterns because
architectures change, and that you can't cover all architectures.

Not only for my own software (I've maintained portable open source for decades
across many architectures), but also huge frustration when porting software to
a new (for that software) architecture.

Examples:

The software should not care if it's "linux" or "freebsd", you care if
getpwnam_r is the three or four argument version. When one OS changes (or
admin tweaks it) to the POSIX compliant API by default, what do you do then?

OpenBSD is API wise close to FreeBSD. So now I should find all files named .
__freebsd_._ and make a copy to _openbsd_, forking the code, if I port to
OpenBSD?

What about Debian kFreeBSD? You don't have all of these OSs, so just test
features, not OS.

~~~
jstimpfle
I think the general idea is simply that you don't use #ifdef but instead move
the conditional compilation logic to the build script / build system. Of
course you should group in files in a way that avoids redundancy.

This is the way I'm going about it at least, even though I assume there might
be complex situations where the boilerplate isn't warranted and it's better to
put all the variants in a single file and use the preprocessor to determine
which alternative to compile.

Like you say in the end, test features (or maybe _standards support_ ), not
too-specific things like OS or distribution.

~~~
knorker
> the general idea is simply that you don't use #ifdef but instead move the
> conditional compilation logic to the build script / build system.

Yes, I entirely agree. But do NOT split it into what OS or architecture it is,
like what I was replying to said.

------
mehrdadn
Just a PSA, but if the parenthesis solution doesn't work for you, you can
define a COMMA macro and use it there (while everyone yells at you).

------
PunksATawnyFill
Macros are inscrutable garbage and a sorry hack.

