Changing preprocessed values during compile time - c

I have written some code using pre processor directives to skip some statements to be executed.But My C code inside main is interested to change previously #defined values and assign new values as per condition and also change the result of pre processed statements too during run time.In short I have to change the pre processed statements during run time. How can I do this?

In short I have to change the pre processed statements during run time
This is impossible. Read about C preprocessing & cpp. Compile-time and run-time are different (and the compiled code could even run on a different machine, read more about cross-compiling). If using GCC, use gcc -C -E foo.c > foo.i to preprocess your foo.c source file into foo.i preprocessed form (and then use an editor or a page to look inside that generated foo.i)
Perhaps you want to load additional code at runtime. This is not possible with pure C99 standard code. Perhaps your operating system offers dynamic loading. POSIX specifies dlopen. You might also want to use JIT compiling techniques to construct machine code at runtime, e.g. with libraries like GCCJIT, asmjit, GNU lightning, libjit, LLVM, ...
Read also about homoiconic languages. Consider coding in Common Lisp (e.g. with SBCL).
Perhaps you want to customize your GCC compiler with MELT.

Not possible. Preprocessing happens before compile-time.
The compiler only sees the result of the preprocessor, nothing more.

Related

Why would gcc change the order of functions in a binary?

Many questions about forcing the order of functions in a binary to match the order of the source file
For example, this post, that post and others
I can't understand why would gcc want to change their order in the first place?
What could be gained from that?
Moreover, why is toplevel-reorder default value is true?
GCC can change the order of functions, because the C standard (e.g. n1570 or newer) allows to do that.
There is no obligation for GCC to compile a C function into a single function in the sense of the ELF format. See elf(5) on Linux
In practice (with optimizations enabled: try compiling foo.c with gcc -Wall -fverbose-asm -O3 foo.c then look into the emitted foo.s assembler file), the GCC compiler is building intermediate representations like GIMPLE. A big lot of optimizations are transforming GIMPLE to better GIMPLE.
Once the GIMPLE representation is "good enough", the compiler is transforming it to RTL
On Linux systems, you could use dladdr(3) to find the nearest ELF function to a given address. You can also use backtrace(3) to inspect your call stack at runtime.
GCC can even remove functions entirely, in particular static functions whose calls would be inline expanded (even without any inline keyword).
I tend to believe that if you compile and link your entire program with gcc -O3 -flto -fwhole-program some non static but unused functions can be removed too....
And you can always write your own GCC plugin to change the order of functions.
If you want to guess how GCC works: download and study its source code (since it is free software) and compile it on your machine, invoke it with GCC developer options, ask questions on GCC mailing lists...
See also the bismon static source code analyzer (some work in progress which could interest you), and the DECODER project. You can contact me by email about both. You could also contribute to RefPerSys and use it to generate GCC plugins (in C++ form).
What could be gained from that?
Optimization. If the compiler thinks some code is like to be used a lot it may put that code in a different region than code which is not expected to execute often (or is an error path, where performance is not as important). And code which is likely to execute after or temporally near some other code should be placed nearby, so it is more likely to be in cache when needed.
__attribute__((hot)) and __attribute__((cold)) exist for some of the same reasons.
why is toplevel-reorder default value is true?
Because 99% of developers are not bothered by this default, and it makes programs faster. The 1% of developers who need to care about ordering use the attributes, profile-guided optimization or other features which are likely to conflict with no-toplevel-reorder anyway.

Can you add preprocessor directives in assembly?

I would like to execute some assembly instructions based on a define from a header file.
Let's say in test.h I have #define DEBUG.
In test.asm I want to check somehow like #ifdef DEBUG do something...
Is such thing possible? I was not able to find something helpful in the similar questions or online.
Yes, you can run the C preprocessor on your asm file. Depends on your build environment how to do this. gcc, for example, automatically runs it for files with extension .S (capital). Note that whatever you include, should be asm compatible. It is common practice to conditionally include part of the header, using #ifndef ASSEMBLY or similar constructs, so you can have C and ASM parts in the same header.
The C preprocessor is just a program that inputs data (C source files), transforms it, and outputs data again (translation units).
You can run it manually like so:
gcc -E < input > output
which means you can run the C preprocessor over .txt files, or latex files, if you want to.
The difficult bit, of course, is how you integrate that in your build system. This very much depends on the build system you're using. If that involves makefiles, you create a target for your assembler file:
assembler_file: input_1 input_2
gcc -E < $^ > $#
and then you compile "assembler_file" in whatever way you normally compile it.
Sure but that is no longer assembly language, you would need to feed it through a C preprocessor that also knows that this is a hybrid C/asm file and does the c preprocessing part but doesnt try to compile, it then feeds to to the assembler or has its own assembler built in.
Possible, heavily depends on your toolchain (either supported or not) but IMO leaves a very bad taste, YMMV.

