Macro name escaping without undef - c

I want to know if there is any way to escape macro name and actually show the real name :
#define BUFF_SIZE 500
printf("%d", BUFF_SIZE);
Is it possible to not expand BUFF_SIZE here without removing the define?

Stringification:
Sometimes you may want to convert a macro argument into a string
constant. Parameters are not replaced inside string constants, but you
can use the ‘#’ preprocessing operator instead. When a macro parameter
is used with a leading ‘#’, the preprocessor replaces it with the
literal text of the actual argument, converted to a string constant.
Unlike normal parameter replacement, the argument is not
macro-expanded first. This is called stringification.
#include <stdio.h>
#define BUFF_SIZE 500
#define STR(x) #x
int main(void)
{
printf("%s\n", STR(BUFF_SIZE));
return 0;
}
Note that you can't print a string with %d, use %s.

Related

C macro stringifying a variable

When can I pass variable's value to a macro for stringifying?
For example the code taken from this post works with a constant-defined macro.
#define MAX_STRING_LENGTH 20
#define STRINGIFY(x) STRINGIFY2(x)
#define STRINGIFY2(x) #x
{
...
char word[MAX_STRING_LENGTH+1];
scanf("%" STRINGIFY(MAX_STRING_LENGTH) "s", word);
...
}
However I cannot use it with a variable such as:
{
...
int val = 20;
char word[MAX_STRING_LENGTH+1];
scanf("%" STRINGIFY(val) "s", word);
...
}
since the compilation is successful with this warning:
warning: invalid conversion specifier 'v' [-Wformat-invalid-specifier]
scanf("%" STRINGIFY(var) "s", word);
~~~^~~~~~~~~~~~~
test2.c:4:22: note: expanded from macro 'STRINGIFY'
#define STRINGIFY(x) STRINGIFY2(x)
^
test2.c:5:23: note: expanded from macro 'STRINGIFY2'
#define STRINGIFY2(x) #x
^
<scratch space>:466:2: note: expanded from here
"var"
^
1 warning generated
but the run of the code does not wait for any input.
On the contrary in this other post it was possible to pass a variable to this macro:
#define PRINT(int) printf(#int "%d\n",int)
...
int var =8;
PRINT(var);
What is the difference between the two cases? How can I modify the first one so that it accepts also variables?
I tried using %d inside the macro but I was not successful.
The preprocessor always operates on tokens only.
A macro is not a function. You don't pass it a variable (by value). You pass a token sequence. In STRINGIFY(MAX_STRING_LENGTH) the token sequence is MAX_STRING_LENGTH, and in STRINGIFY(val) it's the token sequence val.
MAX_STRING_LENGTH is itself a macro, and due to how STRINGIFY is defined to work, the macro will be expanded by the preprocessor before turning it a string literal. So 20 is in turn the token which gets # applied to it, and it produces "20" as a string literal.
On the other hand val is not a macro, the preprcosseor is not going to expand it. It's going to keep the token sequence as val. The fact val is the name of a variable with some value means nothing to the preprocessor, it only cares about tokens. So val is transformed into the literal "val".
The example you brought from another post worked because it expanded to this:
printf("var" "%d\n", var);
The variable name in #int turns into a literal, there is no magic that lets the preprocessor read a variable's value. The fact var 8 is printed is only because var is passed as an argument to printf! It's printed at run-time by the %d specifier.
Finally, when experimenting with the preprcoessor it's always helpful to look at the source file after prpeprocessing is done, but before the file is compiled. The gcc -E flag (or equivalent for your compiler) can help you do that.
STRINGIFY(val) will result in "val", not the value you wanted to stringify, so you get a final format string of "%vals" ("%" "val" "s"). That's how the C preprocessor works, it does just text replacements, nothing more.
The PRINT example:
#define PRINT(int) printf(#int "%d\n", int)
PRINT(var); // to be resolved
printf(#var "%d\n", var); // intermediate result
printf("var" "%d\n", var); // final result, this is what the C compiler sees
But why did it work with MAX_STRING_LENGTH?
#define MAX_STRING_LENGTH 20
#define STRINGIFY(x) STRINGIFY2(x)
#define STRINGIFY2(x) #x
STRINGIFY(MAX_STRING_LENGTH) // to be resolved
STRINGIFY2(20) // intermediate step; STRINGIFY2 known as macro, thus:
#20 // another intermediate step
"20" // final result

Printing define name c

#define Page 5
void printSystemInfo() {
printf ("%i", Page);
}
Thats my code can anyone explain me how to print Page 5 in the console?
For now my console looks like this "5" But I want to have "Page 5"
Thanks for helping !
You can use a little preprocessor trick. We have the # operator, which will convert a symbol into a string.
#define _(a) #a
When you call _(foo), it translates it as "foo". So, in your case, you could do something like:
#include <stdio.h>
#define _(a) # a
#define PAGE 5
int main(int argc, char *argv[])
{
printf("%s: %i\n", _(PAGE), PAGE);
return 0;
}
What this will do is:
We define a macro named _ that takes one parameter a. This macro uses the operator # from the preprocessor (called stringification). This will case a named passed to the macro to be converted into a string. Example: _(foo) gets translated to "foo".
In main, the printf() call is then translated as printf("%s: %i\n", "PAGE", 5);. In a stepwise way, when the preprocessor sees the _(PAGE) symbol, it translates it as "PAGE".
The inner workings of this things is explained in the above link, which I quote (my markings):
Sometimes you may want to convert a macro argument into a string constant. Parameters are not replaced inside string constants, but you can use the ‘#’ preprocessing operator instead. When a macro parameter is used with a leading ‘#’, the preprocessor replaces it with the literal text of the actual argument, converted to a string constant. Unlike normal parameter replacement, the argument is not macro-expanded first. This is called stringification.
Here you go. This is very trivial stuff, but please ask if something is unclear.
#define Page 5
void printSystemInfo()
{
printf((char const[])??<0120,0141,0147,0145,0040,0045,0151,!"bad"??>,Page);
}

Can a macro remove characters from its arguments?

Is it possible to define a macro that will trim off a portion of the string argument passed in?
For example:
//can this be defined?
#define MACRO(o) ???
int main(){
printf(MACRO(ObjectT)); //prints "Object" not "ObjectT"
}
Would it be possible for a macro that trim off the last character 'T'?
You can do it for specific strings that you know in advance, presented to the macro as symbols rather than as string literals, but not for general symbols and not for string literals at all. For example:
#include <stdio.h>
#define STRINGIFY(s) # s
#define EXPAND_TO_STRING(x) STRINGIFY(x)
#define TRUNCATE_ObjectT Object
#define TRUNCATE_MrT Pity da fool
#define TRUNCATE(s) EXPAND_TO_STRING(TRUNCATE_ ## s)
int main(){
printf(TRUNCATE(ObjectT)); // prints "Object"
printf(TRUNCATE(MrT)); // prints "Pity da fool"
}
That relies on the token-pasting operator, ##, to construct the name of a macro that expands to the truncated text (or, really, the replacement text), and the stringification operator, #, to convert the expanded result to a string literal. There's a little bit of required macro indirection in there, too, to ensure that all the needed expansions are performed.
Well, at least it should print "Object"...
//can this be defined?
#define MACRO(o) #o "\b \b"
int main(){
printf(MACRO(ObjectT)); //prints "Object" not "ObjectT"
}
And no, you can't strip character using preprocessor only without actual C code (say, malloc+strncpy) to do that.
With the preprocessor? No. It sounds like what you really want to do is something like this:
Code not tested
#define STRINGIFY(o) #o
char* serialize(char* s)
{
if (strcmp(s, "ObjectT") == 0) return "Object";
}
int main(){
printf(serialize(STRINGIFY(#o))); //prints "Object" not "ObjectT"
}

Having troubles formatting scanf while keeping my code understandable

I need a function to read a file name, with a max length of MAX_FILE_NAME_SIZE, which is a symbolic constant, I did this the following way:
char * readFileName()
{
char format[6];
char * fileName = malloc(MAX_FILE_NAME_SIZE * sizeof(fileName[0]));
if(fileName== NULL)
return NULL;
sprintf(format, "%%%ds", MAX_FILE_NAME_SIZE-1);
scanf(format, fileName);
fileName= realloc(fileName, strlen(fileName)*sizeof(fileName[0]));
return fileName;
}
I'd really like to get read of the sprintf part (and also the format vector), what's the cleanest and most efficient way to do this?
Solution
You can make a little Preprocessor hack:
#define MAX_BUFFER 30
#define FORMAT(s) "%" #s "s"
#define FMT(s) FORMAT(s)
int main(void)
{
char buffer[MAX_BUFFER + 1];
scanf(FMT(MAX_BUFFER), buffer);
printf("string: %s\n", buffer);
printf("length: %d\n", strlen(buffer));
return 0;
}
The FORMAT and FMT macros are necessary for the preprocessor to translate them correctly. If you call FORMAT directly with FORMAT(MAX_BUFFER), it will translate into "%" "MAX_BUFFER" "s" which is no good.
You can verify that using gcc -E scanf.c. However, if you call it through another macro, which will effectively resolve the macro names for you and translate to "%" "30" "s", which is a fine format string for scanf.
Edit
As correctly pointed out by #Jonathan Leffler in the comments, you can't do any math on that macro, so you need to declare buffer with plus 1 character for the NULL terminating byte, since the macro expands to %30s, which will read 30 characters plus the null byte.
So the correct buffer declaration should be char buffer[MAX_BUFFER + 1];.
Requested Explanation
As asked in the comments, the one macro version won't work because the preprocessor operator # turns an argument into a string (stringification, see bellow). So, when you call it with FORMAT(MAX_BUFFER), it just stringifies MAX_BUFFER instead of macro-expanding it, giving you the result: "%" "MAX_BUFFER" "s".
Section 3.4 Stringification of the C Preprocessor Manual says this:
Sometimes you may want to convert a macro argument into a string constant. Parameters are not replaced inside string constants, but you can use the ‘#’ preprocessing operator instead. When a macro parameter is used with a leading ‘#’, the preprocessor replaces it with the literal text of the actual argument, converted to a string constant. Unlike normal parameter replacement, the argument is not macro-expanded first. This is called stringification.
This is the output of the gcc -E scanf.c command on a file with the one macro version (the last part of it):
int main(void)
{
char buffer[30 + 1];
scanf("%" "MAX_BUFFER" "s", buffer);
printf("string: %s\n", buffer);
printf("length: %d\n", strlen(buffer));
return 0;
}
As expected. Now, for the two levels, I couldn't explain better than the documentation itself, and in the last part of it there's an actual example of this specific case (two macros):
If you want to stringify the result of expansion of a macro argument, you have to use two levels of macros.
#define xstr(s) str(s)
#define str(s) #s
#define foo 4
str (foo)
==> "foo"
xstr (foo)
==> xstr (4)
==> str (4)
==> "4"
s is stringified when it is used in str, so it is not macro-expanded first. But s is an ordinary argument to xstr, so it is completely macro-expanded before xstr itself is expanded (see Argument Prescan). Therefore, by the time str gets to its argument, it has already been macro-expanded.
Resource
The C Preprocessor

Define a macro off of the content of a macro

Is it possible to define a macro off of the content of a macro?
For example:
#define SET(key,value) #define key value
SET(myKey,"value")
int main(){
char str[] = myKey;
printf("%s",str);
}
would result in
int main(){
char str[] = "value";
printf("%s",str);
}
after being preprocessed.
Why would I do this? Because I'm curious ;)
No, its not possible to define a macro within another macro.
The preprocessor only iterates once before the compiler. What you're suggesting would require an undetermined amount of iterations.
No you can't - # in a replacment list of a macro means QUOTE NEXT TOKEN. It's more of a spelling issue, than any logical puzzle :)
(If you require this kind of solution in your code, than there are ways and tricks of using macro's, but you need to be specific about the use cases you need - as your example can be achieved by defining: #define mykey "value")
Here it is from the ansi C99 standard
6.10.3.2 The # operator
Constraints
1 Each # preprocessing token in the replacement list for a
function-like macro shall be followed by a parameter as the next
preprocessing token in the replacement list. Semantics 2 If, in the
replacement list, a parameter is immediately preceded by a #
preprocessing token, both are replaced by a single character string
literal preprocessing token that contains the spelling of the
preprocessing token sequence for the corresponding argument. Each
occurrence of white space between the argument’s preprocessing tokens
becomes a single space character in the character string literal.
White space before the first preprocessing token and after the last
preprocessing token composing the argument is deleted. Otherwise, the
original spelling of each preprocessing token in the argument is
retained in the character string literal, except for special handling
for producing the spelling of string literals and character constants:
a \ character is inserted before each " and \ character of a character
constant or string literal (including the delimiting " characters),
except that it is implementation-defined whether a \ character is
inserted before the \ character beginning a universal character name.
If the replacement that results is not a valid character string
literal, the behavior is undefined. The character string literal
corresponding to an empty argument is "". The order of evaluation of #
and ## operators is unspecified.
Macros are a simple text substitution. Generating new preprocessor directives from a macro would require the preprocessor to continue preprocessing from the beginning of the substitution. However, the standard defined preprocessing to continue behind the substitution.
This makes sense from a streaming point of view, viewing the unprocessed code as the input stream and the processed (and substituted) code as the output stream. Macro substitutions can have an arbitrary length, which means for the preprocessing from the beginning that an arbitrary number of characters must be inserted at the beginning of the input stream to be processed again.
When the processing continues behind the substitution, then the input simply is handled in one single run without any insertion or buffering, because everything directly goes to the output.
whilst it is not possible to use a macro to define another macro, depending on what you are seeking to achieve, you can use macros to effectively achieve the same thing by having them define constants. for example, i have an extensive library of c macros i use to define objective C constant strings and key values.
here are some snippets of code from some of my headers.
// use defineStringsIn_X_File to define a NSString constant to a literal value.
// usage (direct) : defineStringsIn_X_File(constname,value);
#define defineStringsIn_h_File(constname,value) extern NSString * const constname;
#define defineStringsIn_m_File(constname,value) NSString * const constname = value;
// use defineKeysIn_X_File when the value is the same as the key.
// eg myKeyname has the value #"myKeyname"
// usage (direct) : defineKeysIn_X_File(keyname);
// usage (indirect) : myKeyDefiner(defineKeysIn_X_File);
#define defineKeysIn_h_File(key) defineStringsIn_h_File(key,key)
#define defineKeysIn_m_File(key) defineStringsIn_m_File(key,##key)
// use defineKeyValuesIn_X_File when the value is completely unrelated to the key - ie you supply a quoted value.
// eg myKeyname has the value #"keyvalue"
// usage: defineKeyValuesIn_X_File(keyname,#"keyvalue");
// usage (indirect) : myKeyDefiner(defineKeyValuesIn_X_File);
#define defineKeyValuesIn_h_File(key,value) defineStringsIn_h_File(key,value)
#define defineKeyValuesIn_m_File(key,value) defineStringsIn_m_File(key,value)
// use definePrefixedKeys_in_X_File when the last part of the keyname is the same as the value.
// eg myPrefixed_keyname has the value #"keyname"
// usage (direct) : definePrefixedKeys_in_X_File(prefix_,keyname);
// usage (indirect) : myKeyDefiner(definePrefixedKeys_in_X_File);
#define definePrefixedKeys_in_h_File_2(prefix,key) defineKeyValuesIn_h_File(prefix##key,##key)
#define definePrefixedKeys_in_m_File_2(prefix,key) defineKeyValuesIn_m_File(prefix##key,##key)
#define definePrefixedKeys_in_h_File_3(prefix,key,NSObject) definePrefixedKeys_in_h_File_2(prefix,key)
#define definePrefixedKeys_in_m_File_3(prefix,key,NSObject) definePrefixedKeys_in_m_File_2(prefix,key)
#define definePrefixedKeys_in_h_File(...) VARARG(definePrefixedKeys_in_h_File_, __VA_ARGS__)
#define definePrefixedKeys_in_m_File(...) VARARG(definePrefixedKeys_in_m_File_, __VA_ARGS__)
// use definePrefixedKeyValues_in_X_File when the value has no relation to the keyname, but the keyname has a common prefixe
// eg myPrefixed_keyname has the value #"bollocks"
// usage: definePrefixedKeyValues_in_X_File(prefix_,keyname,#"bollocks");
// usage (indirect) : myKeyDefiner(definePrefixedKeyValues_in_X_File);
#define definePrefixedKeyValues_in_h_File(prefix,key,value) defineKeyValuesIn_h_File(prefix##key,value)
#define definePrefixedKeyValues_in_m_File(prefix,key,value) defineKeyValuesIn_m_File(prefix##key,value)
#define VA_NARGS_IMPL(_1, _2, _3, _4, _5, _6, _7, _8, _9, _10, _11, _12, N, ...) N
#define VA_NARGS(...) VA_NARGS_IMPL(X,##__VA_ARGS__, 11, 10,9, 8, 7, 6, 5, 4, 3, 2, 1, 0)
#define VARARG_IMPL2(base, count, ...) base##count(__VA_ARGS__)
#define VARARG_IMPL(base, count, ...) VARARG_IMPL2(base, count, __VA_ARGS__)
#define VARARG(base, ...) VARARG_IMPL(base, VA_NARGS(__VA_ARGS__), __VA_ARGS__)
and a usage example that invokes it:
#define sw_Logging_defineKeys(defineKeyValue) \
/** start of key list for sw_Logging_ **/\
/**/defineKeyValue(sw_Logging_,log)\
/**/defineKeyValue(sw_Logging_,time)\
/**/defineKeyValue(sw_Logging_,message)\
/**/defineKeyValue(sw_Logging_,object)\
/**/defineKeyValue(sw_Logging_,findCallStack)\
/**/defineKeyValue(sw_Logging_,debugging)\
/**/defineKeyValue(sw_Logging_,callStackSymbols)\
/**/defineKeyValue(sw_Logging_,callStackReturnAddresses)\
/** end of key list for sw_Logging_ **/
sw_Logging_defineKeys(definePrefixedKeys_in_h_File);
the last part may be a little difficult to get your head around.
the sw_Logging_defineKeys() macro defines a list that takes the name of a macro as it's parameter (defineKeyValue) this is then used to invoke the macro that does the actual definition process. ie, for each item in the list, the macro name passed in is used to define the context ( "header", or "implementation", eg either "h" or "m" file, if you understand the objective c file extensions) whilst this is used for objective c, it is simply plain old c macros, used for a "higher purpose" than possibly Kernighan and Richie ever envisaged. :-)

Resources