Using macros in printf with a number sign - c

I'm a bit confused about an explanation concerning macros in K&R 2nd Ed, p.90. Here is the paragraph:
Formal parameters are not replaced within quoted strings. If, however, a parameter name is preceded by a # in the replacement text, the combination will be expanded into a quoted string with the parameter replaced by the actual argument.
I'm not sure what that second sentence is saying. It goes on to explain a use for this with a "debugging print macro".
This can be combined with a string concatenation to make, for example, a debugging print macro:
#define dprint(expr) printf(#expr " = %g\n", expr);
Edit:
All the input was useful. Thank you guys.

If you define macro like this:
#define MAKE_STRING(X) #X
Then, you can do something like this:
puts(MAKE_STRING(a == b));
Which will expand into:
puts("a == b");
In the dprint() example, it is printing out a string form of the expression, as well as the expression value.
dprint(sin(x)/2);
Will expand into:
printf("sin(x)/2" " = %g\n", sin(x)/2);
String literal concatenation will treat the first parameter as a single string literal.

It is just a neat feature where you can convert a macro parameter into a string literal which mainly is useful for debugging purposes. So
dprint(x + y);
is expanded by the C preprocessor to this
printf("x + y = %g\n", x + y);
Notice how the value of the parameter expr appears both inside the string literal and also in the code generated by the macro. For this to happen you need to prefix expr with # to create a string literal.
One thing worth pointing out is that adjacent string literals are combined into a single string literal, e.g. "x + y" " = %g\n" are combined into "x + y = %g\n".

#expr is expanded into "expr". Two string literals next to each other are automatically concatenated. We can see that invoking gcc -E for dprint(test) will give the following output:
("test" " = %g\n");

This site may help. It describes how stringification can be implemented.

Related

ASCI Escape Codes with #define value?

