Getting the preprocessor to process a block of code - c

I have a system where I specify on the command line the verbosity level. In my functions I check against what was specified to determine if I enter a code block or not:
#ifdef DEBUG
if (verbose_get_bit(verbose_level_1)) {
// arbitrary debugging/printing style code generally goes in here, e.g.:
printf("I am printing this because it was specified and I am compiling debug build\n");
}
#endif
I'd like to make this less tedious to set up, so here's what I have so far:
// from "Verbose.h"
bool verbose_get_bit(verbose_group_name name); // verbose_group_name is an enum
#ifdef DEBUG
#define IF_VERBOSE_BIT_D(x) if (verbose_get_bit(x))
#else // not debug: desired behavior is the entire block that follows gets optimized out
#define IF_VERBOSE_BIT_D(x) if (0)
#endif // not debug
Now, I can do this:
IF_VERBOSE_BIT_D(verbose_GL_debug) {
printf("I don't want the release build to execute any of this code");
glBegin(GL_LINES);
// ... and so on
}
I like this because it looks like an if-statement, it functions as an if-statement, it's clear that it's a macro, and it does not get run in the release build.
I'd be reasonably sure that the code will get optimized out since it will be wrapped in a if(false) block but I would prefer it if there was some way I can get the preprocessor to actually throw the entire block away. Can it be done?

I can't think of a way to do it without wrapping the entire block in a macro.
But this might work for your purposes:
#if DEBUG
#define IF_VERBOSE_BIT_D(x) {x}
#else
#define IF_VERBOSE_BIT_D(x)
#endif
IF_VERBOSE_BIT_D(
cout << "this is" << endl;
cout << "in verbose" << endl;
printf("Code = %d\n", 1);
)
Indeed the compiler should be able to optimize out an if (0), but I often do something similar to this when the code inside the block will not compile at all when not in debug mode.

Not anywhere near as neatly as you just did it. Don't worry, your compiler will fully optimize out any if(0) block.
You can if you so desire check this by writing a program in which you have it as you described and compiling it. If you then remove the if(false) blocks, it should compile to the exact same binary, as shown by an MD5 hash. But that's not necessary, I promise your compiler can figure it out!

Just create a condition in the if-statement which is starts with "false &&" if you want to have it disabled entirely. Unless you compile without any optimization the compiler typically removes dead code.

Related

C macro parameter test at design time

