When I'm trying to define a macro in code, compiler says this:
refix/mod.rs:12:1: 12:12 error: macro definitions are not stable enough for use and are subject to change
refix/mod.rs:12 macro_rules! re_fix(
^~~~~~~~~~~
refix/mod.rs:12:1: 12:12 note: add #[feature(macro_rules)] to the crate attributes to enable
refix/mod.rs:12 macro_rules! re_fix(
I've added a lot of #[feature(macro_rules)], but it didn't help.
Source code: https://gist.github.com/suhr/11207656
PS: yes, they're probably a lot of other errors there, but I am interested about this one.
I think that error message is somewhat misleading. You have to add #![feature(macro_rules)] to your main crate module (note the exclamation sign), along with #![crate_id=...] and others.
#![crate_id="rsfix#0.0"]
#![feature(macro_rules)]
macro_rules! example( ... )
fn main() {
example!(...);
}
This should work on the latest compiler version.
Related
I want to use a custom derive macro that uses attributes. For Rust 2015, I wrote:
#[macro_use]
extern crate pest_derive;
#[derive(Parser)]
#[grammar = "grammar.pest"]
pub struct MyParser;
Using edition = '2018', extern crate is deprecated so macro_use is unavailable. I assumed I could write use pest_derive::{grammar,derive_parser};, but I have to write use pest_derive::*;.
How can I avoid the glob import? The code for the pest_derive crate is very simple, I have no idea what necessary thing * imports that isn’t derive_parser or grammar.
error[E0658]: The attribute `grammar` is currently unknown to the compiler and
may have meaning added to it in the future (see issue #29642)
--> src/parser/mod.rs:10:3
|
10 | #[grammar = "rst.pest"]
| ^^^^^^^
That's the incorrect syntax for importing the derive. You import the name of the derive, not the underlying function. In this case, use pest_derive::Parser:
use pest_derive::Parser;
#[derive(Parser)]
#[grammar = "grammar.pest"]
pub struct MyParser;
or
#[derive(pest_derive::Parser)]
#[grammar = "grammar.pest"]
pub struct MyParser;
This question isn't specific to Rust 2018, either. Rust 1.30 and up allows you to import macros like this.
I'm using a macro to extend a primitive struct:
pub struct MyTypedNumber(pub u32);
struct_impl_my_features!(MyTypedNumber);
The struct_impl_my_features macro can implement functions & traits for MyTypedNumber, however there is a case where its useful to use #[derive(PartialEq, Eq)] - for example.
Is it possible to use #[derive(...)] after the struct is already declared?
An alternative is to pass in the struct definition as an item argument to a macro:
struct_impl_my_features!(
pub struct MyTypedNumber(pub u32);,
MyTypedNumber
);
This works, so it may be the best option, although it is rather clunky and means the declaration and macro extension must be together.
See this complete example, the macro is called struct_bitflag_impl (second example).
I worked around this by manually implementing PartialEq and Eq, however I ran into a case where Rust needs #[derive(...)] to be used as constants within match statement:
= warning: this was previously accepted by the compiler but is being phased out;
it will become a hard error in a future release!
= note: for more information,
see RFC 1445 <https://github.com/rust-lang/rfcs/pull/1445>
The "complete example" link you provide does show an example of having the macro prefix attributes (see the second macro).
#[derive(PartialEq, Eq, Copy, Clone, Debug)]
$struct_p_def
However, if instead you want to be able to provide derive-attributes per struct (e.g., only some of your structs need to derive PartialEq), you can pass the derive expression in the first part of your second struct_impl_my_features! example—the attributes are considered part of the item macro form. E.g.,
struct_impl_my_features!(
#[derive(PartialEq, Eq)]
pub struct MyTypedNumber(pub u32);,
MyTypedNumber
);
Update
Sorry, I don't have an answer to your main question; as far as I know, it is not possible. However, if your primary concern is the clunkiness, and if your structs are all of similar form, you could make your macro call nicer by adding this to the top of your macro:
($x:ident ( $($v:tt)* ) ) => {
struct_impl_my_features!(pub struct $x( $($v)* );, $x)
};
And then calling it like:
struct_impl_my_features!(MyTypedNumber(pub u32));
Is it OK to set debugging macros to empty string when I want to disable debug checks?
Both assert and BOOST_ASSERT are set to ((void)0) when NDEBUG is defined.
Why not to do something line this?
#ifdef NDEBUG
#define MY_DEBUG_MACRO_FUNCTION(x,y,z) ""
#elif
// define macros
#endif
The idea is for the macro to do nothing on release builds. You could define it to an empty string literal, since ""; is a valid expression. I would believe the reason of being defined to ((void)0) is so that the implementation does not emmit warnings for the expression. I have no solid grounds to say this, but some minimal testing shows that ""; generates a warning while ((void)0) doesn't. Of course, warnings are not standarized so there could be a particular implementation that does emit a warning for ((void)0) as well, but it would have to define assert to something else that doesn't on NDEBUG builds or it would be quite annoying to the user.
Not it's not ok. But you can make the "body" of the macro empty:
#define MY_DEBUG_MACRO_FUNCTION(x,y,z)
Note that there is nothing being defined, so when used nothing will be put in the source.
Going by your subject line use #undef. This is useful when there is a macro version and a C version of the function. This way you can use the compiled code over the in-lined expanded macro.
I'm looking to move some of my lighter weight metaprogramming from Nemerle to Boo and I'm trying to figure out how to define custom operators. For example, I can do the following in Nemerle:
macro #<-(func, v) {
<[ $func($v) ]>
}
Then these two are equivalent:
foo <- 5;
foo(5);
I can't find a way of doing this in Boo -- any ideas?
While Boo supports operator overloading by defining the appropriate static operator function (op_addition), and also supports syntactic macros, it does not support creating custom operators at this time.
I'm not sure if this is exactly what you need but you can create syntactic macros in Boo. There's some information on the CodeHaus site, http://boo.codehaus.org/Syntactic+Macros, but the syntax has changed in one of the recent releases. I don't know of any tutorials on the new syntax but the source release for Boo 0.8.2 has some examples (some of the language structures are implemented as macros). If you don't want to download the full source a view of the SVN repository is available, https://svn.codehaus.org/boo/boo/trunk/src/Boo.Lang.Extensions/Macros/. The assert macro would be a good place to start.
HTH
Stoo
How does function name scoping work across multiple C files?
I'm porting a standard gnu toolchain project to iPhone OS, and using Xcode to do it.
The code builds through make, but not through xcode. when building through xcode, the linker complains that the same symbol (function) is defined in two objects. the code has two distinct source files that #include a common file between them. While... odd (to me at least), it seems to work for the standard toolchain. any ideas if this is something that's somehow handled differently through a standard makefile?
All functions not marked static have global scope (they are dumped in a single namespace). Functions marked static are limited to the translation unit they are defined in.
You have a One Definition Rule violation.
One of your headers probably has a definition for a variable. E.g: in common.h you have
int foo = 42;
change it to:
extern int foo; // a declaration
and then create a common.c file where you put a definition:
int foo = 42;
In C, if I remember correctly, static function names are local to the source file in which they are defined, but all other function names exist in a global namespace. So if you have file1.c with
void fn1() {}
static void fn2() {}
and file2.c with
void fn1() {}
static void fn2() {}
and you tried to compile them with something like
cc file1.c file2.c
then you would get a name conflict between the fn1 in file1.c and the fn1 in file2.c, but not between the two fn2 functions (because they're static). (Of course, you'd get a bunch of other errors too because this program doesn't do anything, but those aren't relevant to scoping.)
If it compiles without errors from the Makefile, but not from your XCode project, it is most likely because the compiler's options are being set differently in the two environments. Check the Makefile to see what options are passed to 'gcc'. In particular, it's possible that the duplicate definitions are conditionally-compiled with #ifdef, and you may need to add some preprocessor definitions to your XCode project's settings.
My guess is that the common header defines an inline function that is resulting in a duplicate symbol. If that is the case, prefix those functions with a static inline, or define them as inline with an extern declaration in another .c file.