What is the purpose of '_' in macro - c

I am trying to understand one of the VPP sample function name 'sample_plugin_api_hookup'. What is the purpose of underscore ('_' ) in macro (#define _(N,n) ) ?
#define _(N,n) \
vl_msg_api_set_handlers((VL_API_##N + sm->msg_id_base), \
#n, \
vl_api_##n##_t_handler, \
vl_noop_handler, \
vl_api_##n##_t_endian, \
vl_api_##n##_t_print, \
sizeof(vl_api_##n##_t), 1);
foreach_sample_plugin_api_msg;
#undef _

_ is a valid C identifier, though it's reserved for use at file scope. A C identifier consists of a letter or underscore, followed by zero or more letters, underscores, or digits (I'm ignoring universal character names).
Apparently the author of that code wanted a name that's short, easy to type, and unobtrusive. I believe the GNU gettext package, or code that uses it, follows this convention, with a macro call like
_("This is a message")
being replaced by a localized version of the message. (Which means that a program that uses GNU gettext likely would have to pick a different name).
foreach_sample_plugin_api_msg is another macro that makes use of the _ macro, which is why the _ macro is undefined immediately after that line.
Perhaps the author was influenced by the Go language, which uses _ as a blank identifier.
Opinions are likely to differ on the question of whether this is a neat trick or a crime against good taste.

Related

Is it possible to define macro inside macro?

I want to use macro parameter like this:
#define D(cond,...) do{ \
#if cond \
#define YYY 1 \
#else \
#define YYY 0 \
} while(0)
Is it possible?
UPD
Maybe when sources will be preprocessed twice: gcc -E source.c | gcc -xc - next will work:
#define D(cond,...) #define YYY cond&DEBUG
#if YYY
#define D(...) printf( __VA_ARGS__ )
#else
#define D(...)
#endif
No, because C 2011 [N1570] 6.10.3.4 3 says, about macro replacement, “The resulting completely macro-replaced preprocessing token sequence is not processed as a preprocessing directive even if it resembles one,…”
This is not possible. Read about the GNU cpp preprocessor and the C11 standard (i.e. n1570), and check here. The C preprocessor is (conceptually at least) run before the rest of the compiler (which gets the preprocessed form of your translation unit). BTW, for a file foo.c you could use gcc -C -E foo.c > foo.i (using GCC) to get inside foo.i its preprocessed form, and you can inspect that foo.i -since it is a textual file- with a pager or an editor.
However, a .c file can be generated (generating C code is a common practice, at least since the 1980s; for example with yacc, bison, rpcgen, swig, ....; many large software projects use specialized generators of C or C++ code...). You might consider using some other tool, perhaps the GPP preprocessor (or GNU m4) or some other program or script, to generate your C file (from something else). Look also into autoconf (it might have goals similar to yours).
You may want to configure your build automation tool for such purpose, e.g. edit your Makefile for GNU make.
No, this is not possible.
During translation, all preprocessing directives (#define, #include, etc.) are executed before any macro expansion occurs, so if a macro expands into a preprocessing directive, it won't be interpreted as such - it will be interpreted as (invalid) source code.
As pointed out by others this is not possible but there is a work around:
int YYY;
/* global scope variables are sometimes considered bad practice... */
#define D(cond,...) do{ \
if (cond) { \
YYY = 1; \
} \
else { \
YYY = 0; \
} \
} while(0)
Use an optimizing flag (ex: gcc/clang -O3) and it will replace the dead code as if it was a macro. Obviously you may want to change the type of YYY but you seem to use it like a boolean.
No, you cannot. The C preprocessor cannot know what is going to occur during runtime.
The preprocessor goes through the program before it is even compiled and replaces every macro defined with its assigned value.
This is some poor man's code generation, for when integrating another tool to the project is overkill.
Define a macro like this, expanding for your needs:
#define NESTED /* Comment out instead of backslash new lines.
*/ /*
*/ UNDEF REPLACED /*
*/ /*
*/ IFDEF CONDITION /*
*/ DEFINE REPLACED 1 /*
*/ ELSE /*
*/ DEFINE REPLACED 0 /*
*/ ENDIF
Your version of NESTED can be a function-like macro, and REPLACED can have a more elaborated body.
Leave CONDITION and the directive named macros without a definition.
DEFINE CONDITION to control which value NESTED gets on compilation, similarly to normal #ifdef usage:
DEFINE CONDITION
NESTED
int i = REPLACED; //i == 1
UNDEF CONDITION
NESTED
int z = REPLACED; //z == 0
Source code that uses NESTED and the other macros will not compile. To generate a .c or .cpp file that you can compile with your chosen options, do this:
gcc -E -CC source.c -o temporary.c
gcc -E \
-DDEFINE=\#define -DUNDEF=\#undef \
-DIFDEF=\#ifdef -DELSE=\#else -DENDIF=\#endif \
temporary.c -o usableFile.c
rm temporary.c #remove the temporary file
-E means preprocess only, not compile. The first gcc command expands NESTED and all normally defined macros from the source. As DEFINE, IFDEF, etc. are not defined, they and their future arguments remain as literal text in the temporary.c file.
-CC makes the comments be preserved in the output file. After the preprocessor replaces NESTED by its body, temporary.c contains the directive macros in separate lines, with the comments. When the comments are removed on the next gcc command, the line breaks remain by the standard.
# is accepted in the body of a macro that takes no arguments. However, unlike macros, directives are not rescaned and executed on expansion, so you need another preprocessor pass to make nested defines work. All preprocessing related to the delayed defines needs to be delayed too, and made available to the preprocessor at once. Otherwise, directives and arguments needed in a later pass are consumed and removed from the code in a previous one.
The second gcc command replaces the -D macros by the delayed directives, making all of them available to the preprocessor starting on the next pass. The directives and their arguments are not rescaned in the same gcc command, and remain as literal text in usableFile.c.
When you compile usableFile.c, the preprocessor executes the delayed directives.

undefined reference to `uv_prepare_init' on libuv

Is uv_prepare_init deprecated?
In uv.h there is a function definition, but nowhere I could find the function body in C file. However, on documentation, there are no keyword, as deprecated.
Is there any solution to replace uv_prepare_init?
I need this handle for executing before polling I/O.
uv_prepare_init isn't deprecated.
See the file loop-watcher.c for more details. It's available both for unix (libuv/src/unix) and windows (libuv/src/win).
So, what's the magic?
How is it that there is no definition but the function is part of the library?
Macros. That's all. The definition is there, even though a bit obfuscated.
There exists a macro called UV_LOOP_WATCHER_DEFINE, a part of which follows:
#define UV_LOOP_WATCHER_DEFINE(name, type) \
int uv_##name##_init(uv_loop_t* loop, uv_##name##_t* handle) { \
uv__handle_init(loop, (uv_handle_t*)handle, UV_##type); \
handle->name##_cb = NULL; \
return 0; \
} \
// ... continue ...
Immediately after the definition, the macro is used as:
UV_LOOP_WATCHER_DEFINE(prepare, PREPARE)
You can easily do the substitution for yourself and find that it's actually defining uv_prepare_init.
Therefore we can say that the function is part of the library, it isn't deprecated (at least in v1.x) and you can freely use it for your purposes.
No need to replace it in any way.

Suppress C Macro Variable Substitution

I have this bit of code (part of an interpreter for a garbage-collected Forth system, actually):
#define PRIMITIVE(name) \
do \
{ \
VocabEntry* entry = (VocabEntry*)gc_alloc(sizeof(VocabEntry)); \
entry->code = name; \
entry->name = cstr_to_pstr(#name); \
entry->prev = latest_vocab_entry; \
latest_vocab_entry = entry; \
} \
while (false)
PRIMITIVE(dup);
PRIMITIVE(drop);
PRIMITIVE(swap);
// and a lot more
but there's a problem: in the line
entry->name = cstr_to_pstr(#name);
the name field is substituted for dup, drop, swap, and the rest. I want the field name to not be substituted.
So, is there any way to solve this, other than simply renaming the macro argument?
For an answer, please explain if there is, in general, a way to suppress the substitution of a macro argument name in the macro body. Don't answer "just do it this way" (please).
You can define a different macro to expand to name, like this:
#define Name name
and change the name field in the PRIMITIVE macro to use the new macro, like this:
#define PRIMITIVE(name) \
do \
{ \
VocabEntry* entry = (VocabEntry*)gc_alloc(sizeof(VocabEntry)); \
entry->code = name; \
entry->Name = cstr_to_pstr(#name); \
entry->prev = latest_vocab_entry; \
latest_vocab_entry = entry; \
} \
while (false)
Other than using something different from the parameter name in the macro body or changing the parameter name, there is no other way to do this in the C language. Per C 2011 (N1570) 6.10.3.1 1, when a function-like macro is recognized, parameter names are immediately substituted except when # or ## is present, and there no other exceptions:
After the arguments for the invocation of a function-like macro have been identified, argument substitution takes place. A parameter in the replacement list, unless preceded by a # or ## preprocessing token or followed by a ## preprocessing token (see below), is replaced by the corresponding argument after all macros contained therein have been expanded.
The # token changes the parameter name to a string, which is no use in this situation. The ## token expands the parameter name and pastes it together with an adjacent token, which is also no use in this situation.
No, there is not.
To see why, you need to consider the way macro expansion actually happens. Expanding a function-like macro requires three main steps:
the arguments to the macro are fully expanded, unless the macro uses the # or ## operators on them (not relevant in the example since they're single tokens)
the entire replacement list is scanned, and any occurrence of a parameter name is replaced by the corresponding argument
after step 2 is complete, the expanded replacement list is itself rescanned, and any macros appearing are expanded at this point
This is outlined in standard section 6.10.3 (C11 and C99).
The upshot of this is that it is impossible to write some kind of macro that can take name and abuse the suppression-rules of '##' or anything like that, because the replacement step in the body of PRIMITIVE must run completely before any of the macros within the body are allowed their turn to be recognised. There is nothing you can do to mark a token within the replacement list for suppression, because any marks you could place upon it will only be examined after the replacement step has already run. Since the order is specified in the standard, any exploit you find that would let you mark a token in this way is a compiler bug.
Best I can suggest if you're really set on not renaming the macro argument is to pass na and me as separate arguments to a concatenation macro; the token name will only be formed after replacement is done and the list is no longer being examined for parameter names.
EDIT wish I typed faster.
No, there is no way to suppress the replacement within a macro's body of a token identical to that of a declared argument to said macro. Every possible solution short of jumping into the preprocessor code will require you to rename something, either the argument name or the name of the field (potentially just for purposes of that macro, as Eric's answer does).

What kind of statements,keywords,arguments etc can span multiple lines,and what need "\" for this?

How to know what kind of "things" can span multiple lines in C code without needing a \ character at the end of the line?And what kind of "things" need the \?How to know that?For example, in the following code, if and printf() work fine if I split them up in multiple lines.
if
(2<5)
printf
("Hi");
But in the following code,printf() needs a \ ,else shows error:
printf("Hi \
");
Similarly,the following shows error without a \
char name[]="Alexander the \
great of Greece";
So please tell me how to know when to use the \ while spanning multiple lines in C code, and when we can do without it?I mean, like if works both with and without the \.
This is about a concept called 'tokens'. A token is source-program text that the compiler does not break down into component elements. Literals (42, "text"), variable names, keywords are tokens.
Endline escaping is important for string constants only because it breaks apart a token. In your first example line breaks don't split tokens. All whitespace symbols between tokens are ignored.
The exception is macro definitions. A macro definition is ended with line break, so you need to escape it. But macros are not C code.
If you want to break a string across lines, you can either use the \ as you have...
printf("Hello \
World");
Or, alternatively, you can terminate the string with a " and then start a new string on the next line with no punctuation...
printf("Hello "
"World");
To the best of my knowledge, the issue with lines applies in only two places... within a string and within a define..
#define MY_DEFINE(fp) \
fprintf( fp, "Hello "\
"World" );
In short, the \ character is telling the compiler this statement continues on the next line. However, C/C++ is not white-space dependent, so really the only place this would come up is on a statement that is expected to be on a single line... which would be a string or a define.
C does not depend on line feeds.
You could use line feeds anywhere you like, as well as just not using them at all.
This implies seeing string literals as one token.
But, as in real life: Too much or to few, both does make life difficult. Happyness is matter of balance ... :-)
Please note that lines starting with a # are not C code, but pre-processor instructions.

How can I insert a #defined string into a system() command? (win32)

Here is an overly simplified version of what I am trying to do:
#define LOGDIRECTORY C:\\logs\\
system("mkdir LOGDIRECTORY");
However the preprocessor, instead of swapping out the defined name is not. Instead the system command actually thinks LOGDIRECTORY is the name, and thus is shooting me errors when starting the program.
I know it's wrong and there must be something I can do with the " marks or other characters to specify what I want, but I can't figure it out. I don't want to hardcode the directory and file names because someone may want to change them in the future and it would be much easier to change a define than the whole function etc.
PS, I am coding this in plain C.
#define LOGDIRECTORY C:\\logs\\
#define DEF2STR(x) #x
system("mkdir " DEF2STR(LOGDIRECTORY));
#define LOGDIRECTORY_WITH_QUOTES "C:\\logs\\"
system("mkdir " LOGDIRECTORY_WITH_QUOTES);
In C, you can do simple string concatenation by writing two string literals with no operator in between. "A" "B" will be converted to "AB" at compile time. You can also use this for splitting a long string to multiple lines.
printf("a very long "
"string indeed");
To convert the define to a proper string, use the pound sign (#) in a macro or skip the whole thing and include the quotes in the define itself.
If you were compiling with GCC, you would have no choice but to wrap the define with quotes since the final trailing backslash would be interpreted as a line continuation character, and if that does not cause an error on its own, the penultimate backslash would likely raise a error. However, if you chose to just get rid of the trailing backslash, you'd still need to use two levels of stringification macros, or your syscal would be "mkdir LOGDIRECTORY". See http://gcc.gnu.org/onlinedocs/cpp/Stringification.html
So the above example would become:
#define LOGDIRECTORY C:\\logs
#define DEF2STR(x) #x
#define STR(x) DEF2STR(x)
system("mkdir " STR(LOGDIRECTORY));

Resources