I need a macro variable check at design time (preprocesor), more specific that number to fit in 24 bits.
The macro is intended to be used in a if() statement so I have no idea how to test it.
This is a ARM systick timer (24 bits) and so many time I forgot to #define the right value, especially when change the MCU clock and of course, my if() never fired and this silly mistake was hard to debug.
So in this example, there is a trick to force gcc to ERROR when PARAMETER > 24 bits ?
#define PARAMETER 20000000 // over 24 bits, should throw a error at design time
#define MyMacro(var, par) (var > par)
uint32_t variable;
if(MyMacro(variable,PARAMETER))
{
// do something
// do something WRONG because PARAMETER > 24 bits
// Actually this is working as expected, test for < is valid because
// _Static_assert() is check for TRUE condition
// But I am still trying to find a way to combine this in original macro
_Static_assert(PARAMETER < 0xFFFFFF, "Ooopss... ERROR");
}
Thanks in advance!
Unfortunately, _Static_assert is syntactically defined as a declaration, which means you can't use it directly inside of an expression.
However, _Static_assert isn't needed anyway, because you can perfectly (sans the nice compile time error reporting--but you're a programmer, you should be able to figure out a compile time failure a slightly more technical compile-time error message) emulate it with
#define static_assert_0expr(Truth) ((int)(0*sizeof(struct { int _ : (Truth)?1:-1; })))
(or an equivalent) and that you can fit in an expression (even an integer constant expression) no problem:
#define static_assert_0expr(Truth) ((int)(0*sizeof(struct { int _ : (Truth)?1:-1; })))
#define PARAMETER 20000000 // over 24 bits, should throw a error at design time
#define MyMacro(var, par) (static_assert_0expr((par)<0xffffff) + ((var) > (par)))
//or this, but this is won't preserve integer-constant expressions because of the comma:
/*#define MyMacro(var, par) (static_assert_0expr((par)<0xffffff), ((var) > (par)))*/
//alternatively: (static_assert_0expr(assertion) ? (expr) : (expr)) is the most
//general form (though it leads to larger preprocessor expansions, which may worsen debugging experience with cc -E)
#include <stdint.h>
int main()
{
static_assert_0expr(1)+1;
uint32_t variable;
if(MyMacro(variable,PARAMETER))
{
}
}
The above static_assert_0expr macro could also be implemented with _Static_assert:
#define static_assert_0expr(Truth) \
((int)(0*sizeof(struct { int _; _Static_assert(Truth,""); })))
or you could paste the body of this directly in MyMacro and customize the message (but I consider _Static_assert and its custom compile-time error message feature an unnecessary addition to C and prefer not to use it).
Well, I don't want to reply my own answer, but I think I found a solution that is working (thanks #PSkoicik) and thanks to GCC that allows statement expressions (found in this reply)
Using and returning output in C macro
So basically I could use _Static_assert() inside if() statement, with a helper macro
#define CheckParameter(val) ({bool retval = true; _Static_assert((val)< 0xFFFFFF, "Timer value too large!"); retval;})
Now my macro become
#define MyMacro(var, par) ((var > par) && CheckParameter(par))
Which should work because CheckParameter() will always return TRUE at RUNTIME but at COMPILE time, _Static_assert() will catch my error parameter.
So now I can use
if(MyMacro(variable,PARAMETER))
{
// PAREMETER will be in range
}
Hope I'm not missing something :)
If you need to check that PARAMETER is > 24 bits during compile time you can simply do this:
#define PARAMETER 20000 // over 24 bits, should throw a error at design time
...
#if PARAMETER > (1<<24)
#error PARAMETER > 24 bits
#endif
What you do here is not compile time checking but run time checking:
if(MyMacro(variable,PARAMETER))
{
// do something
// do something WRONG because PARAMETER > 24 bits
}
but what is variable doing here anyway if you just want to know if PARAMETER is > 24 bits?

Using ENUMs as bitmaps, how to validate in C

