Stringification Parentheses Elimination - c

In c I have the following in an existing code base:
#define MYVAR (1)
As you can see this is conforming good practices in C by surrounding the #define with parenthesis (even though I know in this case it makes no difference since the value is not
an expression). Regardless I would like to use this in stringification. when I do this:
#define STRINGIFY(x) #x
#define TO_STRING(x) STRINGIFY(x)
const char* mystring = TO_STRING(MYVAR) ;
The resultant string is "(1)". I'd like to eliminate the parentheses without doing the simple:
#define MYVAR 1
Is there anyway to eliminate parentheses during stringification in c?

Just use STRINGIFY x instead of STRINGIFY(x)
#include <stdio.h>
#define MYVAR 1
#define STRINGIFY(x) #x
#define TO_STRING(x) STRINGIFY x
int main(void)
{
const char *mystring = TO_STRING(MYVAR);
printf("%s\n", mystring);
return 0;
}
TO_STRING(x) expands to STRINGIFY (1) when MYVAR is defined as (1)
If MYVAR is defined as 1 without parentheses you get a compile time error.

Related

Insert double quotes in a macro for pragma in C

I'm trying to create a macro in C in order to create the correct pragma declaration.
_pragma(section .BLOCK1) //Correct but deprecated
_pragma(section ".BLOCK1") //Correct without warning
Following code is working, but the compiler gives me a warning (deprecated declaration):
#define DO_PRAGMA(x) _Pragma(#x)
#define PRAGMA(number) \
DO_PRAGMA(section .BLOCK##number)
PRAGMA(1)
How I can include the double quotes in the macro?
I have already tried inserting "\"", but it is not working because the string is interpreted directly.
You can pass this to a helper macro which expands and stringifies the arguments.
#define _stringify(_x) #_x
#define DO_PRAGMA(a) _Pragma(_stringify(a))
#define PRAGMA(number) \
DO_PRAGMA(section _stringify(.BLOCK##number))
The correct way to add double quotes to a macro is indeed to use backslash i.e.:
#define STRING "\"string\""
"string" is now stored in STRING.
To concatenate a number into your macro string you can do something like, but it needs to be stored in non const char array:
#define STRING "section \".BLOCK%d\""
#define CONV(str, n) sprintf(str, STRING, n)
//...
char str [50];
CONV(str, 1);
DO_PRAGMA(str);
//...
If you haven't already, check pragma documentation and this usage example.

Compare defined expressions as text

Say I have a set of defines arranged this way:
#define Var0 ((uint32_t)0x00001)
#define Var1 ((uint32_t)0x00002)
#define Var2 ((uint32_t)0x00004)
and later in the code I have this:
#define CurrVar Var1
When I attempt to compare:
#if (CurrVar != Var1)
#error "CurrVar" has to be "Var1" for this code to work
#endif
I get:
error: token is not a valid binary operator in a preprocessor subexpression
I cannot change values of VarX since those are part of a library, but I need to make sure that a proper value is used in the code at compile time.
Is there a way to compare those expressions?
Even if it will be compared as text, like this:
"((uint32_t)0x00002)" <> "((uint32_t)0x00002)"
or
"Var1" <> "Var1"
etc
Use _Static_assert, which is in standard C from 2011 on:
_Static_assert(CurrVar == Var1, "CurrVar is not equal to Var1.");
If you must use a pre-2011 implementation of C, a common kludge is to declare an array type with an expression that is negative if an assertion fails, causing the compiler to complain about the array size:
typedef char CurrVarIsNotEqualToVar1[CurrVar == Var1 ? 1 : -1];
You can't use anything C related in such operations. Preprocessor does not understand casts and it does not compare strings.
https://godbolt.org/z/X2xuPa
#include <stdint.h>
#define V1 1
#define V2 2
#define V3 3
#define CV V1
#if CV==V1
void foo(void)
{
printf("V1\n");
}
#else
void foo(void)
{
printf("not V1\n");
}
#endif
int main(void)
{
foo();
}

Can anyone explain the concatenation on #define like that: [duplicate]

#define DEFINE_STAT(Stat) \
struct FThreadSafeStaticStat<FStat_##Stat> StatPtr_##Stat;
The above line is take from Unreal 4, and I know I could ask it over on the unreal forums, but I think this is a general C++ question that warrants being asked here.
I understand the first line defines a macro, however I am not well versed in preprocessor shenanigans in C++ and so I'm lost over there. Logic tells me the backslash means the declaration continues onto the next line.
FThreadSafeStaticStat looks a bit like a template, but there's #'s going on in there and a syntax I've never seen before in C++
Could someone tell me what this means? I understand that you may not have access to Unreal 4, but it's just the syntax I don't understand.
## is the preprocessor operator for concatenation.
So if you use
DEFINE_STAT(foo)
anywhere in the code, it gets replaced with
struct FThreadSafeStaticStat<FStat_foo> StatPtr_foo;
before your code is compiled.
Here is another example from a blog post of mine to explain this further.
#include <stdio.h>
#define decode(s,t,u,m,p,e,d) m ## s ## u ## t
#define begin decode(a,n,i,m,a,t,e)
int begin()
{
printf("Stumped?\n");
}
This program would compile and execute successfully, and produce the following output:
Stumped?
When the preprocessor is invoked on this code,
begin is replaced with decode(a,n,i,m,a,t,e)
decode(a,n,i,m,a,t,e) is replaced with m ## a ## i ## n
m ## a ## i ## n is replaced with main
Thus effectively, begin() is replaced with main().
TLDR; ## is for concatenation and # is for stringification (from cppreference).
The ## concatenates successive identifiers and it is useful when you want to pass a function as a parameter. Here is an example where foo accepts a function argument as its 1st argument and the operators a and b as the 2nd and 3rd arguments:
#include <stdio.h>
enum {my_sum=1, my_minus=2};
#define foo(which, a, b) which##x(a, b)
#define my_sumx(a, b) (a+b)
#define my_minusx(a, b) (a-b)
int main(int argc, char **argv) {
int a = 2;
int b = 3;
printf("%d+%d=%d\n", a, b, foo(my_sum, a, b)); // 2+3=5
printf("%d-%d=%d\n", a, b, foo(my_minus, a, b)); // 2-3=-1
return 0;
}
The # concatenates the parameter and encloses the output in quotes. The example is:
#include <stdio.h>
#define bar(...) puts(#__VA_ARGS__)
int main(int argc, char **argv) {
bar(1, "x", int); // 1, "x", int
return 0;
}

variable name as macro argument

I am trying to create a macro in c, that will take a variable name, and declare it. I could call it like this:
MY_MACRO(test);
Would produce:
int test;
In order to achieve this I went this way:
#define MY_MACRO(var) /
int ##var; /
But the compiler doesn't understand this. Does such syntax exist in C11?
I wouldn't recommend doing such a thing. Anyway, there are two problems. First of all, to skip a newline, you need \, not /.
Second, the ## is wrong. What it does is concatenating the var to the int. So with MY_MACRO(foo) you would get intfoo;, but you want int foo;
The macro needs to be like this:
#define MY_MACRO(var) \
int var
## is not applicable here as it concatenates the token with something else
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define MY_MACRO(var) int var
or
#define MY_MACRO(var) \
int var \
void foo(void)
{
MY_MACRO(a);
a = rand();
printf("%d\n",a);
}
## pastes two tokens together into one token.
#define poem(var)\
int jack##var;
// Produces 'int jacksprat;'
poem(sprat)
In your case you don't need to do anything special at all, you can just use the argument directly:
#define MY_MACRO(var)\
int var;
The correct syntax would be something along the lines of this:
#define MY_MACRO(ident) \
int ident
int main() {
MY_MACRO(test);
test =42;
return test;
}
However, have you been looking into typedefs? Unlike typedefs, macros are considered bad practice.

Is it possible to put compiler -D define string value in variable?

I have following code:
#include <stdio.h>
#ifdef COMP_DEF
static const char * x = COMP_DEF;
#else
static const char * x = "NULL";
#endif
int main(int argc, char ** argv)
{
printf("%s\n", x);
return 0;
}
What I want is to compile this program with two ways. First with compiler parameter:
-DCOMP_DEF=FOO_BAR
and second way without this. I expect, my program would print FOO_BAR and NULL.
But when I try to compile I get following errors:
:0:10: error: 'FOO_BAR' undeclared here
(not in a function) main.c:5:25: note: in expansion of macro
'COMP_DEF' static const char * x = COMP_DEF;
Is it possible to print/store in variable compiler passed macrodefine value?
You should try this common trick usually called stringification:
#define STR_IMPL(x) #x
#define STR(x) STR_IMPL(x)
#ifdef COMP_DEF
static const char * x = STR(COMP_DEF);
#else
static const char * x = "NULL";
#endif
# followed by argument name in macro expands to string literal containing passed argument. If you do just
#define STR(x) #x
this would make STR(COMP_DEF) expand to "COMP_DEF". To avoid this you need another level of macro expansion.

Resources