C/C++ macros with parameters - macros

I'm in doubt about using ## and # inside C macros.
I've found codes like this:
#define GET_INSTANCE_PROC_ADDR(inst, entrypoint) \
{ \
demo->fp##entrypoint = \
(PFN_vk##entrypoint)vkGetInstanceProcAddr(inst, "vk" #entrypoint); \
if (demo->fp##entrypoint == NULL) { \
ERR_EXIT("vkGetInstanceProcAddr failed to find vk" #entrypoint, \
"vkGetInstanceProcAddr Failure"); \
} \
}
I was able to deduces that double ## means it will repeat text parameter, but I don't understand the following segment:
"vk" #entrypoint
After the prefix, it has a space and single # instead of ##.

## is the pasting operator. It ensures that the compiler thinks that the left side and the right side are just one token. If you write GET_INSTANCE_PROC_ADDR(foo, bar), then demo->fp##entrypoint becomes demo->fpbar.
# gets the contents of the macro argument as a string. If you write GET_INSTANCE_PROC_ADDR(foo, bar), then #entrypoint is "bar".
In C and C++, it's legal to put two string literals next to one another and the compiler will concatenate them: "this" "is" "valid" is the same as "thisisvalid".

Related

How to pass value to JsonPath for Gatling

I want to pass categoryId to the jsonPath but could not find the correct way. The following is use but it doesn't accept the $ at the beginning.
The variable is available within the object
object CoreRequests {
val categoryId = Config.categoryId
.check(jsonPath(s"$..Contents[?(#.CategoryID == $categoryId)].ID").findAll.saveAs("staticMovieIDList"))
triple quotes also not working
s"""$..Contents[?(#.CategoryID == $categoryId)].ID"""
As $ is a reserved character in Scala's String interpolation, it has to be escaped (doubled).
.check(jsonPath(s"$$..Contents[?(#.CategoryID == $categoryId)].ID").findAll.saveAs("staticMovieIDList"))

What does the tt metavariable type mean in Rust macros?

I'm reading a book about Rust, and start playing with Rust macros. All metavariable types are explained there and have examples, except the last one – tt. According to the book, it is a “a single token tree”. I'm curious, what is it and what is it used for? Can you please provide an example?
That's a notion introduced to ensure that whatever is in a macro invocation correctly matches (), [] and {} pairs. tt will match any single token or any pair of parenthesis/brackets/braces with their content.
For example, for the following program:
fn main() {
println!("Hello world!");
}
The token trees would be:
fn
main
()
∅
{ println!("Hello world!"); }
println
!
("Hello world!")
"Hello world!"
;
Each one forms a tree where simple tokens (fn, main etc.) are leaves, and anything surrounded by (), [] or {} has a subtree. Note that ( does not appear alone in the token tree: it's not possible to match ( without matching the corresponding ).
For example:
macro_rules! {
(fn $name:ident $params:tt $body:tt) => { /* … */ }
}
would match the above function with $name → main, $params → (), $body → { println!("Hello world!"); }.
Token tree is the least demanding metavariable type: it matches anything. It's often used in macros which have a “don't really care” part, and especially in macros which have a “head” and a “tail” part. For example, the println! macros have a branch matching ($fmt:expr, $($arg:tt)*) where $fmt is the format string, and $($arg:tt)* means “all the rest” and is just forwarded to format_args!. Which means that println! does not need to know the actual format and do complicated matching with it.

How to process expanded macros from within procedural macros?

For overflower, I'm trying to replace all arithmetic operations (binary +, -, *, /, %, <<, >> and unary -) with corresponding trait method calls. However, I'm hitting a wall with macros. Ideally, I'd work on the already expanded macro, but this does not appear to work.
I've followed the suggestion in syntax::fold::Folder::fold_mac(..) and called noop_fold_mac(mac, self), but that does not appear to do anything to stuff inside a macro, like assert_eq!(2, 1 + 1). I don't care about the code pre-expansion, so how do I have my macro work on the expanded code?
I could probably work on the TokenTrees directly, but that's cumbersome.
I'm using rustc 1.11.0-nightly (915b003e3 2016-06-02)
You can use the expand_expr function to do a full expansion (if let, macros, etc...). You need a MacroExpander, which you can get by passing a mutable reference to the ExtCtxt to the MacroExpander::new method or call the ExtCtxt's expander() method.
The actual code is:
fn fold_expr(&mut self, expr: P<Expr>) -> P<Expr> {
..
if let ExprKind::Mac(_) = expr.node {
let expanded = expand_expr(expr.unwrap(), &mut self.cx.expander());
return self.fold_expr(expanded);
}
..
}
Edit: For completeness, one should also expand Items with ItemKind::Mac; there's an syntax::ext::expand::expand_item(..) method working similarly to expand_expr(..).

Difference between a const inside a proc vs outside

This is probably a really dumb question, but other than visibility is there any real difference between a const inside a proc vs outside?
const foo = "FOO"
proc test() =
const bar = "BAR"
echo foo & bar
test()
Like when inside, does the stack grow and shrink for that const every time the proc is invoked, or because it's a const is it just held in a static memory location for the duration of the application?
I'm asking specifically about Nim but reflections on differences/similarities in other languages are welcome too.
If you look at the generated C code, you will see this line:
STRING_LITERAL(TMP139, "FOOBAR", 6);
What this tells us is foo & bar was evaluated at compile time.
nimbase.h has this:
#define STRING_LITERAL(name, str, length) \
static const struct { \
TGenericSeq Sup; \
NIM_CHAR data[(length) + 1]; \
} name = {{length, length}, str}
const in Nim is much more than a static memory location. But it does seem like in this case we get the string "FOOBAR" in a static memory location. However, if we replace these strings with numbers, for example, 1 and 3, the generated code just has a 4 literal without any storage.
Now, for the actual question. The only difference here is the scope in which the constants are seen.
If this wasn't simplified in such a way (e.g. if you wrote echo foo\\echo bar), we can consult the generated code again and see two identical (except for content) STRING_LITERAL declarations.

How to make a macro that takes a formatted string + several additional arguments, just like NSLog?

This is for practise. I try to build something similar to NSLog. Currently I have this:
#define LogThis(info) \
[[MyLogger sharedLogger] logThis:info];\
- (void)logThis:(NSString*)info {
fprintf(stderr, [[NSString stringWithFormat:#" %#\n", info] cString]);
}
Currently all I can do is pass a simple #"string" to it, but no formats and arguments like I could with NSLog. The main advantage here is that I get rid of all this overhead which NSLog produces. For learning purpose I'd like to know how I can get multiple arguments to make something similar to NSLog, so that I could call:
LogThis(#"method foo received input value %d", inputValue)
Is this possible?
Here’s how you define variadic macros in gcc’s cpp:
#define LogThis(format, ...) \
do { printf(format, ## __VA_ARGS__); } while(0)
There is a way, you define the last argument with a trailing '...'. To access the last arguments defined, prepend the argument name with ##. I have a similar Log macro that looks like:
#define LOGGER(format, args...) \
LogManager::log()->addEntry(format, ##args)
where the addEntry function takes in a printf-like format. An example call looks like
LOGGER("This is a debug string with %d arguments %s", 2, "hooray");