Which file is generated after preprocessing of a C program?

For a C program just before compilation, i.e. after the pre-processing has been completed which file(what extension) is generated?
It is compiler dependent. Most compilers by default don't generate intermediate pre-processor files.
With gcc, if you add -save-temps option to get the intermediate files, the output of the pre-processor is dumped in a .i file. With -E option (to perform only the pre-processing), without -o to specify the output file, the result is dumped to stdout.
In most current compilers (e.g. GCC or Clang/LLVM) - and for performance reasons - the C/C++ preprocessor is an internal part of the compiler (in GCC it is libcpp/ and is a library ...), so no preprocessed form is output into a file.
In the very first C or proto-C compilers (1970s PDP-8) the memory was so small (64kilobytes!) that such an organization was not possible, and the preprocessor was a separate program /lib/cpp
Today, our laptops have several gigabytes of memory, which is usually much larger than the preprocessed form (of the largest source file you'll feed to your compiler). So current compilers keep some internal representation of the whole translation unit and are able to optimize it entirely (inter-procedural optimizations, including inlining).
All compilers keep several forms of the abstract syntax tree (AST); the bulk of the work of a compiler is not parsing or code generation, but transforming some internal representation of the AST into another internal representation (itself further transformed). In GCC most of the optimizations are working on the GIMPLE form. You can extend the compiler by adding your own optimization passes, e.g. with your GCC plugin.
In turn, this technological evolution has fertilized the (evolution of) the definition of our programming languages, recent C++11 is designed for a very optimizing compiler. The recent style guiding or coding hints around C++11 are presupposing (and makes sense only because of) very powerful optimizations.
You still can usually invoke the compiler to spit the preprocessed form, e.g. with gcc -C -E source.c > source.i, in a seperate file (conventionally suffixed .i or .ii, and such suffixes can be known to builder like make)
Journey of a C Program to Linux Executable in 4 Stages :
Pre-processing
Compilation
Assembly
Linking
Check this link for more details C program compilation process
>gcc -E fname.c >fname.x /fname.x is the pre-processed output to which u r saving/
The following four things happen in the pre-processing stage.
1> header file inclusion
2>comment removal
3>macro substitution (eg if u have #fenine NUM 10, where-ever in code you have used NUM ll be replaced by 10)
4> conditional compilation (eg
#if 0
...
some code
...
#endif
since "#if 0" evaluates to 0, the code under it never executes. Therefore code under it is not included in your pre-processed output

Extending the C preprocessor to inject code

I am working on a project where I need to inject code to C (or C++) files given some smart comments in the source. The code injected is provided by an external file. Does anyone know of any such attempts and can point me to examples - of course I need to preserve original line numbers with #line. My thinking is to replace the cpp with a script which first does this and then calls the system cpp.
Any suggestions will be appreciated
Thanks
Danny
Providing your modified cpp external program won't usually work, at least in recent GCC where the preprocessing is internal to the compiler (so is part of cc1 or cc1plus). Hence, there is no more any cpp program involved in most GCC compilations (but libcpp is an internal library of GCC).
If using mostly GCC, I would suggest to inject code with you own #pragmas (not comments!). You could add your own GCC plugin, or code your own MELT extension, for that purpose (since GCC plugins can add pragmas and builtins but cannot currently affect preprocessing).
As Ira Baxter commented, you could simply put some weird macro invocations and define these macros in separate files.
I don't exactly guess what precise kind of code injection you want.
Alternatively, you could generate your C or C++ code with your own generator (which could emit #line directives) and feed that to gcc

C/C++ Compiler listing what's defined

This question : Is there a way to tell whether code is now being compiled as part of a PCH? lead me to thinking about this.
Is there a way, in perhaps only certain compilers, of getting a C/C++ compiler to dump out the defines that it's currently using?
Edit: I know this is technically a pre-processor issue but let's add that within the term compiler.
Yes. In GCC
g++ -E -dM <file>
I would bet it is possible in nearly all compilers.
Boost Wave (a preprocessor library that happens to include a command line driver) includes a tracing capability to trace macro expansions. It's probably a bit more than you're asking for though -- it doesn't just display the final result, but essentially every step of expanding a macro (even a very complex one).
The clang preprocessor is somewhat similar. It's also basically a library that happens to include a command line driver. The preprocessor defines a macro_iterator type and macro_begin/macro_end of that type, that will let you walk the preprocessor symbol table and do pretty much whatever you want with it (including printing out the symbols, of course).

Resources