Expand #includes to a text file for C++ - c++

Is it possible to expand out #include lines of a c++ file, probably using the C preprocessor, such that I can read an extended file without #includes, but instead with the files that are #included?
To be concrete, if I have
fileA.cpp:
#include "fileB.H"
int main()
{
//do whatever
return(0);
}
fileB.H:
#include "fileC.H"
//Some lines of code
fileC.H
//Some other lines of code
And output:
//Some other lines of code
//Some lines of code
int main()
{
//do whatever
return(0);
}
Essentially, copy-pasting the files that are included into one large text/C++ code file, without compiling?
If I run the cpp with relevant -I<Directory containing files to include> then I get a long text file, but rather than just code, it gives what would be passed to the compiler (duh!)

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. See this SO answer.

Related

Having difficulties compiling simple c++ program on the command line with multiple files; maybe a linker error?

Sorry for the simple question. I am attempting to learn more c++ at a fundamental level. I have always used VS in the past, and I am trying to learn the command line and compile, navigate, etc. with it.
I started with "hello world" and was able to compile it with gcc/clang, then run it with the expected results.
I then slightly reworked this and made a new header/cpp file to do the output part of hello world, and then call that from the main function, described below:
main.cpp:
#include "MyClass.h"
int main(){
foo();
return 0;
}
MyClass.h
#pragma once
void foo();
MyClass.cpp
#include "MyClass.h"
#include <iostream>
void foo(){
std::cout << "Hello World\n";
}
I then have tried to compile with gcc and clang as follows:
clang -Wall -g main.cpp MyClass.cpp
I have tried the same with GCC, and have also tried various invocations of this, such as using -c:
clang -Wall -g -c main.cpp
clang -Wall -g -c MyClass.cpp
Each and every time, I get an error
λ clang -Wall -g MyClass.cpp main.cpp
main.cpp:13:1: error: use of undeclared identifier 'foo'
foo();
^
1 error generated.
I get this same error whether using gcc or clang.
I also tried from scratch on my laptop, to see if there was some more global issue, but I still get the same problem.
I have also tried on the basic Windows command line as well.
Other areas on StackOverflow demonstrate simple ways of compiling multiple files from the command line, and I have tried as they show, but still get errors.
I also know that "make" is something I need to learn as well, however, I just want to make sure I understand what my make file is doing before I dive into that.
I feel like it must be something trivial that I just cannot figure out.
Thank you to Andreas for the suggestion of looking at the preprocessor output. And thank you to everyone for the suggestions.
The pre-processor output did not make sense to what I was compiling.
I was using VSCode, in this case, as a text editor, making brand new files in my folder after launching it from the command line. I thought the files I created in VSCode directly into the folder (named main.cpp, for example), would produce a regular text file. However, for some reason, it did not.
Essentially, I recreated the above program in notepad and was easily able to compile it using the commands I used above. I guess VSCode may not be perfect for me as a pure text editor or I should figure out if there are settings to change to accomplish my goal.
Thank you all again for your time and consideration.
Use extern on your function. Also make sure you're compiling with c++ and not c; i.e. g++.
MyClass.h
#pragma once
#ifdef __cplusplus
extern "C" {
#endif
extern void foo();
#ifdef __cplusplus
}
#endif

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.

g++: Is there a way to access compile flags inside the code that is being compiled?

Is there a way (e.g., defined constants) to access compile flags with which the compiler was run inside the code that is being compiled.
For example, I want a program that writes the flags with which it was compiled.
int main(){
std::cout << COMPILE_FLAGS << std::endl;
}
Do such constants exist for gcc/g++? Or even better: Are there constants that are defined both in gcc and clang?
I am especially interested in examining the optimization level and the value of the -march flag. So, if there are no constants that show all flags, are there at least ones that display these values?
The following command prints out all predefined macros:
g++ -dM -E - < /dev/null
This works with both gcc and g++. You can check yourself - unfortunately, there is no macro, that gives easy access to the full gcc/g++ command line.
Fortunately, most -m... flags result in adequate precompiler macros to be defined. For example, -m64 defines __x86_64 and -m32 defines __code_model_32__ . Or for -march: -march=core-avx2 results in #define __core_avx2__ 1 .
Just add the option, that you need to check, on the command line above, and check the result for new macro defines.
If you are able to change the compile flags or the script that generates the compilation command, you could add a -DCOMPILE_FLAGS=<the flags you are interested in> to your build to actually create that constant.
From the GCC manual:
-D name=definition The contents of definition are tokenized and processed as if they appeared during translation phase three in a
‘#define’ directive. In particular, the definition will be truncated
by embedded newline characters.

How do I turn off the gcc preprocessor on linux?

I have googled turning off the gcc preprocessor on linux for a good while now (using that exact phrase) and everything has been irrelevant. For example I want to turn off everything except the preprocessor (the opposite of what I want) or pressurising warnings. Does anyone know of a way to disable the preprocessor? I found one that Facebook developed and claimed is faster, and I would like to test it out.
Name your file program.i instead of program.c and it will be treated as already pre-processed by GCC/Clang and sent directly to the compiler.
Example:
$ cat t.i
int printf(const char *f, ...);
int main(){
printf("hello world\n");
}
$ gcc t.i && ./a.out
hello world
I tested what lornix said in a comment, and it works:
Name the other/newer preprocessor "cpp" and put it in your path, and rename the original cpp to cpp-other or cpp-orig. It'll work great considering you are attempting to replace cpp anyways.

C++ command line debug argument

How can I change the value of a boolean macro when I run my program through the command line? For instance, suppose I have the following macro in my cpp file, call it MyCpp.cpp
#define DEBUG 1
How can I change this when I run my program? through the command line:
g++ -Wall -Wextra -o MyCpp MyCpp.cpp
I am pretty sure you specify some kind of command line option, does this ring any bells?
Also, I do NOT want to use argv[]
First, change your source code:
#ifndef DEBUG
# define DEBUG 1
#endif
Now you can say on the command line:
g++ -Wall -Wextra -o MyCpp MyCpp.cpp -DDEBUG=5
# ^^^^^^^^^
The command line argument -DFOO=bar has the same effect as putting #define FOO bar in your source code; you need the #ifndef guard to avoid an illegal redefinition of the macro.
Sometimes people use an auxiliary macro to prevent the definition of another macro:
#ifndef SUPPRESS_FOO
# define FOO
#endif
// ... later
#ifdef FOO
// ...
#endif
Now say -DSUPPRESS_FOO to not define FOO in the code...
How can I change the value of a boolean macro when I run my program through the command line?
As it stands, you can't. You are using a preprocessor symbol so the decision as to whether debug information should be printed is a compile time decision. You are going to have to change that compile-time DEBUG symbol to a run-time variable that you set by parsing the command line, via some configuration file read in at run time, or both.
Parsing the command line isn't that hard. There are plenty of low-level C-style tools to help you do that. Boost has a much more powerful C++ based scheme. The trick then is to change those compile-time debug decisions to run-time decisions. At the simplest, it's not that hard: Just replace that DEBUG preprocessor symbol with a global variable. You can get quite a bit more sophisticated than this of course. Eventually you'll have a configurable logging system. Boost has that, too.
Please note the following. If you have in your c/cpp file or one of your included header files:
#define DEBUG 1
then you cannot modify this definition using the command line of the compiler (makefile). There is simply no chance. The cpp file will simply overwrite the command line setting.