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;
}
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
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.
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.
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++.
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.
Related
I want to generate several pieces of code for several different values using the C++ preprocessor. I entered all of these values into a table generation macro. However, some parts of the code only have to be generated for certain (disjunct) subsets of the values. Hence, I would like to have small table generation macros and then merge them together into a large one (for the code that has to be generated for all of them). This part works flawlessly so far.
However, I require to use a comma as a seperator for some parts of the code (precisely to generate an enum). Unfortunately, this comma is replaced too early (i.e. before the function call of the macro is replaced). Here comes an example which should illustrate my problem:
#include <iostream>
#define A(F, SEP) F(one) SEP F(two)
#define B(F, SEP) F(three) SEP F(four)
#define C(F, SEP) A(F, SEP) SEP B(F, SEP)
#define SOME_F(x) x
#define SOME_SEP ,
enum {C(SOME_F, SOME_SEP)} ENUM;
int main()
{
#define ANOTHER_F(x) std::cout << #x << std::endl;
#define ANOTHER_SEP
A(ANOTHER_F, ANOTHER_SEP)
return 0;
}
Here I want to generate an enum containing all values (it's unused in the example but in my actual code I require it) and print all values of the subset A. If I try to compile this example, it fails with the error error: macro "A" passed 3 arguments, but takes just 2 (same message for B). The reason for this seems to be, that the SOME_SEP macro is replaced before A is substituted (and an attempt to use A(F, ,) is made).
A rather simple (but ugly) fix for this is to replace the SEP argument to be a function-like instead of an object-like macro (one has to add parentheses to each call though). However, I would like to solve this using an object-like macro. During my web search I discovered a lot of people with a similar problem, but they wanted to pass a template-type (and hence can resolve the issue by using braces (which doesn't work for the comma as a seperator)).
Just use brackets and then remove them.
#include <iostream>
#define EXP(...) __VA_ARGS__
#define A(F, SEP) F(one) EXP SEP F(two)
#define B(F, SEP) F(three) EXP SEP F(four)
#define C(F, SEP) A(F, SEP) EXP SEP B(F, SEP)
#define SOME_F(x) x
enum {C(SOME_F, (,))} ENUM;
int main() {
#define ANOTHER_F(x) std::cout << #x << std::endl;
A(ANOTHER_F, ())
}
Overall, this is odd usage and looks odd. Consider using BOOST_PP_SEQ_FOR_EACH and similar FOREACH_* macros. It's odd to define list of elements inside a macro to iterate over - I would expect it to be defined outside and passed as parameter. Like:
#define LIST1 (one)(two)
#define CALLBACK(x) x
SUPER_FOREACH(LIST1, CALLBACK, (,))
Also see How to convert an enum type variable to a string? if you want to stringify an enum.
Is it possible to concatenate quoted string literals outside of the language (C++, in this case)?
That is, can I define MY_MACRO(a,b,c) and use it thus:
MY_MACRO("one", "two", "three")
and have it expand to: "onetwothree"?
The use case is to apply an attribute and its message to, say, a function signature, like so:
MY_ATTRIBUTE_MACRO("this", "is", "the reason") int foo() { return 99; }
and it would result in:
[[nodiscard("thisisthe reason")]] int foo() { return 99; }
The language already does string concatenation!
This:
"hi" "James"
becomes just one string literal.
That means you do not need any preprocessor tricks for this at all.
You need only employ this in the output of your macro:
#define MY_ATTRIBUTE_MACRO(x,y,z) [[nodiscard(x y z)]]
Now this:
MY_ATTRIBUTE_MACRO("this", "is", "the reason") int foo() { return 99; }
is this:
[[nodiscard("this" "is" "the reason")]] int foo() { return 99; }
which is actually already what you wanted, because of the implicit string concatenation (which happens after macro expansion):
[[nodiscard("thisisthe reason")]] int foo() { return 99; }
Translation phase 4:
[lex.phases]/4: Preprocessing directives are executed, macro invocations are expanded, and _Pragma unary operator expressions are executed. If a character sequence that matches the syntax of a universal-character-name is produced by token concatenation, the behavior is undefined. A #include preprocessing directive causes the named header or source file to be processed from phase 1 through phase 4, recursively. All preprocessing directives are then deleted.
Translation phase 6:
[lex.phases]/6: Adjacent string literal tokens are concatenated.
I'm not sure what you mean by "outside the language" but, in C++, any string literals separated just by whitespace are implicitly concatenated into one. Thus, your MY_MACRO definition is actually very simple:
#include <iostream>
#define MY_MACRO(a, b, c) a b c
int main()
{
std::cout << MY_MACRO("one", "two", "three") << std::endl;
return 0;
}
The output from this short program is what you asked for: onetwothree.
Note: As a matter of curiosity/interest, it is normally recommended to enclose macro arguments in parentheses, in the definition part, so as to avoid unwanted side effects of the evaluation. However, in this case, using such parentheses won't work, and breaks the implicit concatenation:
#define MY_MACRO(a, b, c) (a) (b) (c) // Broken!
I have the following defines:
#define STRING_OBJECT_1 "bird"
#define STRING_OBJECT_2 "dog"
#define STRING_OBJECT_3 "cat"
#define STRING_OBJECT_4 "human"
#define STRING_OBJECT_5 "cow"
#define STRING_OBJECT_6 "snake"
#define STRING_OBJECT_7 "penguin"
#define STRING_OBJECT_8 "monkey"
I want to get numbered STRING_OBJECT only using STRING_OBJECT_ + "(number string)", so basically not directly type STRING_OBJECT_1.
Is there anyway to use for loop with string macro in C++?
Is there anyway to use for loop with string macro in C++?
No, there isn't.
Macros are processed before source code is compiled to create object code.
The values of variables in a for loop are set at run time. Hence, they cannot make use of macros.
Your best bet is to augment your code with an array variable and use the array variable in the for loop.
#define STRING_OBJECT_1 "bird"
...
#define STRING_OBJECT_8 "monkey"
std::string object_array[] = {STRING_OBJECT_1, ..., STRING_OBJECT_8};
for ( int i = 0; ... )
{
do_something(object_array[i]);
}
No, You can't do this. macros not part of the C/C++ language.
Macros are replaced by the preprocessor by their value compiles time. There is no way you had be able to change the macro at runtime.
So, it's been a while since I have written anything in C++ and now I'm working on a project using C++11 and macros.
I know that by using the stringify operator I can do this:
#define TEXT(a) #a //expands to "a"
How am I supposed to use the preprocessor for recognizing the tokens like + and * to do this:
#define TEXT(a)+ ??? //want to expand to "a+"
#define TEXT(a)* ??? //want to expand to "a*"
when the input has to be in that syntax?
I have tried doing that:
#define + "+"
but of course it doesn't work. How can I make the preprocessor recognize those tokens?
NOTE:
This is actually part of a project for a small language that defines and uses regular expressions, where the resulting string of the macros is to be used in a regex. The syntax is given and we have to use it as it is without making any changes to it.
eg
TEXT(a)+ is to be used to make the regular expression: std::regex("a+")
without changing the fact that TEXT(a) expands to "a"
First,
#define TEXT(a) #a
doesn't “convert to "a"”. a is just a name for a parameter. The macro expands to a string that contains whatever TEXT was called with. So TEXT(42 + rand()) will expand to "42 + rand()". Note that, if you pass a macro as parameter, the macro will not be expanded. TEXT(EXIT_SUCCESS) will expand to "EXIT_SUCCESS", not "0". If you want full expansion, add an additional layer of indirection and pass the argument to TEXT to another macro TEXT_R that does the stringification.
#define TEXT_R(STUFF) # STUFF
#define TEXT(STUFF) TEXT_R(STUFF)
Second, I'm not quite sure what you mean with TEXT(a)+ and TEXT(a)*. Do you want, say, TEXT(foo) to expand to "foo+"? I think the simplest solution in this case would be to use the implicit string literal concatenation.
#define TEXT_PLUS(STUFF) # STUFF "+"
#define TEXT_STAR(STUFF) # STUFF "*"
Or, if you want full expansion.
#define TEXT_R(STUFF) # STUFF
#define TEXT_PLUS(STUFF) TEXT_R(STUFF+)
#define TEXT_STAR(STUFF) TEXT_R(STUFF*)
Your assignment is impossible to solve in C++. You either misunderstood something or there’s an error in the project specification. At any rate, we’ve got a problem here:
TEXT(a)+ is to be used to make the regular expression: std::regex("a+") without changing the fact that TEXT(a) expands to "a" [my emphasis]
TEXT(a) expands to "a" — meaning, we can just replace TEXT(a) everywhere in your example; after all, that’s exactly what the preprocessor does. In other words, you want the compiler to transform this C++ code
"a"+
into
std::regex("a+")
And that’s simply impossible, because the C++ preprocess does not allow expanding the + token.
The best we can do in C++ is use operator overloading to generate the desired code. However, there are two obstacles:
You can only overload operators on custom types, and "a" isn’t a custom type; its type is char const[2] (why 2? Null termination!).
Postfix-+ is not a valid C++ operator and cannot be overloaded.
If your assignment had just been a little different, it would work. In fact, if your assignment had said that TEXT(a)++ should produce the desired result, and that you are allowed to change the definition of TEXT to output something other than "a", then we’d be in business:
#include <string>
#include <regex>
#define TEXT(a) my_regex_token(#a)
struct my_regex_token {
std::string value;
my_regex_token(std::string value) : value{value} {}
// Implicit conversion to `std::regex` — to be handled with care.
operator std::regex() const {
return std::regex{value};
}
// Operators
my_regex_token operator ++(int) const {
return my_regex_token{value + "+"};
}
// more operators …
};
int main() {
std::regex x = TEXT(a)++;
}
You don't want to jab characters onto the end of macros.
Maybe you simply want something like this:
#define TEXT(a, b) #a #b
that way TEXT(a, +) gets expanded to "a" "+" and TEXT(a, *) to "a" "*"
If you need that exact syntax, then use a helper macro, like:
#define TEXT(a) #a
#define ADDTEXT(x, y) TEXT(x ## y)
that way, ADDTEXT(a, +) gets expanded to "a+" and ADDTEXT(a, *) gets expanded to "a*"
You can do it this way too:
#define TEXT(a) "+" // "a" "+" -> "a+"
#define TEXT(a) "*" // "a" "*" -> "a*"
Two string literals in C/C++ will be joined into single literal by specification.
In the sake of debugging purposes, can I get the line number in C/C++ compilers?
(standard way or specific ways for certain compilers)
e.g
if(!Logical)
printf("Not logical value at line number %d \n",LineNumber);
// How to get LineNumber without writing it by my hand?(dynamic compilation)
You should use the preprocessor macro __LINE__ and __FILE__. They are predefined macros and part of the C/C++ standard. During preprocessing, they are replaced respectively by a constant string holding an integer representing the current line number and by the current file name.
Others preprocessor variables :
__func__ : function name (this is part of C99, not all C++ compilers support it)
__DATE__ : a string of form "Mmm dd yyyy"
__TIME__ : a string of form "hh:mm:ss"
Your code will be :
if(!Logical)
printf("Not logical value at line number %d in file %s\n", __LINE__, __FILE__);
As part of the C++ standard there exists some pre-defined macros that you can use. Section 16.8 of the C++ standard defines amongst other things, the __LINE__ macro.
__LINE__: The line number of the current source line (a decimal
constant).
__FILE__: The presumed name of the source file (a character string
literal).
__DATE__: The date of translation of the source file (a character string
literal...)
__TIME__: The time of translation of the source file (a character string
literal...)
__STDC__: Whether__STDC__ is predefined
__cplusplus: The name __cplusplus is defined to the value 199711L when
compiling a C ++ translation unit
So your code would be:
if(!Logical)
printf("Not logical value at line number %d \n",__LINE__);
You could use a macro with the same behavior as printf(),
except that it also includes debug information such as
function name, class, and line number:
#include <cstdio> //needed for printf
#define print(a, args...) printf("%s(%s:%d) " a, __func__,__FILE__, __LINE__, ##args)
#define println(a, args...) print(a "\n", ##args)
These macros should behave identically to printf(), while including java stacktrace-like information. Here's an example main:
void exampleMethod() {
println("printf() syntax: string = %s, int = %d", "foobar", 42);
}
int main(int argc, char** argv) {
print("Before exampleMethod()...\n");
exampleMethod();
println("Success!");
}
Which results in the following output:
main(main.cpp:11) Before exampleMethod()...
exampleMethod(main.cpp:7) printf() syntax: string = foobar, int = 42
main(main.cpp:13) Success!
C++20 offers a new way to achieve this by using std::source_location. This is currently accessible in gcc an clang as std::experimental::source_location with #include <experimental/source_location>.
The problem with macros like __LINE__ is that if you want to create for example a logging function that outputs the current line number along with a message, you always have to pass __LINE__ as a function argument, because it is expanded at the call site.
Something like this:
void log(const std::string msg) {
std::cout << __LINE__ << " " << msg << std::endl;
}
Will always output the line of the function declaration and not the line where log was actually called from.
On the other hand, with std::source_location you can write something like this:
#include <experimental/source_location>
using std::experimental::source_location;
void log(const std::string msg, const source_location loc = source_location::current())
{
std::cout << loc.line() << " " << msg << std::endl;
}
Here, loc is initialized with the line number pointing to the location where log was called.
You can try it online here.
Use __LINE__ (that's double-underscore LINE double-underscore), the preprocessor will replace it with the line number on which it is encountered.
Checkout __FILE__ and __LINE__ macros
Try __FILE__ and __LINE__.
You might also find __DATE__ and __TIME__ useful.
Though unless you have to debug a program on the clientside and thus need to log these informations you should use normal debugging.
For those who might need it, a "FILE_LINE" macro to easily print file and line:
#define STRINGIZING(x) #x
#define STR(x) STRINGIZING(x)
#define FILE_LINE __FILE__ ":" STR(__LINE__)
Since i'm also facing this problem now and i cannot add an answer to a different but also valid question asked here,
i'll provide an example solution for the problem of:
getting only the line number of where the function has been called in C++ using templates.
Background: in C++ one can use non-type integer values as a template argument. This is different than the typical usage of data types as template arguments.
So the idea is to use such integer values for a function call.
#include <iostream>
class Test{
public:
template<unsigned int L>
int test(){
std::cout << "the function has been called at line number: " << L << std::endl;
return 0;
}
int test(){ return this->test<0>(); }
};
int main(int argc, char **argv){
Test t;
t.test();
t.test<__LINE__>();
return 0;
}
Output:
the function has been called at line number: 0
the function has been called at line number: 16
One thing to mention here is that in C++11 Standard it's possible to give default template values for functions using template. In pre C++11 default values for non-type arguments seem to only work for class template arguments. Thus, in C++11, there would be no need to have duplicate function definitions as above. In C++11 its also valid to have const char* template arguments but its not possible to use them with literals like __FILE__ or __func__ as mentioned here.
So in the end if you're using C++ or C++11 this might be a very interesting alternative than using macro's to get the calling line.
Use __LINE__, but what is its type?
LINE The presumed line number (within the current source file) of the current source line (an integer constant).
As an integer constant, code can often assume the value is __LINE__ <= INT_MAX and so the type is int.
To print in C, printf() needs the matching specifier: "%d". This is a far lesser concern in C++ with cout.
Pedantic concern: If the line number exceeds INT_MAX1 (somewhat conceivable with 16-bit int), hopefully the compiler will produce a warning. Example:
format '%d' expects argument of type 'int', but argument 2 has type 'long int' [-Wformat=]
Alternatively, code could force wider types to forestall such warnings.
printf("Not logical value at line number %ld\n", (long) __LINE__);
//or
#include <stdint.h>
printf("Not logical value at line number %jd\n", INTMAX_C(__LINE__));
Avoid printf()
To avoid all integer limitations: stringify. Code could directly print without a printf() call: a nice thing to avoid in error handling2 .
#define xstr(a) str(a)
#define str(a) #a
fprintf(stderr, "Not logical value at line number %s\n", xstr(__LINE__));
fputs("Not logical value at line number " xstr(__LINE__) "\n", stderr);
1 Certainly poor programming practice to have such a large file, yet perhaps machine generated code may go high.
2 In debugging, sometimes code simply is not working as hoped. Calling complex functions like *printf() can itself incur issues vs. a simple fputs().