C++ Macro expanding in ordinal numbers - c++

I have a code that compiles on various platforms having different features on or off (each represented by a specific define) and I am scratching my head on how to do the following switch (int) statement that would keep "case (number):" ordered and continuous.
int funcParam;
switch(funcParam)
{
case 0: break;
case 1:break;
#ifdef FEATURE_1
case 2: break;
#endif // FEATURE_1
case 3: break; // <<== problem here: 3 follows 1 if FEATURE_1 is not defined
#ifdef FEATURE_2
case 4: break; <<== problem here: 4 follows 2 if FEATURE_1 is not defined
#endif // FEATURE_2
#ifdef FEATURE_3
case 5: break; <<== problem here: 5 follows 2 or 3 or 4 depending on features
#endif // FEATURE_3
}
Each case block of code is a block of 10 or so lines, I guess this is irrelevant, however the perfect solution to have would be to find a way to emit code like:
case NEXTNUM:
that would expand to a next ordinal number with each expansion of a macro NEXTNUM.
Not having an idea on how could it possibly be written.
Please keep in mind that I am using quite old compiler (C++98, may consider C++03).
EDIT:
Found eventually a very similar question here:
Auto-incrementing macro expansion
which boils down to a very simple solution that is using enums instead of just plain numbers.
Thanks, Radek

Create variables equal 0 and 1 depending on if the feature is enabled. Add these variables to cases after the feature case.
int main() {
int funcParam;
const int add_feature_1 =
#ifdef FEATURE_1
1
#else
0
#endif
;
const int add_feature_2 =
#ifdef FEATURE_2
1
#else
0
#endif
;
const int add_feature_3 =
#ifdef FEATURE_3
1
#else
0
#endif
;
switch(funcParam) {
case 0: break;
case 1: break;
#ifdef FEATURE_1
case 2: break;
#endif
case 2 + add_feature_1: break;
#ifdef FEATURE_2
case 3 + add_feature_1: break;
#endif // FEATURE_2
#ifdef FEATURE_3
case 3 + add_feature_1 + add_feature_2: break;
#endif // FEATURE_3
}
}
Consider refactoring your code, so that FEATURE_X has to be defined (which I consider better) and instead define FEATURE_X to number 0 or 1. Then you could:
#define FEATURE_1 0
#define FEATURE_2 1
#define FEATURE_3 0
int main() {
int funcParam;
switch(funcParam) {
case 0: break;
case 1: break;
#if FEATURE_1
case 2: break;
#endif
case 2 + FEATURE_1: break;
#if FEATURE_2
case 3 + FEATURE_1: break;
#endif // FEATURE_2
#if FEATURE_3
case 3 + FEATURE_1 + FEATURE_2: break;
#endif // FEATURE_3
}
}
Or similar combinations, you should get the idea.

instead of case 0, case 1… and so on, use values from an enum; these are also compile-time constants, and thus, legal as case values.
You can insert the same #ifdef feature checks into the enum definition, then the enum options are still continuously labeled.
Rule of thumb though:
you're not making anything prettier that way. Honestly, having a feature enabled or not should probably not change the values functions exchange – that's just ugly and a recipe for debugging disaster. So, I question your motivation!
a case costs nearly nothing. Instead or removing these cases, you should probably think about what the right operation is when that case is triggered. A warning? A system shutdown?
The fact that you're not using an enum in switch/case is a really um, bad sign, and you relying on cases still being contiguously numbered is actively worrying. Using magic numerical constants is bad enough style on its own – making them have different meanings on different feature sets screams "architectural mistakes have been made". I'd duly replace all my magic numeric values with entries from an enum. You will be happier afterwards.
Lastly: uff. C++98. C++03 is 20 years old. It's an important bug-fix release that basically broke nothing. You really should not hesitate a second to use it.

Related

Member function [c++] definition not found by VS2015 due to #define

