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.
Related
ATOMIC_JOIN(prefix, detail_platform) is an macro which will output some string as follows:
base/atomic/gcc_gnu_x64
in another macro ATOMIC_DETAIL_HEADER, which output expected to be:
"base/atomic/gcc_gnu_x64.hpp" // notice: double quotes included in the output
I try to write the ATOMIC_DETAIL_HEADER, such as:
#define ATOMIC_DETAIL_HEADER(prefix) "ATOMIC_JOIN(prefix, ATOMIC_DETAIL_PLATFORM).hpp"
#define ATOMIC_DETAIL_HEADER(prefix) \"ATOMIC_JOIN(prefix, ATOMIC_DETAIL_PLATFORM).hpp\"
#define ATOMIC_DETAIL_HEADER(prefix) "##ATOMIC_JOIN(prefix, ATOMIC_DETAIL_PLATFORM).hpp##"
... failed!
but if i hope output is:
<base/atomic/gcc_gnu_x64.hpp>
The follow macro define can do right thing:
#define ATOMIC_DETAIL_HEADER(prefix) <ATOMIC_JOIN(prefix, ATOMIC_DETAIL_PLATFORM).hpp>
A cpp macro cannot build strings this way. It can join tokens to form new tokens, but at every stage it must be a valid token. Your example with angle-brackets works because the bracket characters are distinct tokens whereas the double-quotes cannot exist floating-off like that, and you cannot apply ## to it.
In most contexts, the compiler will concatenate adjacent string literals, so it may be sufficient to #stringify each piece at let the compiler do that.
While luser droog correctly stated why your use of quotes didn't work, he didn't show exactly how the goal can be accomplished. Indeed the # operator replaces a parameter by a string literal, i. e. puts quotation marks around the argument. This is slightly complicated by the fact that your token sequence has to be expanded first, so an additional level of macro substitution is needed:
#define QUOTED(a) #a
#define QUOTE(a) QUOTED(a)
#define ATOMIC_DETAIL_HEADER(prefix) QUOTE(ATOMIC_JOIN(prefix, ATOMIC_DETAIL_PLATFORM).hpp)
C seems to be pretty permissive when it comes to whitespace.
We can use or omit whitespace around an operator, between a function name and its parenthesized list of arguments, between an array name and its index, etc. in order to make code more readable. I understand this is a matter of preference.
The only place I can think of where whitespace is NOT allowed is this:
#include < stdio.h > // fatal error: stdio.h : No such file or directory
What are the other contexts in C where whitespace cannot be used for readability?
In most cases, adding whitespace within a single token either makes the program invalid or changes the meaning of the token. An obvious example: "foo" and " foo " are both valid string literals with different values, because a string literal is a single token. Changing 123456 to 123 456 changes it from a single integer constant to two integer constants, resulting in a syntax error.
The exceptions to this involve the preprocessor.
You've already mentioned the #include directive. Note that given:
#include "header.h"
the "header.h" is not syntactically a string literal; it's processed before string literals are meaningful. The syntax is similar, but for example a \t sequence in a header name isn't necessarily replaced by a tab character.
Newlines (which are a form of whitespace) are significant in preprocessor directives; you can't legally write:
#ifdef
FOO
/* ... */
#endif
But whitespace other than newlines is permitted:
# if SPACES_ARE_ALLOWED_HERE
#endif
And there's one case I can think of where whitespace is permitted between preprocessor tokens but it changes the meaning. In the definition of a function-like macro, the ( that introduces the parameter list must immediately follow the macro name. This:
#define TWICE(x) ((x) + (x))
defines TWICE as a function-like macro that takes one argument. But this:
#define NOT_TWICE (x) ((x) + (x))
defines NOT_TWICE as an ordinary macro with no arguments that expands to (x) ((x) + (x)).
This rule applies only to macro definitions; a macro invocation follows the normal rules, so you can write either TWICE(42) or TWICE ( 42 ).
White spaces are not allowed for readability (are significant) within a lexical token. I.e. within an identifier (foo bar is different from foobar), within a number (123 456 is different from 123456), within a string (that's your example basically) or within an operator (+ + is different from ++ and + = is different from +=). Between those you can add as much white space as you want, but when you add white space inside such a token you will break the lexical token into two separate tokens (or change the value in case of string constants), thus changing the meaning of your code .
In most cases the code with the added white space is either equivalent to the original code or results in a syntax error. But there are exceptions. For example:
return a +++ b;
is the same as
return a ++ + b;
but is different from:
return a + ++ b;
As I recall you need to be very careful with function-like macros, as in such dummy example:
#include <stdio.h>
#define sum(x, y) ((x)+(y))
int main(void)
{
printf("%d\n", sum(2, 2));
return 0;
}
the:
#define sum(x, y) ((x)+(y))
is different thing than say:
#define sum (x, y) ((x)+(y))
The latter one is object-like macro, that replaces exactly with (x, y) ((x)+(y)), that is parameters are not being subsituted (as it happens in function-like macro).
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.
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);
Is it possible to define a macro off of the content of a macro?
For example:
#define SET(key,value) #define key value
SET(myKey,"value")
int main(){
char str[] = myKey;
printf("%s",str);
}
would result in
int main(){
char str[] = "value";
printf("%s",str);
}
after being preprocessed.
Why would I do this? Because I'm curious ;)
No, its not possible to define a macro within another macro.
The preprocessor only iterates once before the compiler. What you're suggesting would require an undetermined amount of iterations.
No you can't - # in a replacment list of a macro means QUOTE NEXT TOKEN. It's more of a spelling issue, than any logical puzzle :)
(If you require this kind of solution in your code, than there are ways and tricks of using macro's, but you need to be specific about the use cases you need - as your example can be achieved by defining: #define mykey "value")
Here it is from the ansi C99 standard
6.10.3.2 The # operator
Constraints
1 Each # preprocessing token in the replacement list for a
function-like macro shall be followed by a parameter as the next
preprocessing token in the replacement list. Semantics 2 If, in the
replacement list, a parameter is immediately preceded by a #
preprocessing token, both are replaced by a single character string
literal preprocessing token that contains the spelling of the
preprocessing token sequence for the corresponding argument. Each
occurrence of white space between the argument’s preprocessing tokens
becomes a single space character in the character string literal.
White space before the first preprocessing token and after the last
preprocessing token composing the argument is deleted. Otherwise, the
original spelling of each preprocessing token in the argument is
retained in the character string literal, except for special handling
for producing the spelling of string literals and character constants:
a \ character is inserted before each " and \ character of a character
constant or string literal (including the delimiting " characters),
except that it is implementation-defined whether a \ character is
inserted before the \ character beginning a universal character name.
If the replacement that results is not a valid character string
literal, the behavior is undefined. The character string literal
corresponding to an empty argument is "". The order of evaluation of #
and ## operators is unspecified.
Macros are a simple text substitution. Generating new preprocessor directives from a macro would require the preprocessor to continue preprocessing from the beginning of the substitution. However, the standard defined preprocessing to continue behind the substitution.
This makes sense from a streaming point of view, viewing the unprocessed code as the input stream and the processed (and substituted) code as the output stream. Macro substitutions can have an arbitrary length, which means for the preprocessing from the beginning that an arbitrary number of characters must be inserted at the beginning of the input stream to be processed again.
When the processing continues behind the substitution, then the input simply is handled in one single run without any insertion or buffering, because everything directly goes to the output.
whilst it is not possible to use a macro to define another macro, depending on what you are seeking to achieve, you can use macros to effectively achieve the same thing by having them define constants. for example, i have an extensive library of c macros i use to define objective C constant strings and key values.
here are some snippets of code from some of my headers.
// use defineStringsIn_X_File to define a NSString constant to a literal value.
// usage (direct) : defineStringsIn_X_File(constname,value);
#define defineStringsIn_h_File(constname,value) extern NSString * const constname;
#define defineStringsIn_m_File(constname,value) NSString * const constname = value;
// use defineKeysIn_X_File when the value is the same as the key.
// eg myKeyname has the value #"myKeyname"
// usage (direct) : defineKeysIn_X_File(keyname);
// usage (indirect) : myKeyDefiner(defineKeysIn_X_File);
#define defineKeysIn_h_File(key) defineStringsIn_h_File(key,key)
#define defineKeysIn_m_File(key) defineStringsIn_m_File(key,##key)
// use defineKeyValuesIn_X_File when the value is completely unrelated to the key - ie you supply a quoted value.
// eg myKeyname has the value #"keyvalue"
// usage: defineKeyValuesIn_X_File(keyname,#"keyvalue");
// usage (indirect) : myKeyDefiner(defineKeyValuesIn_X_File);
#define defineKeyValuesIn_h_File(key,value) defineStringsIn_h_File(key,value)
#define defineKeyValuesIn_m_File(key,value) defineStringsIn_m_File(key,value)
// use definePrefixedKeys_in_X_File when the last part of the keyname is the same as the value.
// eg myPrefixed_keyname has the value #"keyname"
// usage (direct) : definePrefixedKeys_in_X_File(prefix_,keyname);
// usage (indirect) : myKeyDefiner(definePrefixedKeys_in_X_File);
#define definePrefixedKeys_in_h_File_2(prefix,key) defineKeyValuesIn_h_File(prefix##key,##key)
#define definePrefixedKeys_in_m_File_2(prefix,key) defineKeyValuesIn_m_File(prefix##key,##key)
#define definePrefixedKeys_in_h_File_3(prefix,key,NSObject) definePrefixedKeys_in_h_File_2(prefix,key)
#define definePrefixedKeys_in_m_File_3(prefix,key,NSObject) definePrefixedKeys_in_m_File_2(prefix,key)
#define definePrefixedKeys_in_h_File(...) VARARG(definePrefixedKeys_in_h_File_, __VA_ARGS__)
#define definePrefixedKeys_in_m_File(...) VARARG(definePrefixedKeys_in_m_File_, __VA_ARGS__)
// use definePrefixedKeyValues_in_X_File when the value has no relation to the keyname, but the keyname has a common prefixe
// eg myPrefixed_keyname has the value #"bollocks"
// usage: definePrefixedKeyValues_in_X_File(prefix_,keyname,#"bollocks");
// usage (indirect) : myKeyDefiner(definePrefixedKeyValues_in_X_File);
#define definePrefixedKeyValues_in_h_File(prefix,key,value) defineKeyValuesIn_h_File(prefix##key,value)
#define definePrefixedKeyValues_in_m_File(prefix,key,value) defineKeyValuesIn_m_File(prefix##key,value)
#define VA_NARGS_IMPL(_1, _2, _3, _4, _5, _6, _7, _8, _9, _10, _11, _12, N, ...) N
#define VA_NARGS(...) VA_NARGS_IMPL(X,##__VA_ARGS__, 11, 10,9, 8, 7, 6, 5, 4, 3, 2, 1, 0)
#define VARARG_IMPL2(base, count, ...) base##count(__VA_ARGS__)
#define VARARG_IMPL(base, count, ...) VARARG_IMPL2(base, count, __VA_ARGS__)
#define VARARG(base, ...) VARARG_IMPL(base, VA_NARGS(__VA_ARGS__), __VA_ARGS__)
and a usage example that invokes it:
#define sw_Logging_defineKeys(defineKeyValue) \
/** start of key list for sw_Logging_ **/\
/**/defineKeyValue(sw_Logging_,log)\
/**/defineKeyValue(sw_Logging_,time)\
/**/defineKeyValue(sw_Logging_,message)\
/**/defineKeyValue(sw_Logging_,object)\
/**/defineKeyValue(sw_Logging_,findCallStack)\
/**/defineKeyValue(sw_Logging_,debugging)\
/**/defineKeyValue(sw_Logging_,callStackSymbols)\
/**/defineKeyValue(sw_Logging_,callStackReturnAddresses)\
/** end of key list for sw_Logging_ **/
sw_Logging_defineKeys(definePrefixedKeys_in_h_File);
the last part may be a little difficult to get your head around.
the sw_Logging_defineKeys() macro defines a list that takes the name of a macro as it's parameter (defineKeyValue) this is then used to invoke the macro that does the actual definition process. ie, for each item in the list, the macro name passed in is used to define the context ( "header", or "implementation", eg either "h" or "m" file, if you understand the objective c file extensions) whilst this is used for objective c, it is simply plain old c macros, used for a "higher purpose" than possibly Kernighan and Richie ever envisaged. :-)