I am developing firmware for an embedded application with memory constraints. I have a set of commands that need to processed as they are received. Each command falls under different 'buckets' and each 'bucket' gets a range of valid command numbers. I created two ENUMs as shown below to achieve this.
enum
{
BUCKET_1 = 0x100, // Range of 0x100 to 0x1FF
BUCKET_2 = 0x200, // Range of 0x200 to 0x2FF
BUCKET_3 = 0x300, // Range of 0x300 to 0x3FF
...
...
BUCKET_N = 0xN00 // Range of 0xN00 to 0xNFF
} cmd_buckets;
enum
{
//BUCKET_1 commands
CMD_BUCKET_1_START = BUCKET_1,
BUCKET_1_CMD_1,
BUCKET_1_CMD_2,
BUCKET_1_CMD_3,
BUCKET_1_CMD_4,
//Add new commands above this line
BUCKET_1_CMD_MAX,
//BUCKET_2 commands
CMD_BUCKET_2_START = BUCKET_2,
BUCKET_2_CMD_1,
BUCKET_2_CMD_2,
BUCKET_2_CMD_3,
//Add new commands above this line
BUCKET_2_CMD_MAX,
//BUCKET_3 commands
...
...
...
//BUCKET_N commands
CMD_BUCKET_N_START = BUCKET_N
BUCKET_N_CMD_1,
BUCKET_N_CMD_2,
BUCKET_N_CMD_3,
BUCKET_N_CMD_4,
//Add new commands above this line
BUCKET_N_CMD_MAX,
}cmd_codes
When my command handler function receives a command code, it needs to check if the command is enabled before processing it. I plan to use a bitmap for this. Commands can be enabled or disabled from processing during run-time. I can use an int for each group (giving me 32 commands per group, I realize that 0xN00 to 0xN20 are valid command codes and that others codes in the range are wasted). Even though commands codes are wasted, the design choice has the benefit of easily telling the group of the command code when seeing raw data on a console.
Since many developers can add commands to the 'cmd_codes' enum (even new buckets may be added as needed to the 'cmd_buckets' enum), I want to make sure that the number of command codes in each bucket does not exceed 32 (bitmap is int). I want to catch this at compile time rather than run time. Other than checking each BUCKET_N_CMD_MAX value as below and throwing a compile time error, is there a better solution?
#if (BUCKET_1_CMD_MAX > 0x20)
#error ("Number of commands in BUCKET_1 exceeded 32")
#endif
#if (BUCKET_2_CMD_MAX > 0x20)
#error ("Number of commands in BUCKET_2 exceeded 32")
#endif
#if (BUCKET_3_CMD_MAX > 0x20)
#error ("Number of commands in BUCKET_3 exceeded 32")
#endif
...
...
...
#if (BUCKET_N_CMD_MAX > 0x20)
#error ("Number of commands in BUCKET_N exceeded 32")
#endif
Please also suggest if there is a more elegant way to design this.
Thanks, I appreciate your time and patience.
First fix the bug in the code. As mentioned in comments, you have a constant BUCKET_1 = 0x100 which you then assign CMD_BUCKET_1_START = BUCKET_1. The trailing enums will therefore get values 0x101, 0x102, ... and BUCKET_1_CMD_MAX will be 0x106. Since 0x106 is always larger than 0x20, your static assert will always trigger.
Fix that so that it actually checks the total number of items in the enum instead, like this:
#define BUCKET_1_CMD_N (BUCKET_1_CMD_MAX - CMD_BUCKET_1_START)
#define BUCKET_2_CMD_N (BUCKET_2_CMD_MAX - CMD_BUCKET_2_START)
...
Assuming the above is fixed, then you can replace the numerous checks with a single macro. Not a great improvement, but at least it reduces code repetition:
#define BUCKET_MAX 32 // use a defined constant instead of a magic number
// some helper macros:
#define CHECK(n) BUCKET_ ## n ## _CMD_N
#define STRINGIFY(n) #n
// the actual macro:
#define BUCKET_CHECK(n) \
_Static_assert(CHECK(n) <= BUCKET_MAX, \
"Number of commands in BUCKET_" STRINGIFY(n) "_CMD_N exceeds BUCKET_MAX.");
// usage:
int main (void)
{
BUCKET_CHECK(1);
BUCKET_CHECK(2);
}
Output from gcc in case one constant is too large:
error: static assertion failed: "Number of commands in BUCKET_1_CMD_N exceeds BUCKET_MAX."
note: in expansion of macro 'BUCKET_CHECK'
EDIT
If combining the bug fix with the check macro, you would get this:
#define BUCKET_MAX 32
#define CHECK(n) (BUCKET_##n##_CMD_MAX - CMD_BUCKET_##n##_START)
#define STRINGIFY(n) #n
#define BUCKET_CHECK(n) \
_Static_assert(CHECK(n) <= BUCKET_MAX, \
"Number of commands in BUCKET " STRINGIFY(n) " exceeds BUCKET_MAX.");
int main (void)
{
BUCKET_CHECK(1);
BUCKET_CHECK(2);
}
First of all, preprocessor commands do not work that way. The C preprocessor is able to "see" only names instruced by the #define statement or passes as compiler flags. It is not able to see constants defined as part of an enum or with the const keyword. You should use _Static_assert to validate the commands instead of the preprocessor.
As for the commands, I would suggest to have all the commands numbered in the range 0..0x20:
enum {
BUCKET_1_CMD_1,
BUCKET_1_CMD_2,
...
BUCKET_1_CMD_MAX,
};
enum {
BUCKET_2_CMD_1,
BUCKET_2_CMD_2,
...
BUCKET_2_CMD_MAX,
};
Then you need only a single guard value to check if all the commands are in valid range:
#define MAX_COMMAND 0x20
_Static_assert(BUCKET_1_CMD_MAX <= MAX_COMMAND, "too many bucket 1 commands");
_Static_assert(BUCKET_2_CMD_MAX <= MAX_COMMAND, "too many bucket 2 commands");
To use the commands, bitwise-or them together with the bucket "offset":
enum {
BUCKET_1 = 0x100,
BUCKET_2 = 0x200,
};
...
int cmd = BUCKET_2 | BUCKET_2_CMD_1;

Can #include directives go somewhere other than the start of a file (like inside a loop)? [duplicate]

