Way to print out compile-time -calculated constants - c

I'm doing some microcontroller programming and I have code along these lines:
#define F_CPU 8000000
#define F_ADC (F_CPU / 64.0)
#define T_ADC (1.0/F_ADC)
Is there a way to print out the calculated values of, say T_ADC at compile time? I tried stringifying it
#define STRINGIFY(s) XSTRINGIFY(s)
#define XSTRINGIFY(s) #s
#pragma message ("T_ADC " STRINGIFY(T_ADC))
But that just gives the macro-expansion "(1/(8000000/64))", not the actual value.
This being a micro-controller program, it's awkward to do a printf at startup time. I'm using gcc and I'm happy to use any non-standard gcc features if that helps.

As #mbratch and #freddie said, the computation is made by the compiler, so you can not get the result simply using preprocessor directives.
The easiest way that comes to mind right now, is to assign the macro to a global const, and then read the value of the const using a debugger, or opening the binary image of the executable (you can get the address of the constant from the memory map file).
const float temp = T_ADC;
Note that you are forced to specify the C type, and this is an essential step since the result of the macro depends on it.

I implemented a baud rate calculation in the preprocessor for a microcontroller but tweaked the integer divide so it rounded (as truncation has more error). Then I displayed the achieved error in a series of categories of low, med and too much, but I stopped short of +-X.X% * due to the extra tedious coding effort.
It was along the lines of http://99-bottles-of-beer.net/language-c-c++-preprocessor-115.html but:-
tedious to do, as it's proportional to:-
the number of digits/categories required
the number of variables as nothing can be shared
fairly preprocessor specific
devoid of any compiler checks
As I don't have the code, the exercise/tediousness is left to the reader...
* Using scaled integer based calculations

It's not exactly what you're looking for but it'll help.
/* definition to expand macro then apply to pragma message */
#define VALUE_TO_STRING(x) #x
#define VALUE(x) VALUE_TO_STRING(x)
#define VAR_NAME_VALUE(var) #var "=" VALUE(var)
#define F_CPU 8000000
#define F_ADC (F_CPU / 64.0)
#define T_ADC (1.0/F_ADC)
#pragma message VAR_NAME_VALUE(T_ADC) /* prints note: #pragma message: T_ADC=(1.0/(8000000 / 64.0) */
This is called Stringification.
Edit: The pre-processor only does string replacement. You could use the pragma message and then use a simple script to do the computation. Continued from my comment above.
$ gcc a.c 2> out
$ python -c "print `cat out | cut -d = -f2`"
8e-06

Related

Expand pragma to a comment (for doxygen)

