I'm starting a foray into using macros to generate data structures. Alas, I've run into a strange snag. I want to write the following macro:
#define CREATE_STRUCT(NAME) struct ##NAME { }
I attempt to use it like this:
CREATE_STRUCT(test);
However, it generates an error and the macro expansion apparently doesn't work. I've noticed that in every example of this type of macro expansion I've seen, there is an underscore (_) that precedes the ##<ARG> token. For example:
#define CREATE_STRUCT(NAME) struct _##NAME { }
This one works, but of course it throws an underscore at the beginning of the newly declared type.
So, there's a few questions here:
Is there a way to avoid requiring a character to precede the ## token?
What are the rules regarding the ## token in macros?
Thank you in advance!
You don't need the token pasting operator unless you want to merge multiple tokens into one. For example get TestThis from Test and This. In your case you can just do:
#define CREATE_STRUCT(NAME) struct NAME { }
If you run g++ -E file.cc on your macro, you will see that the preprocessor comes up with structtest { }; and this causes an error.
Related
For example, let us take this code:
Method m()
{
$$$someMacro
}
Or:
Method m(foo as whatever)
{
$$$otherMacro(foo)
}
Provided that I can extract someMacro and otherMacro from the code samples above, is there a way to programmatically expand them?
No. Macro can only be resolved at compile time. Since what macro expands into may depend on where in code macro is placed you can't expand one macro without context.
With syntax highlighting enabled, it's distracting while reading code like answer to this question with new used as a variable name.
I'm trying to think of a reason why only a subset of keywords would be reserved and can't come up with a good one.
Edit: Alternate title for this question:
Why are Go's predeclared identifiers not reserved ?
That's because new and make aren't really keywords, but built-in functions.
If you examine the full list of the reserved keywords, you won't see len or cap either...
In short: because using predeclared identifiers in your own declarations don't make your code ambiguous.
new and make are builtin functions, amongst many others. See the full list in the doc of the builtin package.
Keywords are a carefully chosen small set of reserved words. You cannot use keywords as identifiers because that could make interpreting your source ambiguous.
Builtin functions are special functions: you can use them without any imports, and they may have varying parameter and return list. You are allowed to declare functions or variables with the names of the builtin functions because your code will still remain unambiguous: your identifier in scope will "win".
If you would use a keyword as an identifier, you couldn't reach your entity because an attempt to refer to it by its name would always mean the keyword and not your identifier.
See this dirty example of using the predeclared identifiers of the builtin function make and the builtin type int (not recommended for production code) (try it on the Go Playground):
make := func() string {
return "hijacked"
}
int := make() // Completely OK, variable 'int' will be a string
fmt.Println(int) // Prints "hijacked"
If you could use keywords as identifiers, even interpreting declarations would cause headache to the compiler: what would the following mean?
func() - is it calling your function named func or is it a function type with no params and no return types?
import() - is it a grouped import declaration (and importing nothing) or calling our function named import?
...
I'd like to execute template with noescape and no quotes, but noescape is not supported now.
Any suggestion or do I have to use another template engine? Thank you!
Code here: http://play.golang.org/p/R-Ib5H9bXx
You are encouraged to store safe Javascript in the type template.JS:
type JS string
JS encapsulates a known safe EcmaScript5 Expression,
for example, (x + y * z()). Template authors are responsible for
ensuring that typed expressions do not break the intended precedence
and that there is no statement/expression ambiguity as when passing an
expression like "{ foo: bar() }\n'foo'", which is both a valid
Expression and a valid Program with a very different meaning.
So, the only change you need to do to your code is:
type Var struct {
Name template.JS
Value template.JS
}
A small addition to #ANisus answer. There is also a similar wrapper for HTML (and CSS). Whenever you try to pass an HTML string into a template, it gets quoted. So in order to render the safe HTML properly, use:
yourHTML := "<strong>Hi!</strong>"
yourWrappedHTML := template.HTML(yourHTML)
// pass the later into your template
I have been writing C++ for a while but have very little macro experience. I have read some of the other questions on this topic but I just can't quite translate them to my problem.
I want to define a macro such that coding ENUM_PRAGMA(foo) produces _Pragma("enum(foo)") which I intend to have the effect of #pragma enum(foo)
(The compiler supports _Pragma("string").)
I have tried multiple variations of
#define ENUM_PRAGMA(siz) \
_Pragma( "enum(" #siz ")" )
but can't get any of them to work.
Based on How do I implement a macro that creates a quoted string for _Pragma? I tried
#define HELPER1(x) enum( x )
#define HELPER2(y) HELPER1(#y)
#define ENUM_PRAGMA(siz) _Pragma(HELPER2(siz))
but I'm still not quite there. (Error is string literal was expected but enum was found so I guess my HELPER2 is not quoting the string.
Can anyone please humor me on this? Thanks much.
Okay, I got it.
I defined a general purpose macro STRINGIFY:
#define STRINGIFY(str) #str
Now the real macro comes down simply to
#define ENUM_PRAGMA(siz) _Pragma(STRINGIFY(enum(siz)))
Thanks for your patience.
I have a Swig-wrapped C library that I use in Ruby. I have no control over Swig or any interface definitions since that is done by the vendor of the interface.
No I find that there's a function in the library that has a char ** output parameter defined (among others). Example function definition:
void get_information(char * input, char **output, int someint)
Of course, my first attempt in Ruby was:
output_thing = ''
get_information "input", output_thing, 123
puts output_thing
This resulted in the error message
Expected argument 1 of type char **, but got String ""
Having no experience in Swig, I'm kindof stuck. Is it possible to make use of this function in Swig without defining or using a typemap?
Thanks in advance for your quick responses!
I found it (weee!)
There is a new_charpp method that creates the correct datatype. Apparently you have several of these methods for each of the primitives and commonly used datatypes (new_longpp, new_longlongpp, new_intpp et cetera).
Afterwards, you can read the correct contents from this variable using charpp_value(...)