Have a #define which is called within a member function. By this #define the member-function definition isn't found by the VS2015 environment at the declaration level. The project compiles and runs just fine so no problem there.
This does however, break the functionality of VS2015 to jump between the declaration and definition.
It can be solved by writing the #define within the source, but can this be solved without removing the #define?
File: cFoo.h
class cFoo
{
public:
int Bits;
void Member();
}
File: cFoo.cpp
#include "cFoo.h"
#define SWITCH( x ) for ( int bit = 1; x >= bit; bit *= 2) if (x & bit) switch (bit)
void cFoo::Member()
{
SWITCH( Bits )
{
case 1: break;
case 2: break;
default: break;
}
}
I would disadvice to use such constructs. It is rather counterintuitive and difficult to understand.
Possible problems/difficulties:
switch case with breaks suggests that only one case is executed, but your macro logic hides the loop.
the default case is executed multiple times depending on the highest populated bit.
using signed int as bit set -> use unsigned - its less prone to implementation defined behavior
it is possibly slow because of loop (I do not know if the compiler is able to unroll and optimize it)
its called SWITCH_BITS which suggests that bit numbers are expected, but cases have to be powers of two.
Your whole statement is not more compact than a simple if sequence.
if(bits & 1 ){
}
if(bits & 1024){
}
but you maybe want to test to bit numbers:
inline bool isBitSet(u32 i_bitset, u32 i_bit){ return i_bitset & (1 << i_bit);}
if(isBitSet(bits, 0){
}
if(isBitSet(bits, 10){
}
You can try doing this by completing the switch statement within the #define - macro:
Foo.h
#ifndef FOO_H
#define FOO_H
#ifndef SWITCH
#define SWITCH(x) \
do { \
for ( int bit = 1; (x) >= bit; bit *=2 ) { \
if ( (x) & bit ) { \
switch( bit ) { \
case 0: break; \
case 1: break; \
default: break; \
} \
} \
} \
} while(0)
#endif
class Foo {
public:
int Bits;
void Member();
};
#endif // !FOO_H
Foo.cpp
#include "Foo.h"
void Foo::Member() {
SWITCH( this->Bits );
}
When I was trying the #define or macro as you had it, Foo::Member()
was not being defined by intellisense...
However even with it not being defined I was able to build, compile and run it like this:
#ifndef SWITCH_A
#define SWITCH_A(x) \
for ( int bit = 1; (x) >= bit; bit *= 2 ) \
if ( (x) & bit ) \
switch (bit)
#endif
For some reason; MS Visual Studio was being very picky with it; meaning that I was having a hard time getting it to compile; it was even complaining about the "spacing" giving me compiler errors of missing { or ; need before... etc. Once I got all the spacing down properly it did eventually compile & run, but intellisense was not able to see that Foo::Member() was defined. When I tried it in the original manner that I've shown above; intellisense had no problem seeing that Foo::Member() was defined. Don't know if it's a pre-compiler bug, MS Visual Studio bug etc.; Just hope that this helps you.

How to get a boolean indicating if a macro is defined or not?

My code is configurable with define macros. To get the value in the code, I'm doing this:
#ifdef CONFIG_X
static constexpr bool x = true;
#else
static constexpr bool x = false;
#endif
But this is quickly becoming very ugly in the code with several configuration variables...
Another solution I found is simply to cut the code in two:
#ifdef CONFIG_X
#define CONFIG_X_BOOL true
#else
#define CONFIG_X_BOOL false
#endif
static constexpr bool x = CONFIG_X_BOOL;
This is a bit better, but not really nice either.
Is there a nice way to have a boolean or a 1 or 0 if a macro is defined ?
This IS possible, but only in the limited case where you are looking for empty defines (as is often the case with compilation flags) or where you know the range of ways a flag will be defined, such as with a 0 or 1.
Here is working code:
#include <iostream>
// Define two genetic macros
#define SECOND_ARG(A,B,...) B
#define CONCAT2(A,B) A ## B
// If a macro is detected, add an arg, so the second one will be 1.
#define DETECT_EXIST_TRUE ~,1
// DETECT_EXIST merely concats a converted macro to the end of DETECT_EXIST_TRUE.
// If empty, DETECT_EXIST_TRUE converts fine. If not 0 remains second argument.
#define DETECT_EXIST(X) DETECT_EXIST_IMPL(CONCAT2(DETECT_EXIST_TRUE,X), 0, ~)
#define DETECT_EXIST_IMPL(...) SECOND_ARG(__VA_ARGS__)
// We will create MY_DEFINE, but not MY_DEFINE2
#define MY_DEFINE
int main()
{
// We can now use DETECT_EXIST to detect defines.
std::cout << "MY_DEFINE = " << DETECT_EXIST(MY_DEFINE) << std::endl;
std::cout << "MY_DEFINE2 = " << DETECT_EXIST(MY_DEFINE2) << std::endl;
}
This code will produce the output:
MY_DEFINE = 1
MY_DEFINE2 = 0
Since the first one does exist and the second doesn't.
If the macro is set to a value such as 1, you just need to have an alternate version of DETECT_EXIST_TRUE to handle it, with the macro value pasted on the end. For example:
#define DETECT_EXIST_TRUE1 ~,1
Then if you have:
#define MY_DEFINE1 1
Code like this will also work correctly in main:
std::cout << "MY_DEFINE1 = " << DETECT_EXIST(MY_DEFINE1) << std::endl;
#ifndef CONFIG_X
#error "Written for config x"
#endif
// True for config x, hack this about for other configurations
static bool x = 1;
Now it breaks if config is not x. Generally that's better than trying to second-guess what an unnamed configuration which is not X will require.

Why does the C preprocessor consider enum values as equal?

Why does the std::cout line in the following code run even though A and B are different?
#include <iostream>
enum T { A = 1, B = 2 };
// #define A 1
// #define B 2
int main() {
#if (A == B)
std::cout << A << B;
#endif
}
If I use #define instead (as commented out), I get no output as I expect.
Reason for the question:
I want to have a mode selector for some test code in which I can easily change modes by commenting/uncommenting lines on top:
enum T { MODE_RGB = 1, MODE_GREY = 2, MODE_CMYK = 3 };
// #define MODE MODE_RGB
#define MODE MODE_GREY
// #define MODE MODE_CMYK
int main() {
#if (MODE == MODE_RGB)
// do RGB stuff
#elif (MODE == MODE_GREY)
// do greyscale stuff
#else
// do CMYK stuff
#endif
// some common code
some_function(arg1, arg2,
#if (MODE == MODE_RGB)
// RGB calculation for arg3,
#elif (MODE == MODE_GREY)
// greyscale calculation for arg3,
#else
// CMYK calculation for arg3,
#endif
arg4, arg5);
}
I know I can use numeric values e.g.
#define MODE 1 // RGB
...
#if (MODE == 1) // RGB
but it makes the code less readable.
Is there an elegant solution for this?
There are no macros called A or B, so on your #if line, A and B get replaced by 0, so you actually have:
enum T { A = 1, B = 2 };
int main() {
#if (0 == 0)
std::cout << A << B;
#endif
}
The preprocessor runs before the compiler knows anything about your enum. The preprocessor only knows about macros (#define).
This is because the preprocessor works before compile time.
As the enum definitions occur at compile time, A and B will both be defined as empty (pp-number 0) - and thus equal - at pre-processing time, and thus the output statement is included in the compiled code.
When you use #define they are defined differently at pre-processing time and thus the statement evaluates to false.
In relation to your comment about what you want to do, you don't need to use pre-processor #if to do this. You can just use the standard if as both MODE and MODE_GREY (or MODE_RGB or MODE_CMYK) are all still defined:
#include <iostream>
enum T { MODE_RGB = 1, MODE_GREY = 2, MODE_CMYK = 3 };
#define MODE MODE_GREY
int main()
{
if( MODE == MODE_GREY )
std::cout << "Grey mode" << std::endl;
else if( MODE == MODE_RGB )
std::cout << "RGB mode" << std::endl;
else if( MODE == MODE_CMYK )
std::cout << "CMYK mode" << std::endl;
return 0;
}
The other option using only the pre-processor is to do this as #TripeHound correctly answered below.
Identifiers that are not defined macros are interpreted as value 0 in conditional preprocessor directives. Therefore, since you hadn't defined macros A and B, they are both considered 0 and two 0 are equal to each other.
The reason why undefined (to the pre-processor) identifiers are considered 0 is because it allows using undefined macros in the conditional without using #ifdef.
As the other answers said, the C preprocessor doesn't see enums. It expects, and can only understand, macros.
Per the C99 standard, §6.10.1 (Conditional inclusion):
After all replacements due to macro expansion and the defined unary operator have been performed, all remaining identifiers are replaced with the pp-number 0
In other words, in an #if or #elif directive, any macros that cannot be expanded, because they don't exist/are undefined, will behave exactly as if they'd been defined as 0, and therefore will always be equal to each other.
You can catch likely unintended behavior like this in GCC/clang with the warning option -Wundef (you'll probably want to make it fatal with -Werror=undef).
The preprocessor runs before the compiler, which means that the preprocessor doesn't know anything about symbols defined by the compiler and therefore it can't act depending on them.
Other answers explain why what you're trying doesn't work; for an alternative, I'd probably go with:
#define RGB 1
#define GREY 2
#define CMYK 3
#define MODE RGB
#if MODE == RGB
//RGB-mode code
#elif MODE == GREY
//Greyscale code
#elif MODE == CMYK
//CMYK code
#else
# error Undefined MODE
#endif
You might want prefixes on the RGB/GREY/CMYK if there's a danger of clashes with "real" source code.
The posts have explained why, but a possible solution for you that keeps readability might be like this
#define MODE_RGB
int main()
{
#ifdef MODE_RGB
std::cout << "RGB mode" << std::endl;
#elif defined MODE_GREY
std::cout << "Grey mode" << std::endl;
#elif defined MODE_CMYK
std::cout << "CMYK mode" << std::endl;
#endif
}
You just then need to change the macro at the top, to only the macro you are interested in is defined. You could also include a check to make sure that one and only one is defined and if not then and do #error "You must define MODE_RGB, MODE_GREY or MODE_CMYK

C MACRO to trace the "for" loop iteration in the existing source code

I require a c/c++ MACRO to trace the "for" loop iterations in the existing source code and to print some message if loop is running more that 50 iterations.
NOTE: the macro should not change the existing functionality of code.
I tried some logic C/C++: "for" macro to track loops which are running many iterations but it is not working in all cases!
int main()
{
int i,j,x,y;
j=100;
y=200;
//case 1
for(i=0;i<j;i++)
for(x=0;x<y;x)
x++;
//case 2
if(i>0)
for(;i>0;)
i--;
//case 3
for(;;)
{
i++;
}
return 0;
}
Here is a proof of concept that passes all three cases:
// Max lines in a file you are profiling
#define MAX_LINES 65535
// Array to count all iterations, initialized to zero
uint32_t iterations[MAX_LINES];
// Increments the iteration for the given line, returns non-zero
#define ITER(ln) ++iterations[ln]
// Override for definition
#define for(...) for(__VA_ARGS__) if (!ITER(__LINE__)) { } else
The limitation here is that you can only have one for per line, otherwise it will combine their iterations. So, this is okay:
for(i=0;i<j;i++)
for(x=0;x<y;x)
x++;
but this isn't:
for(i=0;i<j;i++) for(x=0;x<y;x) x++;
The other limitation is that we define an array for every line. You can easily make it a hashmap or something, but that isn't relevant for this example. With a hashmap, you can use the __LINE__ and #x (string representation of the loop) to construct the ID, so the first limitation mostly goes away as well.

flash an LED 1 to 3 short times in an intervall with arduino/c++

I want to let an LED flash some times in an intervall, a lot like the good old BIOS-BEEPS, to give me visual feedback of the program-state and I already got my code working for 3 short flashes, but for every additional flash I have to add code manualy.
I think, there must be a better way, but I cant figure it out, because the functions must not using delays or looping while blinking and therefor stopping the rest of the programm...
Because I want to get better at programming, I want you to ask, what has the function to look like to be working without adding code every time?
Here is my code for 1 to 3 flashes, I cleaned it a bit up for you:
flag++ // gets incremented every 100ms by interrupt no matter what...
// function to flash an LED
// each flash should be 200ms long (2 increments of 'flag')
// 200ms LED on, 200ms LED off
// given is the number of flashes and the duration till it begins
// to flash again.
void blink(int how_many_times, int duration) {
if (how_many_times >= 1) { // blink once
switch (flag) {
case 2: // 200ms
LED_ON;
break;
case 4:
LED_OFF;
break;
}
}
if (how_many_times >= 2) { // blink twice
switch (flag) {
case 6:
LED_ON;
break;
case 8:
LED_OFF;
break;
}
}
if (how_many_times >= 3) { // blink 3 times
switch (flag) {
case 10:
LED_ON;
break;
case 12:
LED_OFF;
break;
}
}
if(flag >= duration*10) { // *10 because duration is in 'seconds'
flag=0;
}
}
// to let it blink 3 times fast every 5 seconds:
blink(3, 5);
Since you would like to get better at programming, I would recommend starting by being more descriptive with your variables. For example, flag doesn't really describe what that variable is doing. It really resembles a timer, so why not call it timer_100ms? Then you know exactly what that variable is for.
I would also recommend using an enumeration for case statements so that what you are trying to accomplish is a little more clear. For example:
/* This timer is incremented every 100ms by the interrupt. */
int timer_100ms;
void blink (int how_many_times, int duration)
{
enum
{
ELAPSED_TIME_200MS = 2,
ELAPSED_TIME_400MS = 4,
/* Fill in other values */
ELAPSED_TIME_1200MS = 12
};
if (how_many_times >= 1)
{
switch (timer_100ms)
{
case ELAPSED_TIME_200MS:
LED_ON;
break;
case ELAPSED_TIME_400MS:
LED_OFF;
break;
}
}
/* The rest of your code follows... */
}
Doing this makes your code a lot more readable.
That being said, to make your code more scalable - with the ability to create more LED blinks without adding more code - I would recommend starting with something like the following:
void blink (int number_of_blinks, int delay_between_blinks_in_seconds)
{
#define ELAPSED_TIME_200MS 2
static int blink_count = 0;
static int timer_prev_100ms = 0;
/* If the delay has been satisfied, start blinking the LED. */
if (timer_100ms >= (delay_between_blinks_in_seconds * 10))
{
/* Change the state of the LED every 200ms. */
if ((timer_100ms - timer_prev_100ms) >= ELAPSED_TIME_200MS)
{
timer_prev_100ms = timer_100ms;
if (led_is_on())
{
LED_OFF;
blink_count++;
}
else
{
LED_ON;
}
}
if (blink_count >= number_of_blinks)
{
timer_100ms = 0;
timer_prev_100ms = 0;
blink_count = 0;
}
}
}
Obviously, you would need to add the led_is_on() function to check the state of the pin you are using to flash the LED. Since, I don't know how you have your LED wired, I didn't want to assume how that would be done. It is very simple to implement though.