3

The below code should output 100 to my knowledge of stringification. vstr(s) should be expanded with value of 100 then str(s) gets 100 and it should return the string "100". But, it outputs "a" instead. What is the reason? But, if I call with macro defined constant foo then it output "100". Why?

#include<stdio.h>
#define vstr(s) str(s)
#define str(s) #s
#define foo 100
int main()
{
    int a = 100;
    puts(vstr(a));
    puts(vstr(foo));
    return 0;
}
chux - Reinstate Monica
  • 143,097
  • 13
  • 135
  • 256
amin__
  • 1,018
  • 3
  • 15
  • 22
  • 1
    Do you know about the separate stages of compilation in C? (Preprocessing, compiling, linking; some people put assembling in there as well) – user253751 Nov 16 '15 at 06:19
  • 1
    For C code, to convert an `int` at *runtime* into a string, use [snprintf](http://man7.org/linux/man-pages/man3/snprintf.3.html). For C++11 code, use `std::to_string` – Basile Starynkevitch Nov 16 '15 at 06:25
  • I am actually working on behavior of # in macro definition, not on converting int into string. I found the behavior varies in case of a macro constant and normal variable. – amin__ Nov 16 '15 at 06:28
  • Check the answers in this thread: https://stackoverflow.com/questions/16989730/stringification-how-does-it-work – Hari Apr 27 '22 at 11:37

5 Answers5

7

The reason is that preprocessors operate on tokens passed into them, not on values associated with those tokens.

#include <stdio.h>

#define vstr(s) str(s)
#define str(s) #s

int main()
{
    puts(vstr(10+10));
    return 0;
}

Outputs: 10+10

user3427419
  • 1,769
  • 11
  • 15
6

The # stringizing operator is part of the preprocessor. It's evaluated at compile time. It can't get the value of a variable at execution time, then somehow magically convert that to something it could have known at compile time.

If you want to convert an execution-time variable into a string at execution time, you need to use a function like std::to_string.

Jerry Coffin
  • 476,176
  • 80
  • 629
  • 1,111
4

Since vstr is preprocessed, the line

puts(vstr(a));

is translated as:

puts("a");

The value of the variable a plays no role in that line. You can remove the line

int a = 100;

and the program will behave identically.

R Sahu
  • 204,454
  • 14
  • 159
  • 270
2

Stringification is the process of transforming something into a string. What your macro stringifies ?

Actually the name of the variable itself, this is done at compilation-time.

If you want to stringify and then print the value of the variable at execution-time, then you must used something like printf("%\n",v); in C or cout << v << endl; in C++.

Jean-Baptiste Yunès
  • 34,548
  • 4
  • 48
  • 69
2

A preprocessor macro is not the same thing as a function, it does not expand the arguments at runtime and sees the value, but rather processes it at preprocessing stage (which is before compilation, so it doesn't even know the variables dependency).

In this case, you've passed the macro a to stringify, which it did. The preprocessor doesn't care a is also the name of a variable.

Leeor
  • 19,260
  • 5
  • 56
  • 87