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
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"))
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.
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(..).
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.
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");