This question already has answers here:
Closed 11 years ago.
Possible Duplicate:
#include anywhere
For the respective languages, is the following valid (acceptable programming practice):
#include "SomeHeader.h"
#include "HeaderDefs.h" //Includes #defines (like CONST_VAR)
void Function1(){;}
void Function2(){;} //etc
//Additionally:
void Function3(){while(1){
#include "Files.h"
;
}} //Result?
#include "HeaderUndefs.h" //Includes #undef (like undef CONST_VAR)
In expansion from below comment:
I expanded. Bear in mind it's 'validity' and not 'will it compile'. I am sure it can compile, but Stack Overflow offers insights (like Daniel Wagner's) that intrigues further exploration. Can I have a while loop of #includes? (Or does this break convention... #includes anywhere - are they valid also?).
Yep, #include directives can go just about anywhere. Even inside functions, or for loops, or anything. The preprocessor that fills that stuff in doesn't know anything about the C (or C++) language, it's totally dumb.
It is valid, but probably has no purpose for CPP files (which I assume yours is, since you have function bodies).
CPP files are not intended to be included in other files, so just undefining macros by #include "HeaderUndefs.h" at the end of CPP won't be seen anywhere. If, however, "HeaderUndefs.h" does something that is meaningful as a part of a CPP file (such as defining functions), it may make sense. This is usually a horrible thing for maintainability, but can be done...
The code you presented is not valid and will not compile. A #include directive, like any other preprocessor directive, must be on a line by itself. There can be arbitrary whitespace (including comments) before the #, between the # and the include, etc., but there can't be any other code (or other directives) on the same line. EDIT: This applied to the original version of the question; it was edited while I was writing this.
If your code is modified so the #include is on a line by itself, it's potentially valid (depending on the contents of the file you're including). But it's not at all a useful thing to do. In particular, #include directives are processed at compile time; putting a #include directive inside a loop does not mean that the file will be included multiple times.
It might make sense to put a chunk of code in a separate file and #include it inside a loop; for example, you might choose which file to include based on some configuration option. But it's an extremely ugly way to structure your code, and whatever you're trying to accomplish, there's almost certainly a cleaner way to do it. (For example, the included file might define a macro that you can invoke inside the loop; you could then have the #include directive at the top of your source file.)
Think of the preprocessor as a power tool with no safety features. Use it with discipline, and you can do useful things with it. Start using it in "clever" ways, and you can lose limbs.
Typically, included files are headers, which contain prototypes, definititions, types, and other data that must be declared/defined BEFORE the code in the file itself, which is why they are at the top. It is rare to have a included file that contains information that is more useful in another place in the file.
Undefs are possible, but seem like they would cause more problems, since the only possible purpose would be to put them in the middle of a compilation unit, which would just be confusing.
A more common usage is .inl files, which are "inline" files, which work like very large macros. The only one I use is a "BitField.inl" I made, which makes a handy bitfield class along with a ToString(...) member, which is used as follows:
#define BITNAME State
#define BITTYPES SEPERATOR(Alabama) SEPERATOR(Alaska) SEPERATOR(Arazona) SEPERATOR(Arkansas) SEPERATOR(California) \
SEPERATOR(Colorado) SEPERATOR(Connecticut) SEPERATOR(Delaware) SEPERATOR(Florida) SEPERATOR(Georga) \
SEPERATOR(Hawaii) SEPERATOR(Idaho) SEPERATOR(Illinois) SEPERATOR(Indiana) SEPERATOR(Iowa) \
SEPERATOR(Kansas) SEPERATOR(Kentucky) SEPERATOR(Louisiana) SEPERATOR(Maine) SEPERATOR(Maryland) \
SEPERATOR(Massachusettes) SEPERATOR(Michigan) SEPERATOR(Minnesota) SEPERATOR(Mississippi) SEPERATOR(Missouri) \
SEPERATOR(Montana) SEPERATOR(Nebraska) SEPERATOR(Nevada) SEPERATOR(NewHampshire) SEPERATOR(NewJersey) \
SEPERATOR(NewMexico) SEPERATOR(NewYork) SEPERATOR(NorthCarolina) SEPERATOR(NorthDakota) SEPERATOR(Ohio) \
SEPERATOR(Oklahoma) SEPERATOR(Oregon) SEPERATOR(Pennsylvania) SEPERATOR(RhodeIsland) SEPERATOR(SouthCarolina) \
SEPERATOR(SouthDakota) SEPERATOR(Tennessee) SEPERATOR(Texas) SEPERATOR(Utah) SEPERATOR(Vermont) \
SEPERATOR(Virginia) SEPERATOR(Washington) SEPERATOR(WestVerginia) SEPERATOR(Wisconsin) SEPERATOR(Wyoming)
#include "BitField.inl" // WOO MAGIC!
int main() {
StateBitfield States;
States.BitField = 0; // sets all values to zero;
States.Alaska = 1; // activates Alaska;
std::cout << "States.Bitfield=" << (int)States.BitField << std::endl;
//this is machine dependent.
States.BitField |= (StateBitfield::WashingtonFlag | StateBitfield::IdahoFlag);
// enables two more
std::cout << "CaliforniaFlag=" << (States.BitField & StateBitfield::CaliforniaFlag) << '\n';
// 0, false.
std::cout << "sizeof(colorBitField)=" << sizeof(colorBitfield) << std::endl;
// 4, since BITTYPE wasn't defined
States.BitField = (StateBitfield::AlaskaFlag | StateBitfield::MinnesotaFlag | StateBitfield::FloridaFlag | StateBitfield::NorthDakotaFlag |
StateBitfield::SouthDakotaFlag | StateBitfield::CaliforniaFlag | StateBitfield::OregonFlag| StateBitfield::NevadaFlag |
StateBitfield::IdahoFlag | StateBitfield::MichiganFlag | StateBitfield::OregonFlag| StateBitfield::NevadaFlag);
// sets the states I've been to
//for each state, display if I've been there
for(unsigned int i=0; i<50; i++) {
//This is showing what is enabled
if (States.BitField & (1LL << i))
std::cout << StateBitfield::ToString((StateBitfield::StateBitNum) i) << '\n';
}
//Shows the states that were flagged
std::cout << States.Alaska << States.Minnesota << States.Florida << States.NorthDakota << States.SouthDakota << States.California <<
States.Oregon << States.Nevada << States.Idaho << States.Michigan << States.Oregon << States.Nevada << std::endl;
//displays 111111111111 (I think I had this in for debugging.)
}
States.BitField &= StateBitfield::NoFlags;
//set all to zero
States.BitField |= StateBitfield::AllFlags;
//set all to one
}
You can put an #include directive just about anywhere in the code; that doesn't mean it's a good idea.
I remember having to maintain some code where the author put random snippets of code into header files and #included them where necessary (these weren't self-contained functions, they were just blocks of statements). This made code that was already badly written and hard to follow that much worse.
There's a temptation to use the preprocessor for really sophisticated tasks; resist that temptation.
i think this is valid if you don't use any variable or function from the HeaderUnderfs.h
before #include "HeaderUnderfs.h"
/#include is a preprocessor directive. They mean nothing to the actual language, and are valid. To the compiler, those physical files are inserted in-line with the other source.

