C pre-processor define directive with multiple replacements - c

/*
* Recommended alloc parameters for "small" contexts that are never expected
* to contain much data (for example, a context to contain a query plan).
*/
#define ALLOCSET_SMALL_MINSIZE 0
#define ALLOCSET_SMALL_INITSIZE (1 * 1024)
#define ALLOCSET_SMALL_MAXSIZE (8 * 1024)
#define ALLOCSET_SMALL_SIZES \
ALLOCSET_SMALL_MINSIZE, ALLOCSET_SMALL_INITSIZE, ALLOCSET_SMALL_MAXSIZE
I don't understand last marco, I use
printf("%d", ALLOCSET_SMALL_SIZES);
then warning:
warning: too many arguments for format [-Wformat-extra-args]
and also return 0.
similar post I found: #define directive with multiple replacements?
Update: Jumped around source code, got it.
function like
foo(size_t,size_t,size_t)
can just use
foo(ALLOCSET_DEFAULT_SIZES)

Given the following snippet:
#define ALLOCSET_SMALL_SIZES \
ALLOCSET_SMALL_MINSIZE, ALLOCSET_SMALL_INITSIZE, ALLOCSET_SMALL_MAXSIZE
The macro ALLOCSET_SMALL_SIZES gets replaced with:
ALLOCSET_SMALL_MINSIZE, ALLOCSET_SMALL_INITSIZE, ALLOCSET_SMALL_MAXSIZE
which gets replaced with:
0,
(1 * 1024),
(8 * 1024)
which are separate arguments. Then in the call to printf ():
printf("%d", ALLOCSET_SMALL_SIZES);
ALLOCSET_SMALL_SIZES gets replaced with 0, (1 * 1024), (8 * 1024)
Or,
printf ("%d", 0, (1 * 1024), (8 * 1024));
Hence the warning.
Fix:
Replace it with:
printf ("%d %d %d", 0, (1 * 1024), (8 * 1024));
See: Why use Macros in C? and What are C macros useful for?

Related

Get the value of a macro using a string with macro name

I have a set of macro definitions that the name only change on the number between "C_" and "_E". What I need is a macro that gets a integer variable and returns the integer value of the corresponding macro definition in case it exists, if it does not exist, it returns "-1" or gives a compile error. Is that possible? The code I need is something like this:
#include <stdio.h>
#define C_1_E 4
#define C_2_E 2
#define C_3_E 0
#define C_4_E 420
#define STR(x) #x
#define STR_MACRO(x) "C_" STR(x) "_E"
#define MACRO_VAL(x) ... // return the value of the macro C_x_E when x=1,2,3 or 4
void main() {
uint8_t n;
for(n=1;n<=4;n++) printf("val %u: %u\n",n, MACRO_VAL(STR_MACRO(n)));
}
Expected output:
val 1: 4
val 2: 2
val 3: 0
val 4: 420
According to my search, this is not possible, but I can swear I did cross this solution once, but I didn't need it back then although I thought it could be helpful.
If you need to have a macro specifically, not a function, then it must be that a macro that expands to a function call is not acceptable either. That makes sense to me only if you need the conversion of macro number to macro expansion to be performed at compile time, by the preprocessor. That doesn't appear to be a necessity for the example code, but there are cases where it would indeed be needed.
And that's too bad, because the C preprocessor then provides no way to achieve what you ask. Variables do not exist or have values at compile time, so there is no way at compile time for the compiler to convert a variable name to the value it represents, much less to build a macro name out of it, much less to expand such a name to its replacement text.
You could, however, do it with numeric literals instead of a variable:
#define EXPAND(x) x
#define MACRO_VAL(n) EXPAND(C_ ## n ## _E)
printf("val %d: %d\n",n, 1, MACRO_VAL(1));
printf("val %d: %d\n",n, 2, MACRO_VAL(2));
printf("val %d: %d\n",n, 3, MACRO_VAL(3));
printf("val %d: %d\n",n, 4, MACRO_VAL(4));
If you try to expand that with an argument that does not produce the name of a defined macro or in-scope variable then that (almost surely) will produce a compile-time error for a reference to an undefined variable.
If run-time evaluation were acceptable after all, then you could write a function that does it (which you could wrap in a macro if you wanted):
#define MACRO_VAL(n) lookup_macro(n)
#define EXPAND(x) x
#define MACRO_CASE(i) case i: return EXPAND(C_ ## i ## _E)
int lookup_macro(int n) {
switch (n) {
MACRO_CASE(1);
MACRO_CASE(2);
MACRO_CASE(3);
MACRO_CASE(4);
default: return -1;
}
}
That will return -1 for an arithmetic argument that is not covered by the defined cases.
You could also consider a lookup table, possibly wrapped in a function, but that would require somewhat more code to provide a -1 result in the event of an argument that doesn't match any macro, especially if the macro numbers are not all consecutive or if the least of them is not known in advance.
Token pasting approaches are inappropriate as x is a variable name.
Here is a simplistic approach that will work as long as the macro argument is an expression without side effects:
#include <stdio.h>
#define C_1_E 4
#define C_2_E 2
#define C_3_E 0
#define C_4_E 420
// return the value of the macro C_x_E when x=1,2,3 or 4
#define MACRO_VAL(x) ((x) == 1 ? C_1_E : \
(x) == 2 ? C_2_E : \
(x) == 3 ? C_3_E : \
(x) == 4 ? C_4_E : -1)
int main() {
int n;
for (n = 1; n <= 4; n++)
printf("val %u: %u\n", n, MACRO_VAL(n));
return 0;
}

