How include #defined constants in Serial.print or Serial.println?

Hello, is it possible to include constants (defined with #define) in the Serial.print or Serial.println function? If so, how would this be done?

I was looking at "stringification" in C++, and it seems to indicate you can include the defined constant name prepended with a # (hash) symbol as in the following example: (https://gcc.gnu.org/onlinedocs/cpp/Stringification.html)

#define WARN_IF(EXP) \
     do { if (EXP) \
             fprintf (stderr, "Warning: " #EXP "\n"); } \
     while (0)
     WARN_IF (x == 0);
          ==> do { if (x == 0)
                fprintf (stderr, "Warning: " "x == 0" "\n"); } while (0);

But when I try to include the constant in this way, the Arduino compiler complains of stray # symbol.

For example:

#define THEVALUE hello123
Serial.println("This is the value: " #THEVALUE);

But the compiler doesn't replace the value within strings, so this doesn't work either:

#define THEVALUE hello123
Serial.println("This is the value: #THEVALUE");

Thanks for any insight!

The stringification only works in Macros.

You could write another macro that stringifies what it gets.

#define SOME_CONSTANT 3

#define STRINGIFY_ME(x) #x

Then:

Serial.print(STRINGIFY_ME(SOME_CONSTANT));

would print "SOME_CONSTANT"

Fist of all, why not make it a normal C++ constant?

const char TheValue[] = "hello123";

Serial.println(TheValue);

If you really want it from a preprocessor define, you can do

#define MYVALUE "hello123"

Serial.println(MYVALUE);

Or if it’s really a problem to make the #define as a string you can use the double define trick:

#define THEVALUE hello123

#define STRINGIFY(x) #x
#define TOSTRING(x) STRINGIFY(x)

Serial.println(TOSTRING(THEVALUE));

Why do you need two defines to do that? I've never understood that.

STRINGIFY(THEVALUE) expands to "THEVALUE"

TOSTRING(THEVALUE) expands to STRINGIFY(hello123) which expands to "hello123"

These work except in my use-case where the defined value includes commas (it’s an array).
(I’m using this to define the IP address for the ethernet module, and since Ethernet.begin requires a byte array for the IP address, I’m defining the IP as #define IP_ADDRESS 192,168,1,100.

Then I want to display it on the serial console so I don’t have to depend on a piece of paper taped to the outside of the unit to keep track of the IP address.

For example, this fails:

#define MYVAL 123,456
#define st(a) #a
#define xst(a) st(a)

Serial.print(xst(MYVAL));

Yields an error: the macro expected 1 parameter but got 2

#define MYVAL (123,456)
#define st(a) #a
#define xst(a) st(a)

void setup()
{
  Serial.begin(115200);
  Serial.print(xst(MYVAL));
}

void loop()
{
}

Prints (123,456). The parens may, or may not, be a problem.