Using the C preprocessor to effectively rename variables

I'm writing a few very tight loops and the outermost loop will run for over a month. It's my understanding that the less local variables a function has, the better the compiler can optimize it. In one of the loops, I need a few flags, only one of which is used at a time. If you were the proverbial homicidal maniac that knows where I live, would you rather have the flag named flag and used as such throughout or would you prefer something like
unsigned int flag;
while (condition) {
#define found_flag flag
found_flag = 0;
for (i = 0; i<n; i++) {
if (found_condition) {
found_flag = 1;
break;
}
}
if (!found_flag) {
/* not found action */
}
/* other code leading up to the next loop with flag */
#define next_flag flag
next_flag = 0;
/* ... /*
}
This provides the benefit of allowing descriptive names for each flag without adding a new variable but seems a little unorthodox. I'm a new C programmer so I'm not sure what to do here.
Don't bother doing this, just use a new variable for each flag. The compiler will be able to determine where each one is first and last used and optimise the actual amount of space used accordingly. If none of the usage of the flag variables overlap, then the compiler may end up using the same space for all flag variables anyway.
Code for readability first and foremost.
I completely agree with dreamlax: the compiler will be smart enough for you to ignore this issue entirely, but I'd like to mention that you neglected a third option, which is rather more readable:
while (something) {
/* setup per-loop preconditions */
{
int flag1;
while (anotherthing) {
/* ... */
}
/* deal with flag found or not-found here */
}
/* possibly some other preconditions */
{
int flag2;
while (stillanotherthing) {
/* ... */
}
}
}
which would tell a dumb compiler explicitly when you are done with each flag. Note that you will need to take care about where you declare variables that need to live beyond the flag-scope blocks.
Your trick would only be useful on very old, very simple, or buggy compilers that aren't capable of correct register (re)allocation and scheduling (sometimes, that's what one is stuck with for various or ancient embedded processors). gcc, and most modern compilers, when optimizations are turned on, would reallocate any register or local memory resources used for local variables until they are almost hard to find when debugging at the machine code level. So you might as well make your code readable and not spend brain power on this type of premature optimization.