Dependency between defining constants in C? [duplicate]

This question already has answers here:
C Programming Macros multiplication [duplicate]
(2 answers)
Closed 4 years ago.
I used the #define command for following code and constants. I defined in the first WORKLOAD_MAX with 4 and second line TASK_COUNT_MAX with 10 and used multiplication of them in the third line.
after a long time debugging, I realized that the correct value does not apply while executing the code, and I have to manually set the value that I do not like it. (like 40 on the fourth commented line)
Someone can help.
Thank you
#define WORKLOAD_MAX 4
#define TASK_COUNT_MAX 10
#define READY_LOOP_DEEP TASK_COUNT_MAX*WORKLOAD_MAX
//#define READY_LOOP_DEEP 40
struct workItem // It is a STRUCT to keep the status of task in different stages
{
int task_ID; // Task ID
int workload_ID; // Workload ID
};
// Read from the beginning of the readyQueue
struct workItem readFromReadyQueue()
{
struct workItem witem;
// Picking up from queue head
witem = readyQueue[readyQueueHead];
// Move forward the queue head index in rotation
readyQueueHead = (readyQueueHead + 1) % READY_LOOP_DEEP;
// Reduce the number of queue elements
readyQueueSize--;
#ifdef PRINT_ReadReadyQueue
printf("Task_ID #%d (Workload_ID #%d) read from readyQueue.\n", witem.task_ID , witem.workload_ID);
#endif
return witem;
}
Macros are textual replacements the semantics of which are context dependent. In this case any occurrence of READY_LOOP_DEEP will be replaced with 4*10 which in context may not behave as you might expect due to operator precedence and evaluation order. It is an example of a dangerous macro, and should be written thus:
#define READY_LOOP_DEEP (TASK_COUNT_MAX * WORKLOAD_MAX)
with parentheses to ensure the evaluation order is as expected.
In your case the expression:
readyQueueHead = (readyQueueHead + 1) % READY_LOOP_DEEP;
expands to:
readyQueueHead = (readyQueueHead + 1) % 4 * 10 ;
with left-to-right evaluation, so (readyQueueHead + 1) % 4 is multiplied by 10, rather than (readyQueueHead + 1) % 40 as you intended.
The parentheses change the expression to:
readyQueueHead = (readyQueueHead + 1) % (4 * 10) ;
which will evaluate as you intended.

Extract Argument from C Macro

