Is there a way to manipulate preprocessor define scope in C - c

Just curious. Imagine I need to have a #define A that is the sum of n numbers, and those n numbers have a meaning I'd like to make explicit, but only for the computation of A, to improve readiblity,
instead of writing n macros or just writing #define A <result_of_the_sum>.
Is there a way I could limit the reach of these n #define directives to just the definition of A ? Just as in C one would do :
int a = 0;
{
int b = 1;
int c = 2;
int d = 3;
a = b + c + d;
} // end of b,c,d scope.
My intention is to have A defined when compiling but no definition for the other n defines used to compute A, since these would only be useful to understand the code better.
Edit:
Imagine I have these macros:
#define MEANINGFUL_NUMBER_1 1
#define MEANINGFUL_NUMBER_2 2
#define MEANINGFUL_NUMBER_3 3
And I have a macro, A that is the sum of them, and I like someone reading my code to understand the value of A not just see it defined straightforwardly, i.e. #define A (MEANINGFUL_NUMBER_1 + ... + MEANINGFUL_NUMBER_N), such that only A is substituted before compilation but MEANINGUL_NUMBER_* is not.

Is there a way to manipulate preprocessor define scope in C
No.
Is there a way I could limit the reach of these n #define directives to just the definition of A ?
No.
Note that macros are evaulated upon use. That means that everything has to be visible when the macro is used. You can #undef all the macros after all usages, ergo "limit the reach" in that way.
In C, there are no namespaces. In C use prefixes. You would do:
#define LIB_PRIV_B 1
#define LIB_PRIV_C 2
#define LIB_PRIV_D 3
#define LIB_A (LIB_PRIV_B + LIB_PRIV_C + LIB_PRIV_D)
If you really do not want the numbers to leak into C, then use something to generate the C source code, which also gives you more power to the preprocessor side. Use jinja2, m4, php or python, and configure your build system to properly handle the generation dependency.

Related

How do I define multiple #define with single assign value in C

I had found some related question about How do I #define multiple values C / C++. But that is not what I am looking for. Instead, I want to do the opposite way.
We can simply assign something like this
int a,b,c,d,e;
a = b = c = d = e = 5;
printf("Value %d",e);
But what I am looking for is how to combine below define into one line, given fix value to assign.
#define SIZE_OF_NODE_ADD 4
#define SIZE_OF_KEY_ADD 4
#define SIZE_OF_ID_ADD 4
#define SIZE_OF_PW_ADD 4
Is it possible to do that ? something like
#define SIZE_OF_NODE_ADD = SIZE_OF_KEY_ADD = SIZE_OF_ID_ADD = SIZE_OF_PW_ADD = 4
/* The syntax is wrong, I just emphasize for easier understanding what I am looking for*/
Well, #define statements can handle multiple lines using '\' at the end of the line without any other character next, so you can create fancy MACROS (Multi-line DEFINE directives?). But a simple solution for your problem may be using a reference definition so you just have to change that one to change the others value.
#define REFERENCE_VALUE 4
#define SIZE_OF_NODE_ADD REFERENCE_VALUE
#define SIZE_OF_KEY_ADD REFERENCE_VALUE
#define SIZE_OF_ID_ADD REFERENCE_VALUE
#define SIZE_OF_PW_ADD REFERENCE_VALUE
Remember that the REFERENCE_VALUE has to be before its use in the file, otherwise it won't compile.
It's in the C standard, that a preprocessor statement is terminated by a new line, so you must do:
#define SIZE_OF_NODE_ADD 4
#define SIZE_OF_KEY_ADD 4
#define SIZE_OF_ID_ADD 4
#define SIZE_OF_PW_ADD 4
A multiple define statement is not allowed.(And even really hard to read)

Difference between macros and Functions in C language

I'm new to C language. When I'm learning C language I learn something called macros. As I understood macros are like a functions in JavaScript that we can call when we needed. But then I learn that after compiling the program all the places that i have called to macros are replaced by the definition of the macro. So I'm confusing what is the difference between macro and a function in C language.
Also I wanna know whether I can write multi line macros in my code and if it is possible how it will be replaced when the code compiled.
As a example assume that I wanna macro to find the maximum value among two numbers.
Is it a good practice to write that process as a macro rather than write is as a function.
Everything stands - don't use macro. A better alternative inline the function - it would achieve the same efficiency you expect. But for fun, I worked a bit to use gcc statement expressions that means a non-portable gcc centric solution.
#include <stdio.h>
#define SUM(X) \
({ long s = 0; \
long x = (X) > 0 ? (X) : (-(X)); \
while(x) { \
s += x % 10; \
x /= 10; \
} \
s; \
})
int main(void) {
printf("%ld\n",SUM(13423) );
return 0;
}
This solution begs for a function. Using statement expression to have that return something feature inside macro. Well I said, go for inline function. That would serve the purpose much cleaner way.
Using macros is sometimes dangourous:
https://gcc.gnu.org/onlinedocs/cpp/Macro-Pitfalls.html#Macro-Pitfalls
you can read on the dangers of using it here..
but, for your question:
#include <stdio.h>
#define SUM(X, Y) (X + Y)
void main() {
printf("the sum of 3,4 is : %d\n", SUM(3,4));
}
will output:
the sum of 3,4 is : 7