I have a #define'd value named HEIGHT with a value of 20.
I want to use the ASCI escape code "\033[HA" (where H is the number of lines the cursor is moved up.
However, when my code reads "\033[HEIGHTA", it is reading the 'H' as a different escape code (return cursor home). How can I include a #define'd value within an escape code?
Thanks
There are several alternatives, among them
Use a function instead of a macro to generate the escape code as needed. For example,
const char *cursor_up_seq() {
static char sequence[12];
if (sequence[0] == '\0') {
// one-time initialization
sprintf(sequence, "\033[%dA", HEIGHT);
}
return sequence;
}
As a variation on (1), do not produce the escape sequence as a standalone entity at all. Instead, embed it in whatever else you are printing, where it is natural to use (say) printf() to print the value of the HEIGHT macro.
But if you really want to produce a macro for a string literal containing the whole escape sequence, then you can do so by combining two C features:
the stringification (#) macro operator, and
automatic concatenation of adjacent string literals
Another answer, now deleted, attempted to demonstrate that, but floundered on one of the gotchas in that area. Here is a variation that works:
#define HEIGHT 20
#define STRINGIFY(x) #x
#define STRINGIFY_VALUE(x) STRINGIFY(x)
#define SEQUENCE "\033[" STRINGIFY_VALUE(HEIGHT) "A"
The resulting SEQUENCE macro expands to "\033[" "20" "A", which is 100% equivalent to "\033[20A" because of string literal concatenation. The gotcha here is that you cannot use STRINGIFY() directly for this purpose, because that does not macro-expand its argument before converting it to a string (per the standard behavior of #). Wrapping it in another macro layer (STRINGIFY_VALUE) results in that outer layer expanding the argument before presenting the result for stringification.

integer to string converter(using macros)

I was doing basics of macros. I define a macro as follows:
#define INTTOSTR(int) #int
to convert integer to string.
Does this macro perfectly converts the integer to string? I mean are there some situations where this macro can fail?
Can I use this macro to replace standard library functions like itoa()?
for example:
int main()
{
int a=56;
char ch[]=INTTOSTR(56);
char ch1[10];
itoa(56,ch1,10);
printf("%s %s",ch,ch1);
return 0;
}
The above program works as expected.
Interestingly this macro can even convert float value to string.
for example:
INTTOSTR(53.5);
works nicely.
Till now I was using itoa function for converting int to string in all my projects. Can I replace itoa confidently in all projects. Because I know there is less overhead in using macro than function call.
Macros execute during (before to be exact) compile time, so you can convert a literal number in your sourcecode to a string but not a number stored in a variable
In your example, INTTOSTR(56) uses the stringification operator of the preprocessor which eventually results in "56". If you called it on a variable, you'd get the variable name but not its content.
In C, you can use itoa or if you are desperate and would like to avoid it, use snprintf for instance:
snprintf(my_str, sizeof(int), "%i", my_int);
The problem with your macro is that you are thinking about constants, but of course, your macro will be broken when you need to use a variable holding an integer. Your macro would try to stringify the macro name as opposed to the value it would be holding.
If you are fine with constants, your macro is "good", otherwise it is b0rked.
Your macro does not convert integers to strings, it converts a literal into a string literal, which is something very different.
Literals are any plain numbers or definitions of values in your code. when you do int x = 10; the numeral 10 in an integer literal, while x is a variable and int is the type. const char* ten = "10"; also defines a literal, in this case a string literal, with value "10" and a variable called ten which points to the address where this literal is defined. What your macro actually does is change the way the literal is represented before any actual compilation goes on, from an integer literal into a string literal.
So, the actual change is being done before any compilation, just at source code level. Macros are not functions and cannot inspect memory, and your convertion would not work with variables. If you try:
int x = 10;
const char* ten = INTTOSTR(x);
You would be very puzzled to find that your variable ten would actually hold the value "x". That's because x is treated as a literal, and not as a variable.
If you want to see what's going on, I recommend asking your compiler to stop at preprocessing, and see the output before your code is acutally compiled. You can do this in GCC if you pass the -E flag.
PS. Regarding the apparent "success" with conversion of float values, it just comes to show the danger of macros: they are not type-safe. It does not look at 53.5 as a float, but as a token represented by characters 5, 3, . and 5 in the source code.

Different behavior in visual c++ versus gcc/clang while stringifying parameter which contains comma

I'm using stringizing operator to convert parameter which may contains comma passed to a macro into string. As I know, some characters cannot be stringified – notably, the comma(,) because it is used to delimit parameters and the right parenthesis()) because it marks the end of the parameter. So I use a variadic macro to pass commas to the stringizing operator like this:
#include <stdio.h>
#define TEST 10, 20
#define MAKE_STRING(...) #__VA_ARGS__
#define STRING(x) MAKE_STRING(x)
int main()
{
printf("%s\n", STRING(TEST) );
return 0;
}
it works fine. But it occurs to me what would happen without variadic macro, so I modify the macro: #define MAKE_STRING(x) #x. It compiles fine unexpectedly in visual c++ 2008/2010, and output 10, 20 while gcc/clang give the compilation error as expected:
macro "MAKE_STRING" passed 2 arguments, but takes just 1
So my question: is the Visual c++ doing additional work or the behavior is undefined?
VS in general allows extra parameters in macros and then just drops them silently:
STRING(10, 20, 30) - still works and prints 10. This is not the case here, but it pretty much means VS don't even have the error gcc threw at you.
It's not any additional work but "merely" a difference in substitution order.
I am not sure if this will answer your question but i hope this will help you solving your problem. When defining a string constant in C, you should include it in double quotes (for spaces). Also, the # macro wrap the variable name inside double quotes so, for example, #a become "a".
#include <stdio.h>
#define TEST "hello, world"
#define MAKE_STRING(x) #x
int main()
{
int a;
printf("%s\n", TEST);
printf("%s\n", MAKE_STRING(a));
return 0;
}
I compiled this code using gcc 4.7.1 and the output is:
hello, world
a
I dunno why this has upvotes, or an answer got downvoted (so the poster deleted it) but I don't know what you expect!
#__VA_ARGS__ makes no sense, suppose I have MACRO(a,b,c) do you want "a,b,c" as the string?
http://gcc.gnu.org/onlinedocs/cpp/Variadic-Macros.html#Variadic-Macros
Read, that became standard behaviour, variable length arguments in macros allow what they do in variable length arguments to functions. The pre-processor operates on text!
The only special case involving # is ##, which deletes a comma before the ## if there are no extra arguments (thus preventing a syntax error)
NOTE:
It is really important you read the MACRO(a,b,c) part and what do you expect, a string "a,b,c"? or "a, b, c" if you want the string "a, b, c" WRITE THE STRING "a, b, c"
Using the # operator is great for stuff like
#define REGISTER_THING(THING) core_of_program.register_thing(THING); printf("%s registered\n",#THING);

How to make string or char constants with macro expansion using ## operator

I am trying to do the following:
#define mkstr(str) #str
#define cat(x,y) mkstr(x ## y)
int main()
{
puts(cat(\,n));
puts(cat(\,t))
return 0;
}
both of the puts statements cause error. As \n and n both are preprocessor tokens I expected output them correctly in those puts statements, but Bloodshed/DevC++ compiler giving me the following error:
24:1 G:\BIN\cLang\macro2.cpp pasting "\" and "n" does not give a valid preprocessing token
Where is the fact I'm missing?
The preprocessor uses a tokenizer which will require C-ish input. So even when stringifying you cannot pass random garbage to a macro. ==> Don't make your preprocessor sad - it will eat kittens if you do so too often.
Actually, there is no way to create "\n" via compile-time concatenation since "\\" "n" is a string consisting of the two literals, i.e. "\n".

Stringizing operator

How does the following code compile correctly,
#include <stdio.h>
#define stringer( x ) printf_s( #x "\n" )
int main() {
stringer( "In quotes when printed to the screen" );
}
isn't it supposed to get expanded into
printf_s(""In quotes when printed to the screen""\n");
which is an error as there are nested double quotes in printf_s??
No, the # operator handles character string literals specially. It must \ escape each " in a character string literal that is passed to it. The correct expansion is:
printf_s( "\"In quotes when printed to the screen\"" "\n" );
No, it's expanded into
printf_s("\"In quotes when printed to the screen\"" "\n");
which will finally be
printf_s("\"In quotes when printed to the screen\"\n");
and should print
"In quotes when printed to the screen"
In C, adjacent string literals are concatenated:
Adjacent string literals are concatenated at compile time; this allows long strings to be split over multiple lines, and also allows string literals resulting from C preprocessor defines and macros to be appended to strings at compile time:

Resources