Is there a way to escape a C preprocessor directive? - c++

What I am trying to do is have the C preprocessor output #ifdef, #else, and #endif directives. That is, I would like to somehow "escape" a directive so that the output of the preprocessor includes the directive were the preprocessor to run on the output.
Is it possible to "escape" a CPP directive so that it is outputted by the preprocessor such that the output of an escaped directive would be a preprocessor directive if the CPP output were to be itself preprocessed?

A slight variant of Marcelo Cantos's answer works for me on GNU cpp 4.4.3:
#define HASH(x) x
...
HASH(#)ifdef __cplusplus
class foo { };
HASH(#)endif

EDIT: The following answer only appears to work on earlier versions of cpp. It breaks somewhere between 4.2.1 and 4.3.2. gcc -E and g++ -E break even earlier. See comments for the details.
Here's one trick that seems to work:
#define HASH() #
...
HASH()ifdef __cplusplus
class foo { };
HASH()endif
You'll have to use cpp directly, since a compiler will try to immediately consume the preprocessor output and won't know what to do with the unprocessed directives.

Another trick that seems to work is:
#define EMPTY
EMPTY#ifdef
With GCC's preprocessor (version 4.5.2) I get:
#ifdef
For some reason, this technique has the same leading space issue as Ilmari Karonen's solution, but this is probably not an issue with modern standards-conforming C preprocessors.

Related

Distinguish between Clang CL and MSVC CL

There is CLang-CL which is a drop-in replacement for MSVC's CL.
Does anyone know how to distinguish if my code is currently compiled by clang-cl or msvc's cl? Without passing any extra defined macros on command line.
Using
#ifdef _MSC_VER
//.....
#endif
doesn't work, both compilers define _MSC_VER.
Also in regular CLang on Linux (Windows too) it was possible to do clang -dM -E - < /dev/null which dumps all defined macros. But clang-cl and msvc-cl both don't have such option to dump all defined macros as far as I know, so I don't know of a way to see a difference in list of defined macros for both compilers to figure out which macro to use to distinguish between these compilers.
The macro you're looking for is __clang__.
Note that the regular Clang (not only Clang-CL) also defines it, so you want to check for both __clang__ and _MSC_VER at the same time.

What kind of code is in that file *.cpp.. #define mdTyVzgFy4_0UFy9GimmM

I just downloaded an open source code from a library called aruco for QR code detection written in C++, and while I was examing the code I found some files that doesn't look like c++..
Would anyone understand what kind of code is that? It looks like that
#define mUXyv8dbk5ppT_acPhWw1 mFzTZaNOrvPJ32i9gU3Wr9J28M8DBzQ(a,:,[,+,c,+,:,^,Z,Z,/,-,r,O,[,;,9,e,;,P)
#define mmdgJNaGE2dbCM6TccQ56 mkzSZJDew824aa0gKauM6fZ2VRvPUyZ(^,Q,5,r,j,P,t,B,c,;,T,A,o,W,},u,*,e,7,/)
#define mVBw_rTkATYMOTRmsNe_B mGJoExPsp9LQpgvTNdOhH4AqaFjFPrq(+,W,4,t,i,o,d,2,e,P,1,A,:,a,E,S,v,F,Y,V)
#define mH9xkXr1In9WhMDYLLAkQ mhN2hPhnFFq5alNSwVOjtfx8xECWu2g(R,r,R,z,t,2,i,b,!,k,S,n,e,C,k,K,5,o,K,a)
#define mSye5PefiM2uFq__QqZRQ m_dk3EP_dRaChCeAYkjUT4mGB6eHLjG(s,Y,^,r,*,P,D,X,y,^,b,},k,4,a,=,i,X,!,v)
#define mJpQJFURUc57_1UwCTPvr mByXC_NAGVGzCcmUEv_c9mAYK8t5jBN(t,R,.,>,!,i,W,0,R,C,*,Y,A,>,K,h,T,-,*,8)
#define my9E4sAt6II28meWefBqO mu1aRcYPGwwmkdvLrXjWyYkshrNbQfZ(8,N,+,t,},r,I,T,=,C,*,h,!,m,{,/,D,y,_,T)
#define mRtPBvwiZzHWglctKPmaF msiqIfe8Aci2FIHOTIR3qsdKyqc9jUO(7,i,j,^,_,^,6,},I,<,E,-,/,d,j,=,:,N,+,s)
#endif
#ifndef _ARUCO_MarkerDetector_Impl_H
#define _ARUCO_MarkerDetector_Impl_H
#include "aruco_export.h"
#include "markerdetector.h"
#include <opencv2/imgproc/imgproc.hpp>
mH83V9yQZ4TlJHtn2Baef
aruco
mBduW7dqSuFrUAvwh7kHo
mTj14DRd7xgEPvsp5xhPs
CameraParameters mVlbuMLWi_vwpED0hDKIw
mrJuVHPe96ExiggCdsmDG
MarkerLabeler mv0LWHXRSvGJF76ckeLfO
mPXYuzTL9RZjjZA9XYUV9
MarkerDetector_Impl
mYwjl00gOK3Vja3UkLMIP
friend mukY8albO2VdJSsWPXwW4
MarkerDetector mD07x3flmZMPVC6kwqG6P
public:
MarkerDetector_Impl mnODdIJiXbJxgUNOnnK7Q
mYCDBBfn03HaGvoHBxAMq
MarkerDetector_Impl mK8B3zN6mQAB0xYXFlxGO
int dict_type, mYJJZNT6RsQUQcGvcjw6s
error_correction_rate mRUhvrauugCIk8ZFUtFF5
0 mswZzmsb_awITT3YY34kR
What kind of code is in that file *.cpp.. #define mdTyVzgFy4_0UFy9GimmM
#define mdTyVzgFy4_0UFy9GimmM is a pre-processor directive that defines a macro. Macros are used to replace text during pre-processing.
Would anyone understand what kind of code is that?
Probably no human can understand it. And that is probably the reason why that has been done in the first place: It seems to be an attempt to obfuscate the source code.
You can use a pre-processor to generate the processed code to see what the compiler sees. For example, gcc -E. Note that the pre-processor will expand the include directives, so you'll need to scroll past the included files first.
Would anyone understand what kind of code is that?
Yes! Wow this is fun. That is indeed an obfuscated source code.
It is still C/C++. It is using pre-processor definitions. Basically it is a key that can be used multiple times. (like a variable).
The compiler will search for all preprocessor definitions and replaces them by the actual text.
I guess you want to deobfuscate it to have a closer look in the source code.
For gcc and clang, you can use the -E option (see similar answer) to output the preprocessor output without compiling.
To also show comments like in your sample output, you can add in the -CC and -P flags:
clang++ -E -CC -P fileA.cpp
All of the processor options for -E can be found on here, on
gcc.gnu.org.
-CC Do not discard comments, including during macro expansion. This is like -C, except that comments contained within macros are also passed
through to the output file where the macro is expanded.
-P Inhibit generation of linemarkers in the output from the preprocessor. This might be useful when running the preprocessor on
something that is not C code, and will be sent to a program which
might be confused by the linemarkers.
For the Visual C++ compiler, you can use /E.

Avoid gcc warning for (generated) tokens after preprocessing directive?

Microsoft's MIDL compiler generates C/C++ source code files that are slightly invalid, like the code in this extract:
#ifndef CLSID_DEFINED
#define CLSID_DEFINED
typedef IID CLSID;
#endif // CLSID_DEFINED
#define MIDL_DEFINE_GUID(type,name,l,w1,w2,b1,b2,b3,b4,b5,b6,b7,b8) \
const type name = {l,w1,w2,{b1,b2,b3,b4,b5,b6,b7,b8}}
#endif !_MIDL_USE_GUIDDEF_
The tokens after #endif are ignored by Visual C++, but the Holy Standard require nothing there, and so g++ errs out, and even gcc (compiling as C) yields a warning:
H:\dev\tools\better keyboard\test>gcc com_server\com_server_i.c -c
com_server\com_server_i.c:68:8: warning: extra tokens at end of #endif directive
#endif !_MIDL_USE_GUIDDEF_
^
H:\dev\tools\better keyboard\test>_
It gets tiresome and annoying to manually fix up that code each time that it's generated.
Is there some better way to avoid this apparently unnamed warning, assuming that gcc must compile the code?
I have looked at an existing question roughly about this, but to no avail.
Converting comments into an answer.
The simplest mechanism is probably to post-process the generated code:
sed -i.bak -e 's/^#endif .*/#endif/' com_server/com_server_i.c
or equivalent. Or you can preserve the material after the #endif but put a comment there:
sed -i.bak -e 's%^#endif \(.*\)%#endif // \1%' com_server/com_server_i.c
If you're using a makefile, it is pretty easy to add the post-processing as an extra operation after the invocation of the MIDL compiler.
The cross-referenced question won't readily help; the ! cannot be removed by macro definition. Actually, the presence of a macro after the #endif elicits the warning even if the macro expands to nothing.
Have you checked the Microsoft bug reports for the MIDL compiler (to see whether it is a known problem that they decline to fix)? And have you checked the options to the MIDL compiler to see if there's anything that would fix this?

cross platform macro for silencing unused variables warning

In porting a large piece of C++ code from Visual Studio (2008) to Xcode (4.4+), I encounter lines such as:
UNUSED_ALWAYS(someVar);
the UNUSED_ALWAYS(x) (through UNUSED(x)) macro expands to x which seems to silence Visual C++ just fine. It's not enough for Clang however.
With Clang, I usually use the #pragma unused x directive.
The UNUSED_ALWAYS and UNUSED macros are defined in an artificial windows.h header which I control that contains a number of utilities to help Xcode compile Windows stuff.
Is there a way to define UNUSED(x) to expand to #pragma unused x? I tried this, which Clang fails to accept:
#define UNUSED(x) #pragma unused(x)
I also tried:
#define UNUSED(x) (void)(x)
Which seems to work. Did I miss anything?
(void)x;
is fine; has always worked for me. You can't usually expand a macro to a #pragma, although there is usually a slightly different pragma syntax that can be generated from a macro (_Pragma on gcc and clang, __pragma on VisualC++).
Still, I don't actually need the (void)x anymore in C++, since you can simply not give a name to a function parameter to indicate that you don't use it:
int Example(int, int b, int)
{
... /* only uses b */
}
works perfectly fine.
Yup - you can use this approach for GCC and Clang:
#define MON_Internal_UnusedStringify(macro_arg_string_literal) #macro_arg_string_literal
#define MONUnusedParameter(macro_arg_parameter) _Pragma(MON_Internal_UnusedStringify(unused(macro_arg_parameter)))
although mine did have the (void) approach defined for clang, it appears that Clang now supports the stringify and _Pragma approach above. _Pragma is C99.
#define and #pragma both are preprocessor directives. You cannot define one macro to expand as preprocessor directive. Following would be incorrect:
#define MY_MACRO #if _WIN32
MY_MACRO cannot expand to #if _WIN32 for the compiler.
Your best bet is to define your own macro:
#define UNUSED(_var) _var

Detect ICC vs GCC at compile time

How to detect at compile time if I'm using gcc or icc?
(I was quite puzzled to find out that icc defines __GNUC__ -- and even __GNUC_MINOR__ and __GNUC_PATCHLEVEL__ ! why?)
We use
#ifdef __INTEL_COMPILER
to split icc off, assuming gcc as a default.
I believe you could check for __INTEL_COMPILER according to this.
The reason ICC defines __GNUC__ etc. is because of code like yours that is inspecting compiler-specific macros and expects to see them...
Traditionally, compilers have defined a symbol of their own as well as their version as preprocessor symbols so that the code could be adapted (generally to work around bugs or specificities).
CLang has introduced a mechanism I had not seen so far, under the form of the __has_feature query. It does not replace the "work around bugs" practices (which is why CLang still exposes specific symbols) but allows a more natural style for querying the compiler capacities. I don't know if other compilers plan on defining such a facility.
You can make the processor output the defined macros in the preprocessor output and look for a macro that suits you. You can generated the preprocessor output like this:
icc -dM -E -o foo.P foo.c
Then look at foo.P (since it is a text file). In my case, I found icc defined an __ICC macro with the version of the compiler. It didn't define any __INTEL_COMPILER though.