Advertisement

Use defines in string? (c/c++)

Started by June 12, 2019 07:24 PM
10 comments, last by Bregma 5 years, 6 months ago

Hi!

Why cannot i do this? (and any way to do it?)


#define MY_VAL  5
someFunc("the value is MY_VAL");

I thought defines were replaced when compiling exactly as they are written. So why cannot the parameter of the function (char *) interpret this as "the value is 5"?

I also use the MY_VAL as an number such as:


int val = MY_VAL;

 

Macros aren't expanded inside string literals. If they were, how would you write the text string "MY_VAL"?

You might find some good results if you search for string interpolation.

Hello to all my stalkers.

Advertisement

2 suggestions, and correct me if i'm wrong:

 

C++-way:

std::ostringstream s;

s << "The value is " << YOUR_VAL;

void someFunc( s.str() ); // assuming someFunc expects an std::string

 

C way needs a little more dedication. A possible roadmap:

- char everything[50] = "The value is ";

- convert YOUR_VAL to char array (possibly via sprintf or sprintf_s ?).

- concatenate that array with everything (strcat or strcat_s ?).

- check documentation if it appends '\0'. I think it does ... if not append '\0'

 

Yea, strings are not the strengths of C ?

 

And don't forget the C preprocessor stringify and glue:

https://gcc.gnu.org/onlinedocs/gcc-4.8.5/cpp/Stringification.html


#define VALUE 123
#define XSTR(s) STR(s)
#define STR(s) #s

int main() {
	cout << ("value=" XSTR(VALUE)) << endl;
	return 0;
}

 

Nowadays you would prefer a constexpr anyway, unless you were doing some macro trickery. Defines are not really part of your program.

The reason why the C preprocessor does not substitute macros into strings is because preprocessor macro expansion takes place after after tokenization.  The entire string literal is a single token.  The macro name is a single token.  The preprocessor works at the token level, not as a simple text replacement processor.

This is spelled out explicitly in the ISO C standard.

Stephen M. Webb
Professional Free Software Developer

Advertisement

I might be wrong but I rember that I have read that something like this
 


const char* str = "Hello"
" "
"World";

Is concatenated anyways because the compiler will strip those character tokens following another character token and instead add the contents to the first one in the row

Yep, that's syntactically valid C code but not ISO C++ according to gcc (though it may compile with a warning).

But OP wants to concatenate a char array and an integer and hasn't quite specified if he wants to do so in C or C++. Imo it is important to point out that these languages handle this (strings and arrays) different.

 

1 hour ago, Green_Baron said:

Yep, that's syntactically valid C code but not ISO C++ according to gcc (though it may compile with a warning). 

It's been valid ISO C++ since at least 1997. GCC supported string literal concatenation long before that.

Stephen M. Webb
Professional Free Software Developer

You are right.

When compiling

char * str{ "Hello" " " "world\n" };

with -Wall -std=c++17, i got

../src/testmain.cpp:78:36: warning: ISO C++ forbids converting a string constant to ‘char*’ [-Wwrite-strings]

But this is not a string conversion warning but a qualifier warning, right ?

Good to be forced to think twice ...

This topic is closed to new replies.

Advertisement