Comments are usually converted to a single white-space before the preprocesor is run. However, there is a compelling use case.
#pragma once
#ifdef DOXYGEN
#define DALT(t,f) t
#else
#define DALT(t,f) f
#endif
#define MAP(n,a,d) \
DALT ( COMMENT(| n | a | d |) \
, void* mm_##n = a \
)
/// Memory map table
/// | name | address | description |
/// |------|---------|-------------|
MAP (reg0 , 0 , foo )
MAP (reg1 , 8 , bar )
In this example, when the DOXYGEN flag is set, I want to generate doxygen markup from the macro. When it isn't, I want to generate the variables. In this instance, the desired behaviour is to generate comments in the macros. Any thoughts about how?
I've tried /##/ and another example with more indirection
#define COMMENT SLASH(/)
#define SLASH(s) /##s
neither work.
In doxygen it is possible to run commands on the sources before they are fed into the doxygen kernel. In the Doxyfile there are some FILTER possibilities. In this case: INPUT_FILTER the line should read:
INPUT_FILTER = "sed -e 's%^ *MAP *(\([^,]*\),\([^,]*\),\([^)]*\))%/// | \1 | \2 | \3 |%'"
Furthermore the entire #if construct can disappear and one, probably, just needs:
#define MAP(n,a,d) void* mm_##n = a
The ISO C standard describes the output of the preprocessor as a stream of preprocessing tokens, not text. Comments are not preprocessing tokens; they are stripped from the input before tokenization happens. Therefore, within the standard facilities of the language, it is fundamentally impossible for preprocessing output to contain comments or anything that resembles them.
In particular, consider
#define EMPTY
#define NOT_A_COMMENT_1(text) /EMPTY/EMPTY/ text
#define NOT_A_COMMENT_2(text) / / / text
NOT_A_COMMENT_1(word word word)
NOT_A_COMMENT_2(word word word)
After translation phase 4, both the fourth and fifth lines of the above will both become the six-token sequence
[/][/][/][word][word][word]
where square brackets indicate token boundaries. There isn't any such thing as a // token, and therefore there is nothing you can do to make the preprocessor produce one.
Now, the ISO C standard doesn't specify the behavior of doxygen. However, if doxygen is reusing a preprocessor that came with someone's C compiler, the people who wrote that preprocessor probably thought textual preprocessor output should be, above all, an accurate reflection of the token sequence that the "compiler proper" would receive. That means it will forcibly insert spaces where necessary to make separate tokens remain separate. For instance, with test.c the above example,
$ gcc -E test.c
...
/ / / word word word
/ / / word word word
(I have elided some irrelevant chatter above the output we're interested in.)
If there is a way around this, you are most likely to find it in the doxygen manual. There might, for instance, be configuration options that teach it that certain macros should be understood to define symbols, and what symbols those are, and what documentation they should have.

How to catch undefined preprocessor macro with gcc?

I've been working on a piece of code that had an overlooked derp in it:
#include<stdio.h>
#include<stdlib.h>
#include<limits.h>
#define MAX_N_LENGTH
/*function prototypes*/
int main(){
...
}
It should be easy to spot with the context removed: #define MAX_N_LENGTH should have read #define MAX_N_LENGTH 9. I have no idea where that trailing constant went.
Since that macro was only used in one place in the form of char buf[ MAX_N_LENGTH + 1], it was extremely difficult to track down and debug the program.
Is there a way to catch errors like this one using the gcc compiler?
You can use char buf[1 + MAX_N_LENGTH], because char buf[1 +] should not compile with the error message error: expected expression before ']' token:
http://ideone.com/5m2LYw
What you have there isn't an undefined macro. It's an empty macro. And defined empty macros are perfectly legit, because you can test for their definedness.
They're used quite a lot in the implementation header files, although all those empty macros will be in the implementation namespace, which means they will either contain two underscores or an underscore followed by an uppercase letter.
What you could do is test whether you have an empty macro that's not in the implementation namespace, and you can do that with:
cpp -dM YOUR_FILE.c |
cut -d\ -f2- | grep '^[a-zA-Z0-9_]* $' |grep -v -e __ -e ^_[A-Z]
For your example, it should output just MAX_N_LENGTH.
It's not possible to catch this error in the general sense, because it isn't an error. There's plenty of cases where this sort of behavior is desired, so the compiler cannot treat it as an error or a warning.
If you can track the error down to a line, using gcc's -E command line argument will cause it to output the result of the preprocessor. In that case, your char line would have turned to char buf[+1], which is legal C code, but might catch your attention because you expected it to be char buf[9+1]. -E causes gcc to print those results, so you would actually see char buf[+1] in the output of gcc.
Issues like this are why C++ discourages use of define macros in this way (C++, of course, has more alternatives than C which makes it easier to discourage them)
You can use the preprocessor to catch when a macro is either 0 or defined without a value:
#define VAR
#if VAR+0 == 0
#error "VAR is either 0 or defined without a value."
#endif

Is math within macro computed at compile time?

For example, does MIN_N_THINGIES below compile to 2? Or will I recompute the division every time I use the macro in code (e.g. recomputing the end condition of a for loop each iteration).
#define MAX_N_THINGIES (10)
#define MIN_N_THINGIES ((MAX_N_THINGIES) / 5)
uint8_t i;
for (i = 0; i < MIN_N_THINGIES; i++) {
printf("hi");
}
This question stems from the fact that I'm still learning about the build process. Thanks!
If you pass -E to gcc it will show what the preprocessor stage outputted.
gcc -E test.c | tail -n11
Outputs:
# 3 "test.c" 2
int main() {
uint8_t i;
for (i = 0; i < ((10) / 5); i++) {
printf("hi");
}
return 0;
}
Then if you pass -s flag to gcc you will see that the division was optimized out. If you also pass the -o flag you can set the output files and diff them to see that they generated the same code.
gcc -S test.c -o test-with-div.s
edit test.c to make MIN_N_THINGIES equal a const 2
gcc -S test.c -o test-constant.s
diff test-with-div.s test-constant.s
// for educational purposes you should look at the .s files generated.
Then as mentioned in another comment you can change the optimization flag by using -O...
gcc -S test.c -O2 -o test-unroll-loop.s
Will unroll the for loop even such that there isn't even a loop.
Preprocessor will replace MIN_N_THINGIES with ((10)/5), then it is up to the compiler to optimize ( or not ) the expression.
Maybe. The standard does not mandate that it is or it is not. On most compilers it will do after passing optimization flags (for example gcc with -O0 does not do it while with -O2 it even unrolls the loop).
Modern compilers perform even much more complicated techniques (vectorization, loop skewing, blocking ...). However unless you really care about performance, for ex. you program HPC, program real time system etc., you probably should not care about the output of the compiler - unless you're just interested (and yes - compilers can be a fascinating subject).
No. The preprocessor does not calculate macros, they're handled by the compiler. The preprocessor can calculate arithmetic expressions (no floating point values) in #if conditionals though.
Macros are simply text substitutions.
Note that the expanded macros can still be calculated and optimized by the compiler, it's just that it's not done by the preprocessor.
The standard mandates that some expressions are evaluated at compile time. But note that the preprocessor does just text splicing (well, almost) when the macro is called, so if you do:
#define A(x) ((x) / (S))
#define S 5
A(10) /* Gives ((10) / (5)) == 2 */
#undef S
#define S 2
A(20) /* Gives ((20) / (2)) == 10 */
The parenteses are to avoid idiocies like:
#define square(x) x * x
square(a + b) /* Gets you a + b * a + b, not the expected square */
After preprocessing, the result is passed to the compiler proper, which does (most of) the computation in the source that the standard requests. Most compilers will do a lot of constant folding, i.e., computing (sub)expressions made of known constants, as this is simple to do.
To see the expansions, it is useful to write a *.c file of a few lines, just with the macros to check, and run it just through the preprocessor (typically someting like cc -E file.c) and check the output.

"if " and " #if "; which one is better to use [duplicate]

This question already has answers here:
Difference between preprocessor directive #if and normal if
(3 answers)
Closed 9 years ago.
I learned that if or #if can both be used for condition checks.
As we can check conditions using if, why would we use preprocessor #if?
What difference will it make to my code if I use #if instead of if?
Which one is better to use and why?
if and #if are different things with different purposes.
If you use the if statement, the condition is evaluated at runtime, and the code for both branches exists within the compiled program. The condition can be based on runtime information, such as the state of a variable. if is for standard flow control in a program.
If you use the preprocessor's #if, the condition is evaluated at compile-time (originally this was before compile-time, but these days the preprocessor is usually part of the compiler), and the code for the false branch is not included in the compiled program. The condition can only be based on compile-time information (such as #define constants and the like). #if is for having different code for different compile-time environments (for instance, different code for compiling on Windows vs. *nix, that sort of thing).
we could not say which better to use, because one is used in the compilation phase (#if) and the other one is used in the runtime phase(if)
#if 1
printf("this code will be built\n");
#else
printf("this code will not\n");
#endif
try to build the above code with gcc -E and you will see that your compiler will generate another code containing only :
printf("this code will be build\n");
the other printf will not be present in the new code (pre processor code) and then no present in the program binary.
Conclusion: the #if is treated in the compilation phase but the normal if is treated when your program run
You can use the #if 0 in a part of your code inorder to avoid the compiler to compile it. it's like you have commented this part
example
int main(void) {
printf("this code will be build\n");
#if 0
printf("this code will not\n");
#endif
}
it's equivalent to
int main(void) {
printf("this code will be built\n");
/*
printf("this code will not\n");
*/
}
Hey both are different
#if Tests if the condition is true at the compile time.
if is evaluated at runtime.
You should use #if when the outcome of the condition is known at compile time and regular if when outcome is not known until runtime.
#if DEBUG
I know at compile time I am making a debug build
if (date == DateTime.Today)
Depends on what day it is
Some uses of #if are:
You want to put extra prints, or checks when you build a debug version of your code
you want to ensure the compiler doesn't include a .h file twice
you want to write code that will use different system calls, and depending on the system it gets compiled on use the appropriate ones.
Because all of the above are checked at compile time this means that:
The condition must be able to be evaluated at compiletime
The produced code will not contain the branches that evaluate to false, leading to smaller code, and faster, as the condition is not checked every time the program is run.
Examples:
Adding extra checks only for debug mode:
#define DEBUGLEVEL 2
#if DEBUGLEVEL > 1
printf("The value of x is: %d", x);
#end if
#if DEBUGLEVEL > 2
printf("The address of x is: %x", &x);
ASSERT(x > 100);
#end if
Ensuring header only gets included once:
#ifndef PERSON_H
#define PERSON_H
class Person{
....
};
#end if
Having different code depending on platform:
#ifdef WINDOWS
time = QueryPerformanceCounter(..);
#else
time = gettimeofday(..);
#endif

How can I generate a list of #define values from C code?

I have code that has a lot of complicated #define error codes that are not easy to decode since they are nested through several levels.
Is there any elegant way I can get a list of #defines with their final numerical values (or whatever else they may be)?
As an example:
<header1.h>
#define CREATE_ERROR_CODE(class, sc, code) ((class << 16) & (sc << 8) & code)
#define EMI_MAX 16
<header2.h>
#define MI_1 EMI_MAX
<header3.h>
#define MODULE_ERROR_CLASS MI_1
#define MODULE_ERROR_SUBCLASS 1
#define ERROR_FOO CREATE_ERROR_CODE(MODULE_ERROR_CLASS, MODULE_ERROR_SUBCLASS, 1)
I would have a large number of similar #defines matching ERROR_[\w_]+ that I'd like to enumerate so that I always have a current list of error codes that the program can output. I need the numerical value because that's all the program will print out (and no, it's not an option to print out a string instead).
Suggestions for gcc or any other compiler would be helpful.
GCC's -dM preprocessor option might get you what you want.
I think the solution is a combo of #nmichaels and #aschepler's answers.
Use gcc's -dM option to get a list of the macros.
Use perl or awk or whatever to create 2 files from this list:
1) Macros.h, containing just the #defines.
2) Codes.c, which contains
#include "Macros.h"
ERROR_FOO = "ERROR_FOO"
ERROR_BAR = "ERROR_BAR"
(i.e: extract each #define ERROR_x into a line with the macro and a string.
now run gcc -E Codes.c. That should create a file with all the macros expanded. The output should look something like
1 = "ERROR_FOO"
2 = "ERROR_BAR"
I don't have gcc handy, so haven't tested this...
The program 'coan' looks like the tool you are after. It has the 'defs' sub-command, which is described as:
defs [OPTION...] [file...] [directory...]
Select #define and #undef directives from the input files in accordance with the options and report them on the standard output in accordance with the options.
See the cited URL for more information about the options. Obtain the code here.
If you have a complete list of the macros you want to see, and all are numeric, you can compile and run a short program just for this purpose:
#include <header3.h>
#include <stdio.h>
#define SHOW(x) printf(#x " = %lld\n", (long long int) x)
int main(void) {
SHOW(ERROR_FOO);
/*...*/
return 0;
}
As #nmichaels mentioned, gcc's -d flags may help get that list of macros to show.
Here's a little creative solution:
Write a program to match all of your identifiers with a regular expression (like \#define :b+(?<NAME>[0-9_A-Za-z]+):b+(?<VALUE>[^(].+)$ in .NET), then have it create another C file with just the names matched:
void main() {
/*my_define_1*/ my_define_1;
/*my_define_2*/ my_define_2;
//...
}
Then pre-process your file using the /C /P option (for VC++), and you should get all of those replaced with the values. Then use another regex to swap things around, and put the comments before the values in #define format -- now you have the list of #define's!
(You can do something similar with GCC.)
Is there any elegant way I can get a list of #defines with their final numerical values
For various levels of elegance, sort of.
#!/bin/bash
file="mount.c";
for macro in $(grep -Po '(?<=#define)\s+(\S+)' "$file"); do
echo -en "$macro: ";
echo -en '#include "'"$file"'"\n'"$macro\n" | \
cpp -E -P -x c ${CPPFLAGS} - | tail -n1;
done;
Not foolproof (#define \ \n macro(x) ... would not be caught - but no style I've seen does that).

Resources