macro expansion using flag variables at runtime - c

if (a==5)
{
#define FLAG 1
}
#ifdef FLAG
{
// Execute this portion else not
}
#endif
I want to use this as flag variable and if the variable is defined(at runtime depending upon condition) then the piece if code in #ifdef shall be executed else not.
If this is not possible in c programming then please suggest me the best way to implement the same.
Which can help in faster execution of code. Also reduced compilation time

1) FLAG is not variable, it is a preprocessor symbol.
2) The preprocessor is running from top to bottom defining the symbols (or undefining them) regardless of your compilable code logic (so of course it can't depend on it), before it is even compiled. So in your example the #ifdef will always work.
3) To achieve the functionality you seem to want, just use a regular if/else statements.

bool flag = false;
if (a == 5)
{
flag = true;
}
if (flag)
{
// [...]
}

Related

new preprocessor trick to me

(Below code is correct, not create by myself.)
(it is inside the config of a motor board.)
#define BTN_TABLE(X) X(BUTTON, PA1)
#define BTN_X_EXTERNS(A, B) extern Button A;
BTN_TABLE(BTN_X_EXTERNS)
#define BTN_X_ID(A, B) A##_ID
#define BTN_X_ENUM(A, B) BTN_X_ID(A, B),
typedef enum { BTN_TABLE(BTN_X_ENUM) NUM_BOARD_BUTTONS } BoardButtonID;
#define BTN_X_FROM_ENUM(A, B) else if (button_id == BTN_X_ID(A, B)) return &A;
static __forceinline Button* button_from_enum(BoardButtonID button_id) {
if (0) return 0;
BTN_TABLE(BTN_X_FROM_ENUM)
else return 0;
}
I don't get the meaning of if (0) return 0; and else return 0; in above example.
why place the Marco in between these two line?
I think we cannot place anything between if{} , else{} statement.
I think the intent behind this code was as follows:
We have some buttons; currently just one, but eventually there may be many more
Each button needs a corresponding global variable and a value in the BoardButtonID enum
We want a function which given the enum BoardButtonID value returns a pointer to the button's global variable
We want to achieve all this while only listing all buttons once.
#bolov has shown how the code expands. I'll note that one can add more buttons just by changing the definition of the BTN_TABLE macro:
#define BTN_TABLE(X) X(BUTTON, PA1) \
X(ANOTHER_BUTTON, PA2) \
X(YET_ANOTHER_BUTTON, PA3) \
X(OH_GOD_NOT_ANOTHER_BUTTON_MAKE_THEM_STOP, PA4)
The PA1, PA2, ... aren't actually used in this version of the code; maybe they would have been used for something later.
Now you can see the effect (I've reformatted the output):
extern Button BUTTON;
extern Button ANOTHER_BUTTON;
extern Button YET_ANOTHER_BUTTON;
extern Button OH_GOD_NOT_ANOTHER_BUTTON_MAKE_THEM_STOP;
typedef enum {
BUTTON_ID,
ANOTHER_BUTTON_ID,
YET_ANOTHER_BUTTON_ID,
OH_GOD_NOT_ANOTHER_BUTTON_MAKE_THEM_STOP_ID,
NUM_BOARD_BUTTONS
} BoardButtonID;
static __forceinline Button* button_from_enum(BoardButtonID button_id) {
if (0)
return 0;
else if (button_id == BUTTON_ID)
return &BUTTON;
else if (button_id == ANOTHER_BUTTON_ID)
return &ANOTHER_BUTTON;
else if (button_id == YET_ANOTHER_BUTTON_ID)
return &YET_ANOTHER_BUTTON;
else if (button_id == OH_GOD_NOT_ANOTHER_BUTTON_MAKE_THEM_STOP_ID)
return &OH_GOD_NOT_ANOTHER_BUTTON_MAKE_THEM_STOP;
else
return 0;
}
And this makes it clear why the initial if is needed: the macro expansion in button_from_enum has no way to treat the first one specially. So it has to produce an else if for every button, including the first one, and the only way to make that valid is for there to be an if at the beginning. It needs to have a test that always fails, hence 0, and its corresponding "then" clause doesn't matter as it will never execute. The return 0 there may have just been chosen to shut up a compiler warning about the function possibly returning without a value. Of course, the return 0 in the final else clause can be reached, and serves as a default if someone passes a value that doesn't match any button.
You are right that if you put anything else in between the if and else, everything will break.
They could have defined it a little differently and used switch instead, which would have been slightly cleaner. I don't know why they didn't; maybe the compiler generates different code that they didn't like (e.g. a jump table that occupies more code space).
In any event, the resulting set of macros, while clever, are certainly not very easy to maintain. They should probably have considered writing a script instead that would generate the desired code from a simple list of buttons in a text file.
Or, they could have put the Button objects in an array instead of insisting on each one having its own variable. This would go nicely with their enum:
typedef enum {
BUTTON_ID,
ANOTHER_BUTTON_ID,
YET_ANOTHER_BUTTON_ID,
OH_GOD_NOT_ANOTHER_BUTTON_MAKE_THEM_STOP_ID,
NUM_BOARD_BUTTONS
} BoardButtonID;
Button all_the_buttons[NUM_BOARD_BUTTONS];
static __forceinline Button* button_from_enum(BoardButtonID button_id) {
if (button_id < NUM_BOARD_BUTTONS)
return &all_the_buttons[button_id];
else
return NULL;
}
This way still only requires listing the buttons once, and it involves no macros at all.
This is one of the most unreadable pieces of code I have seen.
I personally don't have neither the time, energy or willingness to analyze and figure out these horible macros. So I just dumped the preprocessor output and this is the code presented to the compiler:
extern Button BUTTON;
typedef enum { BUTTON_ID, NUM_BOARD_BUTTONS } BoardButtonID;
static __forceinline Button* button_from_enum(BoardButtonID button_id) {
if (0) return 0;
else if (button_id == BUTTON_ID) return &BUTTON;
else return 0;
}
it is inside the config of a motor board.
That explains the code. It is consistent with code that is generated by other software, rather than by a human. It is generated by some code that configures a software package to some target environment.
The purpose of code like this:
if (0) return 0;
BTN_TABLE(BTN_X_FROM_ENUM)
else return 0;
is to allow the generating code to put any number of else if lines between the if line and the else line. For example, in various circumstances, the generated code might be this:
if (0) return 0;
else return 0;
or this:
if (0) return 0;
BTN_TABLE(BTN_X_FROM_ENUM)
else return 0;
or this:
if (0) return 0;
BTN_TABLE(BTN_X_FROM_ENUM)
BTN_TABLE(BTN_Y_FROM_ENUM)
else return 0;
By using if (0) and else as bookends, the generating code is freed from having to have conditional cases such as “If there are zero conditions, just write return 0;. If there is one condition, write if (condition) return something; else return 0;. If there are multiple conditions, write if (first condition) return something; else if (second condition) return something;… else return 0;.
Instead, the generating code is simply:
Write if (0) return 0;.
For each condition, write an else if line for it (likely in the form of some BTN_TABLE macro use, the definition for which is emitted elsewhere in the generating code).
Write else return 0;.
Thus, while the resulting code is more complicated, the actual generating code is simpler.
I don't get the meaning of if (0) return 0; and else return 0; in above example.
The if (0) is needed simply so that the following lines can be any number of else if statements. The return 0; is never executed and is simply needed to complete the if statement grammatically.
The else return 0; statement provides a default in case none of the conditions are met.
why place the Marco in between these two line?
The generating code emits a macro invocation for every case it determines is needed in the target system.
I think we cannot place anything between if{} , else{} statement.
Of course you can, the else if statements are proper there.

How to solve warning problems?

I am trying to resolve warning issues which is shown as below :
warning: suggest braces around empty body in an 'if' statement
Relevant code:
cdc(.....)
{
//some statements
ENTER_FUNC(CDC_TRKEY_FC,cdcType_t); //Showing warning in this line
if(something)
{
if(..)
{
}
else
{
}
}
else
{
}
}
If I remove ; and adding the braces as below
ENTER_FUNC(CDC_TRKEY_FC,cdcType_t)
{
}
the warning is gone.
What does exactly it means? Is it behaving like an if statement?
Sorry, its confidential code, so I cant share entirely.
If this is your code
if (/* condition */);
/* other code */
Then the other code will ALWAYS be executed.
You probably want the other code to only be executed if the condition is true.
In order to achieve that, you mainly have to delete the ;.
It is widely considered to be best practice to be somewhat generous with the {}, i.e.
if (/* condition */)
{
/* other code */
}
The fact that the warning does not occur after deleting the ; in line
ENTER_FUNC(CDC_TRKEY_FC,cdcType_t); and replacing it with {}
can be explained if it is actually a macro which essentially expands (together with the ; which is NOT part of the macro) to the if();, which earlier versions of your question were mentioning.
The replacement with {} then does exactly what the compiler wanted.
The ENTER_FUNC() is probably meant to be used like
ENTER_FUNC(CDC_TRKEY_FC,cdcType_t) /* delete this ; */
{ /* new {, followed by rest of your function code */
if(something)
{
if(..)
{
}
else
{
}
}
else
{
}
} /* new */
Please excuse that this answer more or less assumes that you made a mistake in your code. Compare the contribution by Scheff, which assumes (also plausibly) that actually you were acting to a more complex design and fully intentionally.
The statement
if (cond) ; else do_something();
or even
if (cond) ; do_something();
might be intended. May be, the ; after if (cond) is a placeholder for something which shall be added later.
Inserting comments
if (cond) /** #todo */ ; else do_something();
or
if (cond) /** #todo */ ; /* and then always */ do_something();
would make it clear to the human reader but not for the compiler which ignores comments completely.
However, the compiler authors suspected high chance that the semicolon was unintendedly set (and can easily be overlooked). Hence, they spent a warning about this and gave a hint how to make the intention clear if there is one:
Use { } instead ; for intendedly empty then-body to come around this warning.
Sample:
#include <stdio.h>
int main()
{
int cond = 1;
if (cond) /** #todo */ ; else printf("cond not met.\n");
if (cond) /** #todo */ ; printf("cond checked.\n");
return 0;
}
Output:
cond checked.
Life demo on ideone
The compiler used on ideone is stated as gcc 6.3.
I must admit that I didn't get the diagnostics of OP.
After the question was edited, the answer does not seem to match the question anymore. Hence, a little update:
The OP states that the
warning: suggest braces around empty body in an 'if' statement
appears for this line of code:
ENTER_FUNC(CDC_TRKEY_FC,cdcType_t); //Showing warning in this line
It seems that the OP was not aware that ENTER_FUNC is (very likely) a macro with an if statement in its replacement text (something like #define ENTER_FUNC(A,B) if (...)). (This is the most imaginable scenario to get this warning for this code.)
Unfortunately, the OP is not willing to show how ENTER_FUNC is defined, nor to prepare an MCVE with the same behavior.
However, the technique to hide an if in a macro is even more questionable – I wouldn't recommend to do so. Imagine the following situation:
cdc(.....)
{
//some statements
ENTER_FUNC(CDC_TRKEY_FC,cdcType_t) // This time, the author forgot the ; or {}
if(something)
{
if(..)
{
}
else
{
}
}
else
{
}
}
The if(something) statement becomes now the body of the hidden if of the ENTER_FUNC() macro which is probably not intended but a bug. The application may now behave wrong in certain situations. By simply looking at the source code, this is probably hard to catch. Only, by single-step debugging and a bit luck, the error can be found.
(Another option would be to expand all macros and check the C code after replacement. C compilers provide usually a pre-process-only option which makes the result of pre-processing visible to human eyes. E.g. gcc -E)
So, the author of ENTER_FUNC built a macro which
causes a compiler warning if macro is used properly
where the warning goes away if macros is used wrong.
IMHO, this is a not-so-lucky design.

Array of macros in c -- is it possible

I was wondering if it is possible to create something like an array of macros.
I've implemented the following code which works:
struct led_cmds_
{
ioport_pin_t *commands[LED_COUNT] ;
};
struct led_cmds_ the_led_cmd_ ;
void populate() {
the_led_cmd_.commands[0] = SPECIFICPIN(0);
}
and in main:
int main(void)
{
//.....
populate();
LED_On(the_led_cmd_.commands[0]);
}
SPECIFICPIN(x) is macro defined as:
#define SPECIFICPIN(X) (LED##X##_PIN)
What I was hoping for is a way to is a way to do something like this:
#define ioport_pin_t* ARR_LED[LED_COUNT] \
for (int j = 0; j < LED_COUNT; j++) ARR_LED[j] = SPECIFICPIN(j);
and then only need to call the following when I want to use the specific pin
LED_On(ARR_LED[some_number])
when I try to do that I get an ARR_LED undeclared (first use in this function) error.
When I try to call SPECIFICPIN(x) where x is an int iterator in a for loop for example, I get an error saying something like 'LEDx_PIN' undeclared...
You need to work on your terminology. An array of macros is not possible. Macros are no data type, but rather pure text replacement before your program is actually compiled.
I guess " populate an array using macros " is what you want to do. But it is not possible to do that in a compile-time loop - What you seem to want to achieve with your ioport_pin_t macro attempt. Macros do not have the capability to expand to more instances of text elements than you have initially given. There is no such feature as looping at compile time through macro expansions and do repetitive expansion of macros.
Your for loop loops at run-time, while the macro is being expanded at compile-time. Once you have made yourself aware what is done by the preprocessor what is done by the compiler, and what is done at run-time by the finished program, you will see that will not work.
Something like
#define P(X) {(LED##X##_PIN)}
ioport_pin_t *commands[LED_COUNT] = {
P(0), P(1), P(2),......}
#undefine P
Would be the closest thing possible to what you seem to want. Note the main use of the pre-processor is not to save you typing effort - You would be better off using copy & paste in your editor, achieve the same thing and have clearer code.
An array as tofro's answer is the way to go. However in cases that couldn't be solved simply with an array then there's another way with switch
#define SPECIFICPIN(X) (LED##X##_PIN)
void setpin(int pin, int value)
{
switch (pin)
{
case 1:
SPECIFICPIN(1) = value;
doSomething(); // if needed
break;
case x: ...
default: ...
}
}

calculating FLASH utilisation by C code

I want to optimize/reduce memory usage of my software. One of the approaches that I'm looking at is to look for removing redundant and unnecessary code.
In my software there are lot of features (up to 3000) which can be activated/deactivated via a Feature Enable mechanism. What I am trying to do is to find how much RAM/FLASH a feature utilizes and then start evaluating with the biggest ones and see if they are required or not (Features not required can be safely deleted from the code). Also please note a function may have more than one feature within itself.
Our code would look something like this:
void foo (void)
{
if(TRUE == feature1_enable)
{
doSomething;
}
if(TRUE == feature2_enable)
{
doSomething;
}
//rest of the code
}
How can I calculate how much FLASH the code inside if statements is using? I cannot use final link map file as it provides data only about the function but not individual statements inside them. One solution that I have thought is to create an assembly listing file (.alst) out of the C code and then calculate the size of the instructions within the if statements which is nothing but the amount of FLASH utilized by these lines of code.
Kindly let me know if I am on the right track or if there is a better/easier way to do this?
I am using:
Processor: MPC5554 (POWER PC architecture)
Compiler: WindRiver Diab
If the logic is correct I would eventually write a script to search the enables and do the required calculations.
The only solution that comes to my mind that works with optimizations:
void foo (void)
{
#if 0 // disable feature 1 for size test
if(TRUE == feature1_enable)
{
doSomething;
}
#endf // feature 1
if(TRUE == feature2_enable)
{
doSomething;
}
//rest of the code
}
If you need to automate:
void foo (void)
{
#ifndef DISABLE_FEATURE_1_AT_COMPILE_TIME // disable feature 1 for size test
if(TRUE == feature1_enable)
{
doSomething;
}
#endf // feature 1
#ifndef DISABLE_FEATURE_2_AT_COMPILE_TIME // disable feature 2 for size test
if(TRUE == feature2_enable)
{
doSomething;
}
#endif // feature 2
//rest of the code
}
Then you can automate in your build script for every feature you have and measure the size of the feature alone. The most work you will have is adding all the defines now.

Evaluate macro parameter once only

In the following code, whatever is passed as retval is evaluated as given for every use of that token.
#define _CPFS_RETURN(commit, retval) do { \
util_cpfs_exit(commit); \
return retval; \
} while (false)
#define CPFS_RETURN_BOOL(retval) do { \
_CPFS_RETURN(retval, retval); \
} while (false)
For example given the use CPFS_RETURN_BOOL(inode && file_truncate(inode, len));, this is generated:
do {
do {
util_cpfs_exit(inode && file_truncate(inode, len));
return inode && file_truncate(inode, len);
} while (0);
} while (0);
Evidently I don't want to execute the statement inode && file_truncate(inode, len); more than once.
How can I ensure that the given tokens are evaluated before being pasted helter-skelter?
Update
I believe I have good reason to use macros here. Where possible, code is put into real functions (such as util_cpfs_exit) which are invoked from a set of macros I'm using. The macros vary based on the return type: in C++ I'd have explicit templates to handle this.
As your macro vary on the return type, you can evaluate the retval expression and store it in a variable of the right type inside the first level of macro then use this variable. ie:
#define CPFS_RETURN_BOOL(retval) do { \
bool _tmp_ = retval;
_CPFS_RETURN(_tmp_, _tmp_); \
} while (false);
If I understand well, that should be enough for your use case, and for other use cases you can use functions.
In your exemple you'll get:
do {
bool _tmp_ = inode && file_truncate(inode, len);
do {
util_cpfs_exit(_tmp_);
return _tmp_;
} while (0);
} while (0);
Looks fine.
PS: as a sidenote if you always use _CPFS_RETURN indirectly through another macro following the above model, there is no need to protect it by a do { } while (false);. Also, putting a semi-colon after the while(false) removes most of the interest of using it... that may be a good example of why C macros are dangerous and hides easy pitfalls. Not that I dislike macros, quite the contrary. I'm from the (probably rare) kind of people that would prefer C macros to be enhanced to bypass their current limitations to become really cool (and no, C++ templates are not enhanced macros, they are something completely different).
I would recommend that you evaluate the condition first.
i.e.
bool val = inode && file_truncate(inode, len);
Other than that may advice would be to steer well clear of macros, they seem unnecessary in this instance, use functions instead.
Write a function instead of using a macro. In this case, where you want to build a return statement in, you might be better off just writing the code explicitly instead of relying on a macro to hide what you're doing.
Change the macro to a "static inline" function. In gcc, it's as fast as a macro.
http://gcc.gnu.org/onlinedocs/gcc/Inline.html

Resources