Mangling __FILE__ and __LINE__ in code for quoting?

Is there a way to get the C/C++ preprocessor or a template or such to mangle/hash the __FILE__ and __LINE__ and perhaps some other external input like a build-number into a single short number that can be quoted in logs or error messages?
(The intention would be to be able to reverse it (to a list of candidates if its lossy) when needed when a customer quotes it in a bug report.)
You will have to use a function to perform the hashing and create a code from __LINE__ and __FILE__ as the C preprocessor is not able to do such complex tasks.
Anyway, you can take inspiration by this article to see if a different solution can be better suited to your situation.
Well... you could use something like:
((*(int*)__FILE__ && 0xFFFF0000) | version << 8 | __LINE__ )
It wouldn't be perfectly unique, but it might work for what you want. Could change those ORs to +, which might work better for some things.
Naturally, if you can actually create a hashcode, you'll probably want to do that.
I needed serial valuse in a project of mine and got them by making a template that specialized on __LINE__ and __FILE__ and resulted in an int as well as generating (as compile time output to stdout) a template specialization for it's inputs that resulted in the line number of that template. These were collected the first time through the compiler and then dumped into a code file and the program was compiled again. That time each location that the template was used got a different number.
(done in D so it might not be possible in C++)
template Serial(char[] file, int line)
{
prgams(msg,
"template Serial(char[] file : \"~file~"\", int line : "~line.stringof~")"
"{const int Serial = __LINE__;");
const int Serial = -1;
}
A simpler solution would be to keep a global static "error location" variable.
#ifdef DEBUG
#define trace_here(version) printf("[%d]%s:%d {%d}\n", version, __FILE__, __LINE__, errloc++);
#else
#define trace_here(version) printf("{%lu}\n", version<<16|errloc++);
#endif
Or without the printf.. Just increment the errloc everytime you cross a tracepoint. Then you can correlate the value to the line/number/version spit out by your debug builds pretty easily.
You'd need to include version or build number, because those error locations could change with any build.
Doesn't work well if you can't reproduce the code paths.
__FILE__ is a pointer into the constants segment of your program. If you output the difference between that and some other constant you should get a result that's independent of any relocation, etc:
extern const char g_DebugAnchor;
#define FILE_STR_OFFSET (__FILE__ - &g_DebugAnchor)
You can then report that, or combine it in some way with the line number, etc. The middle bits of FILE_STR_OFFSET are likely the most interesting.
Well, if you're displaying the message to the user yourself (as opposed to having a crash address or function be displayed by the system), there's nothing to keep you from displaying exactly what you want.
For example:
typedef union ErrorCode {
struct {
unsigned int file: 15;
unsigned int line: 12; /* Better than 5 bits, still not great
Thanks commenters!! */
unsigned int build: 5;
} bits;
unsigned int code;
} ErrorCode;
unsigned int buildErrorCodes(const char *file, int line, int build)
{
ErrorCode code;
code.bits.line=line & ((1<<12) - 1);
code.bits.build=build & ((1<< 5) - 1);
code.bits.file=some_hash_function(file) & ((1<<15) - 1);
return code.code;
}
You'd use that as
buildErrorCodes(__FILE__, __LINE__, BUILD_CODE)
and output it in hex. It wouldn't be very hard to decode...
(Edited -- the commenters are correct, I must have been nuts to specify 5 bits for the line number. Modulo 4096, however, lines with error messages aren't likely to collide. 5 bits for build is still fine - modulo 32 means that only 32 builds can be outstanding AND have the error still happen at the same line.)

Resources