I have a number of definitions consisting of two comma-separated expressions, like this:
#define PIN_ALARM GPIOC,14
I want to pass the second expression of those definitions (14 in the case above) to unary macros like the following:
#define _PIN_MODE_OUTPUT(n) (1U << ((n) * 2U))
How can I extract the second number? I want a macro, call it "PICK_RIGHT", which will do this for me:
#define PICK_RIGHT(???) ???
So that I can make a new macro that can take my "PIN" definitions:
#define PIN_MODE_OUTPUT(???) _PIN_MODE_OUTPUT(PICK_RIGHT(???))
And I can simply do:
#define RESULT PIN_MODE_OUTPUT(PIN_ALARM)
Do not use macros for this. If you must, the following will work by throwing away the left part first so just the number remains. Use with care. No guarantees.
#define PIN_ALARM GPIOC,14
#define RIGHTPART_ONLY(a,b) b
#define PIN_MODE_OUTPUT(a) RIGHTPART_ONLY(a)
#define RESULT PIN_MODE_OUTPUT(PIN_ALARM)
int main (void)
{
printf ("we'll pick ... %d\n", PIN_MODE_OUTPUT(PIN_ALARM));
printf ("or maybe %d\n", RESULT);
return 0;
}
If you want the left part as a string, you can use this (with the same warnings as above), where the left part gets converted to a string by #:
#define LEFTPART_ONLY(a,b) #a
#define PIN_MODE_NAME(a) LEFTPART_ONLY(a)
There is a practical reason this is not entirely without problems. GPIOC is a symbol and as such it is possibly defined elsewhere. Fortunately, it is not a problem if it is undefined, or it is but to a simple type - after all, first thing the macros do is "throw away the left part". But as Jonathan Leffler comments
Note that if GPIOC maps to a macro containing commas, you're likely to get compilation errors.

use of #define in c

#include<stdio.h>
#include<stdlib.h>
#define d 10+10
int main()
{
printf("%d",d*d);
return 0;
}
I am new to the concept of macros.I found the output for the above program to be 120.What is the logic behind it?
Thanks.
10+10*10+10 == 10 + 100 + 10
Is that clear?
Macros are replaced literally. Think of search/replace. The compiler sees your code as 10+10*10+10.
It is common practice to enclose macro replacement texts in parentheses for that reason:
#define d (10 + 10)
This is even more important when your macro is a function-like macro:
#define SQ(x) ((x) * (x))
Think of SQ(a + b)...
d*d expands into 10+10*10+10. Multiplication comes before addition, so 10 + 100 + 10 = 120.
In general, #define expressions should always be parenthesized: #define d (10+10)
A macro is a nothing more than a simple text replacement, so your line:
printf("%d",d*d);
becomes
printf("%d",10+10*10+10);
You could use a const variable for more reliable behaviour:
const int d = 10+10;
The macro is expanded as is.
Your program becomes
/* declarations and definitions from headers */
int main()
{
printf("%d",10+10*10+10);
return 0;
}
and the calculation is interpreted as
10 + (10 * 10) + 10
Always use parenthesis around macros (and their arguments when you have them)
#define d (10 + 10)
#define
preprocessor directive substitute the first element with the second element.
Just like a "find and replace"
I'm not sure about #include but in C# #define is used at the top to define a symbol. This allows the coder to do things like
#define DEBUG
string connStr = "myProductionDatabase";
#if DEBUG
connStr = "myTestDatabase"
#edif
10+10*10+10 = 20 + 100 = 120
Simple math ;)
Macro doesn't evaluate the value (it doesn't add 10 + 10) but simply replaces all it's occurences with the specified expression.

some error in output in using macro in C

my code is:-
#include<stdio.h>
#include<conio.h>
#define sq(x) x*x*x
void main()
{
printf("Cube is : %d.",sq(6+5));
getch();
}
The output is:-
Cube is : 71.
now please help me out that why the output is 71 and not 1331...
thank you in advance.
Always shield your macro arguments with parenthesis:
#define sq(x) ((x) * (x) * (x))
Consider the evaluation without the parenthesis:
6 + 5 * 6 + 5 * 6 + 5
And recall that * has a higher precedence than +, so this is:
6 + 30 + 30 + 5 = 71;
Get to know the precedence rules if you don't already: http://en.cppreference.com/w/cpp/language/operator_precedence
You need parentheses around the argument.
#define sq(x) ((x)*(x)*(x))
Without the parentheses, the expression will expand to:
6+5*6+5*6+5
Which you can see why it would evaluate to 71.
A safer solution would be to use an inline function instead. But, you would need to define a different one for each type. It might also be more clear to rename the macro.
static inline int cube_int (int x) { return x*x*x; }
If you define the macro like this:
#define sq(x) x*x*x
And call it:
sq(6+5);
The pre-processor will generate this code:
6+5*6+5*6+5
Which is, due to operator precedence, equivalent to:
6+(5*6)+(5*6)+5
That's why, the macro arguments must be parenthesized:
#define sq(x) (x)*(x)*(x)
So that pre-processor output becomes:
(6+5)*(6+5)*(6+5)
However, if you pass some arguments with side-effects such as (i++):
sq(i++)
It will be expanded to:
(i++)*(i++)*(i++)
So, be careful, perhaps you need a function

Resources