I've one string array char version[][8] = {"new", "old", "latest", "oldest", "ancient"};
and I've one macro
#define FS(file, attr) \
filesys(file, file_ ##attr## _ops) \
How could I pass members of version of string array into the FS macro ?
You cannot. Macros are compile time and the compiler will no be able to splice the strings the way you want. Instead, try using strcat(), just don't forget that you need to keep track of how large your string arrays are.
You cant use any C features in the macros as proprocessor does not know anything about the C and the C language.
Bear in mind that it is compile time token substitution.
Use normal functions instead
Related
I'm programming in Windows and MSVC. There are two ways to write a DEBUG_PRINT statement as I know of:
printf(__FUNCTION__": Error code: %x\n", ErrorCode);
printf("%s: Error code: %x\n", __FUNCTION__, ErrorCode);
Is it okay to concatenate predefined macro with strings like this? I don't know if predefined macro like __FUNCTION__ or __LINE__ is a legit string literal. And intuitively, seems like a dangerous way to treat strings like this in C.
And what's the difference between these two? As I used /FAcs compiler option to output the code snippet to assembly, I really can't see much of a difference.
First of all __FUNCTION__ is not in the C standard, you should probably use __func__ instead (except that microsoft has decided to skip support for that in their C compiler).
Second __FUNCTION__/__func__ "macro" is not really a macro (or at least not normally - microsoft's compiler seem to behave differently), it behaves more like a local variable and therefore it isn't a candidate for the string concatenation. You should use string formatting instead (since that will ensure that your code will become more portable).
The __LINE__ macro (is a macro), but it doesn't work well with string concatenation directly since it doesn't expand to a string - it expands to a number (which by the way can be useful in other cases). However you can use the preprocessor to stringify it (the XSTR macro will first expand it's argument and then stringify the result while STR will not expand the it's argument before stringifying it):
#define STR(x) # x
#define XSTR(x) STR(x)
printf("I'm on line #" XSTR(__LINE__));
The __FILE__ macro (which is also a macro) does expand to a string literal which plays well together with string concatenation directly.
The reason you don't see any difference is that the compiler knows what printf does and can use that for optimization. It would figure out that it doesn't need to rely on printf code to expand the %s at runtime since it can do it at compile time.
The former will concatenate the function name in __FUNCTION__ with the format string at compile-time. The second will format it into the output at runtime.
This assumes it's a pre-defined macro (it's not standard). MSVC has __FUNCTION__ as a proper string literal, GCC does not.
__LINE__ is supported by GCC, and expands to a decimal integer, i.e. not a string.
For performance reasons, I would suggest always using the first way when possible, i.e. when the two strings are compile-time constant. There will be a price to pay, as usual: the string pool will be larger, since each use of the macro creates a unique format string. For desktop-class systems, this is probably neglible.
The difference is that in the 1st case the string literal gets concatenated with the format string during the compiler translation phases, while in the second case, it gets read in during run-time. So the first method is much faster.
If you know that the macro is a pre-defined string literal, I don't see anything wrong with the code.
That being said, I have no idea what __FUNCTION__ is. There is a standard C macro __func__ but it is not a string literal and should be treated like a const char array.
__LINE__ is a standard C macro that gives the source file line as an integer.
Thanks for answering. Looks like the first way is a legit literal string concatenate, it just does it in build-time, and it's faster, just space consuming.
I think I'll stick in the first way. Thanks again.
I am trying to use a function-like macro to generate an object-like macro name (generically, a symbol). The following will not work because __func__ (C99 6.4.2.2-1) puts quotes around the function name.
#define MAKE_AN_IDENTIFIER(x) __func__##__##x
The desired result of calling MAKE_AN_IDENTIFIER(NULL_POINTER_PASSED) would be MyFunctionName__NULL_POINTER_PASSED. There may be other reasons this would not work (such as __func__ being taken literally and not interpreted, but I could fix that) but my question is what will provide a predefined macro like __func__ except without the quotes? I believe this is not possible within the C99 standard so valid answers could be references to other preprocessors.
Presently I have simply created my own object-like macro and redefined it manually before each function to be the function name. Obviously this is a poor and probably unacceptable practice. I am aware that I could take an existing cpp program or library and modify it to provide this functionality. I am hoping there is either a commonly used cpp replacement which provides this or a preprocessor library (prefer Python) which is designed for extensibility so as to allow me to 'configure' it to create the macro I need.
I wrote the above to try to provide a concise and well defined question but it is certainly the Y referred to by #Ruud. The X is...
I am trying to manage unique values for reporting errors in an embedded system. The values will be passed as a parameter to a(some) particular function(s). I have already written a Python program using pycparser to parse my code and identify all symbols being passed to the function(s) of interest. It generates a .h file of #defines maintaining the values of previously existing entries, commenting out removed entries (to avoid reusing the value and also allow for reintroduction with the same value), assigning new unique numbers for new identifiers, reporting malformed identifiers, and also reporting multiple use of any given identifier. This means that I can simply write:
void MyFunc(int * p)
{
if (p == NULL)
{
myErrorFunc(MYFUNC_NULL_POINTER_PASSED);
return;
}
// do something actually interesting here
}
and the Python program will create the #define MYFUNC_NULL_POINTER_PASSED 7 (or whatever next available number) for me with all the listed considerations. I have also written a set of macros that further simplify the above to:
#define FUNC MYFUNC
void MyFunc(int * p)
{
RETURN_ASSERT_NOT_NULL(p);
// do something actually interesting here
}
assuming I provide the #define FUNC. I want to use the function name since that will be constant throughout many changes (as opposed to LINE) and will be much easier for someone to transfer the value from the old generated #define to the new generated #define when the function itself is renamed. Honestly, I think the only reason I am trying to 'solve' this 'issue' is because I have to work in C rather than C++. At work we are writing fairly object oriented C and so there is a lot of NULL pointer checking and IsInitialized checking. I have two line functions that turn into 30 because of all these basic checks (these macros reduce those lines by a factor of five). While I do enjoy the challenge of crazy macro development, I much prefer to avoid them. That said, I dislike repeating myself and hiding the functional code in a pile of error checking even more than I dislike crazy macros.
If you prefer to take a stab at this issue, have at.
__FUNCTION__ used to compile to a string literal (I think in gcc 2.96), but it hasn't for many years. Now instead we have __func__, which compiles to a string array, and __FUNCTION__ is a deprecated alias for it. (The change was a bit painful.)
But in neither case was it possible to use this predefined macro to generate a valid C identifier (i.e. "remove the quotes").
But could you instead use the line number rather than function name as part of your identifier?
If so, the following would work. As an example, compiling the following 5-line source file:
#define CONCAT_TOKENS4(a,b,c,d) a##b##c##d
#define EXPAND_THEN_CONCAT4(a,b,c,d) CONCAT_TOKENS4(a,b,c,d)
#define MAKE_AN_IDENTIFIER(x) EXPAND_THEN_CONCAT4(line_,__LINE__,__,x)
static int MAKE_AN_IDENTIFIER(NULL_POINTER_PASSED);
will generate the warning:
foo.c:5: warning: 'line_5__NULL_POINTER_PASSED' defined but not used
As pointed out by others, there is no macro that returns the (unquoted) function name (mainly because the C preprocessor has insufficient syntactic knowledge to recognize functions). You would have to explicitly define such a macro yourself, as you already did yourself:
#define FUNC MYFUNC
To avoid having to do this manually, you could write your own preprocessor to add the macro definition automatically. A similar question is this: How to automatically insert pragmas in your program
If your source code has a consistent coding style (particularly indentation), then a simple line-based filter (sed, awk, perl) might do. In its most naive form: every function starts with a line that does not start with a hash or whitespace, and ends with a closing parenthesis or a comma. With awk:
{
print $0;
}
/^[^# \t].*[,\)][ \t]*$/ {
sub(/\(.*$/, "");
sub(/^.*[ \t]/, "");
print "#define FUNC " toupper($0);
}
For a more robust solution, you need a compiler framework like ROSE.
Gnu-C has a __FUNCTION__ macro, but sadly even that cannot be used in the way you are asking.
I'd like to shorten variable names, so instead of this :
FPData.Temps.T.Solar.Val
I'd like to use :
TEMP_Solar.Val
and define macro :
#define TEMP_ FPData.Temps.T.
But it works only if I put space in between :
TEMP_ Solar.Val
compiles ok, but I'd like to use this one
TEMP_Solar.Val
Possible? I know I could get around by using macro and arguments "TEMP_VAL(Solar)" but would like to keep it simple, linear concatenation...
It's because the preprocessor, which handles macros, only recognizes their own identifiers. When you use e.g. TEMP_Solar it's a different identifier from TEMP_.
The preprocessor might even use a simple strcmp to find its macros, so there can't be no sub-strings nor can there be differences in case.
The most obvious and easy solution:
#define TEMP FPData.Temps.T
TEMP.Solar.Val
(You cannot and should not change the actual variable names of the struct members.)
Ignoring that there are sometimes better non-macro ways to do this (I have good reasons, sadly), I need to write a big bunch of generic code using macros. Essentially a macro library that will generate a large number of functions for some pre-specified types.
To avoid breaking a large number of pre-existing unit tests, one of the things the library must do is, for every type, generate the name of that type in all caps for printing. E.g. a type "flag" must be printed as "FLAG".
I could just manually write out constants for each type, e.g.
#define flag_ALLCAPSNAME FLAG
but this is not ideal. I'd like to be able to do this programatically.
At present, I've hacked this together:
char capname_buf[BUFSIZ];
#define __MACRO_TO_UPPERCASE(arg) strcpy(capname_buf, arg); \
for(char *c=capname_buf;*c;c++)*c = (*c >= 'a' && *c <= 'z')? *c - 'a' + 'A': *c;
__MACRO_TO_UPPERCASE(#flag)
which does what I want to some extent (i.e. after this bit of code, capname_buf has "FLAG" as its contents), but I would prefer a solution that would allow me to define a string literal using macros instead, avoiding the need for this silly buffer.
I can't see how to do this, but perhaps I'm missing something obvious?
I have a variadic foreach loop macro written (like this one), but I can't mutate the contents of the string literal produced by #flag, and in any case, my loop macro would need a list of character pointers to iterate over (i.e. it iterates over lists, not over indices or the like).
Thoughts?
It is not possible in portable C99 to have a macro which converts a constant string to all uppercase letters (in particular because the notion of letter is related to character encoding. An UTF8 letter is not the same as an ASCII one).
However, you might consider some other solutions.
customize your editor to do that. For example, you could write some emacs code which would update each C source file as you require.
use some preprocessor on your C source code (perhaps a simple C code generator script which would emit a bunch of #define in some #include-d file).
use GCC extensions to have perhaps
#define TO_UPPERCASE_COUNTED(Str,Cnt)
#define TO_UPPERCASE(Str) TO_UPPERCASE_COUNTED(Str,__COUNT__) {( \
static char buf_##Cnt[sizeof(Str)+4]; \
char *str_##Cnt = Str; \
int ix_##Cnt = 0; \
for (; *str_##Cnt; str_##Cnt++, ix_##Cnt++) \
if (ix_##Cnt < sizeof(buf_##Cnt)-1) \
buf_##Cnt[ix_##Cnt] = toupper(*str_##Cnt); \
buf_##Cnt; )}
customize GCC, perhaps using MELT (a domain specific language to extend GCC), to provide your __builtin_capitalize_constant to do the job (edit: MELT is now an inactive project). Or code in C++ your own GCC plugin doing that (caveat, it will work with only one given GCC version).
It's not possible to do this entirely using the c preprocessor. The reason for this is that the preprocessor reads the input as (atomic) pp-tokens from which it composes the output. There's no construct for the preprocessor to decompose a pp-token into individual characters in any way (no one that would help you here anyway).
In your example when the preprocessor reads the string literal "flag" it's to the preprocessor basically an atomic chunk of text. It have constructs to conditionally remove such chunks or glue them together into larger chunks.
The only construct that allows you in some sense to decompose a pp-token is via some expressions. However these expressions only can work on arithmetic types which is why they won't help you here.
Your approach circumvents this problem by using C language constructs, ie you do the conversion at runtime. The only thing the preprocessor does then is to insert the C code to convert the string.
I want to fill a multidimensional array using a macro so that the people using it think that they are using a function and passing only one string. The macro will use this string and at compile time convert it so that it would appear as a multidimensional array, like this:
make_array ("string1,{string2,{string3,{...,{stringN");
So the macro will replace this function to a multidimensional array and cut that string wherever it encounters,{. The code above will turn in something like this:
make_array = { "string1", "string2", "string3", ..., "stringN"};
I'm using GCC; how can I accomplish this?
Update: I thought I could exclude the quotes of the string using a macro, so I would have a string without a text and I could edit the string in macro but GCC does not accept the declaration of a macro to replace double quotes (like shown below).
#define macro_array ( "text") text
So the text will appear without double quotes and I could find the ,{ mark and cut it and use then stringify to turn the string back.
You can get a moderate approximation to what you are after with C99 and variable arguments in macros:
Source
#define make_array(name, dim1, dim2, ...) \
static char name[dim1][dim2] = { __VA_ARGS__ }
make_array(mine, 2, 2, "abc", "def", "ghi", "jkl");
Output
$: gcc -E xx.c
# 1 "xx.c"
# 1 "<built-in>"
# 1 "<command-line>"
# 1 "xx.c"
static char mine[2][2] = { "abc", "def", "ghi", "jkl" };
$
However, you cannot readily split a string in the preprocessor as requested - it is simply the wrong tool for the job.
You cannot do string processing with macros.
I'm not sure I understand exactly what you want to do, but this is probably best achieved with a function.
Forget it. I see way too many questions along the lines of "How can I make my code look like this?" when the question for achieving good code should be "How can I make my code work like this?" What is the goal you're trying to achieve?
If you want to import external data that was formatted in the weird notation you specified, does the data vary at runtime or is it constant? In the former case you'll need a parser in your program and a good deal of dynamic allocation. In the latter case, you need to write a program that runs before compiling the main program which parses and converts the data into C. But if there's no legitimate reason for the data to be in this weird format to begin with, you should simply write it in C from the start rather than trying to force C to look like something else.
Get rid of the quotes and use a variadic macro
Write a function to split the string and call it from the macro
Don't use macros for this, just make a static inline function. It is just as fast.
As Oli has already said, this kind of string processing is impossible with macros. Concatenation and replacement of other strings is about as much as you can do with macros.
I think the answer here is a question- why does the input string have to be of that format? Writing your required result does not require any more effort than it is to write your input, so why would you want to go through the pain of processing it?