Can I capture the underlying value of one macro when defining another?

Imagine I want to #define a macro such that it is equal to the current value of another macro (if such a concept exists).
For example:
#include "def_a.h" // defines macro A
#define B A
This defines B to be A. If A later changes definition (i.e., through a redefinition) the value of B also changes (because B expands to A at the point of use, which further expands to the new value of A).
What I'd like is some way to "bake in" the value of A into B so that B just expands to the value of A, not A itself.
For example:
#define A first
#define B BAKE_IN(A)
#undef A
#define A second
#define C BAKE_IN(A)
#undef A
#define A third
// here I want B to expand to first, and C to expand to second
Of course BAKE_IN is not a real thing, but I'm wondering if there is some way to achieve this effect.
Now, I didn't really say what should happen if A itself is defined in terms of other macros, but I'm OK both with "one level of expansion" (i.e., B gets the value of A is expanded, so further macros remain) and also "full expansion" (i.e., A is fully expanded, recursively, as it would be at a point of use).
Macros are never replaced in the body of a #define directive, so there is no way to define a macro as the current value of another macro, except for the limited case of macros whose value is a constant arithmetic expression.
In the latter case, you can use BOOST_PP_ASSIGN_SLOT from the Boost preprocessor library. (Although most of the Boost libraries are C++-specific, the Boost preprocessor library works for both C and C++, and has no dependency on any other Boost component.)
I don't think there is a clean solution. The closest thing that I found is to preserve "stringified" values within char arrays:
#include <stdio.h>
#define BAKE_IN(X, id) BAKE_IN_REAL(X ## _, X, id)
#define BAKE_IN_REAL(X, Y, id) static const char X ## id[] = #Y;
#define BAKE_OUT(X, id) X ## _ ## id
#define A first
BAKE_IN(A, 1)
#define B BAKE_OUT(A, 1)
#undef A
#define A second
BAKE_IN(A, 2)
#define C BAKE_OUT(A, 2)
#undef A
int main(void)
{
printf("%s\n", B); // prints "first"
printf("%s\n", C); // prints "second"
return 0;
}
The idea is that BAKE_IN macro declares object named as e.g. A_1, which holds the current expansion of A.
There are two major limitations:
Every pair of BAKE_IN and BAKE_OUT needs unique id
The expansion is only available in "stringified" form

Macro as an argument to a macro in C

I want to know which macro gets replaced first in the following code
#define A 100
#define B 200
#define C(A,B) A+B
here when we use C, then evaluation will be from left to right or right to left. That is B gets the value first or A gets the value first
i gave this example just to make things look simple, may be i was wrong. the actual thing i want to ask is, if A and B also take arguments and have the scope of expansion, then which one would expand first
I'm not sure what you mean. There's never a point where you can "see" half a result of the preprocessor; the entire input file is preprocessed, then handed over to the compiler.
I think that the names for the macro arguments will never also be replaced as if they were stand-alone symbols.
I tried it, and this program:
#include <stdio.h>
#define A 100
#define B 200
#define C(A, B) A + B
int main(void) {
printf("A=%d\nB=%d\nC(1,2)=%d\n", A, B, C(1,2));
return 0;
}
prints
A=100
B=200
C(1,2)=3
So, C(1,2) expands to 1 + 2, the definitions of A and B don't matter.
Of course I must say that I find the above very bad practice, since it's quite confusing. Never use all-caps names for macro arguments, since macros and preprocessor symbols tend to use such names.

How do I access #define Variable from one structure in a C file?

#define MAX 7
#define BUFFER 16
#define MODULO 8
typedef struct {
int x;
} BLAH;
if I have:
checkWindow(BLAH *b) {
int mod;
mod = b.MODULO;
}
Specifically can I access MODULO from the BLAH structure?
I think you misunderstand the meaning of preprocessor definitions. #define-d items only look like variables, but they are not variables in the classical sense of the word: they are text substitutions. They are interpreted by the preprocessor, before the compiler gets to see the text of your program. By the time the preprocessor is done, the text of the program has no references to MAX, BUFFER, or MODULO: their occurrences are substituted with 7, 16, and 8. That is why you cannot access #define-d variables: there are no variables to access.
All #defines will be replaced in plain text by the "values" they define, before compilation. They are not variables, just short-hand syntax to make writing programs easy. None of your #def stuff actually reaches the compiler, its resolved in preprocessor.
Now, if you simply replace MODULO in your example by 8, does the resulting code make sense to you?
If it does make sense, please take a Computer Programming 101 course.

Resources