Configuration attributes

The final type of attributes are #[cfg] attributes. These attributes are incredibly powerful, enabling us to compile certain parts of the code depending on the target we are compiling to. For example, we might want to use a specific Windows function and have a backup one for the rest, or we might want the code to do different things in little- and big-endian machines.

The syntax is pretty easy. For example, if you want to check the system architecture, you can use #[cfg(target_arch = "arm")], and instead of ARM, you can check for "x86", "x86_64""mips", "powerpc", "powerpc64", or "aarch64" too. To compile something only for FreeBSD, we can use #[cfg(target_os = "freebsd")]. You can compare the target_os configuration attribute with "windows", "macos", "ios", "linux", "android", "freebsd", "dragonfly", "bitrig" , "openbsd", or "netbsd".

If you only care about Windows/Unix differences, you can use #[cfg(target_family = "windows")] or #[cfg(target_family = "unix")], or even directly #[windows] and #[unix]. This can be specified further by using #[cfg(target_env = "gnu")], or "msvc", or "musl". The endianness of the system can be checked with #[cfg(target_endian = "little")] or #[cfg(target_endian = "big")], and the pointer width (32 or 64 bits) with #[cfg(target_pointer_width = "32")] or #[cfg(target_pointer_width = "64")] respectively.

More complex details can also be checked, such as whether the target has atomic integer types, and what size those atomic integers are. For example, to check whether the target platform has atomic 8 bit integers, you will use #[cfg(target_has_atomic = "8")]. You can check for 8, 16, 32, 64, and pointer width integers (with "ptr"). You can even check the vendor of the target architecture by checking #[cfg(target_vendor = "apple")]. You can check for "apple", "pc", or "unknown".

Finally, a couple of attributes let you know whether you are doing a test (using #[test]) and whether the debug assertions are turned on (using #[debug_assertions]). The first one could be useful if you want to change any particular behavior only for tests (not recommended; tests should run the same code as in production), and the second one lets you, for example, add some debug information if the application was compiled in debug mode.

You can set/use a configuration item selectively by using #[cfg_attr(a, b)]. This will have the same effect as doing #[b], but will only do something if a is true. If it's false, it will be like nothing was written. This is useful, for example, if you want to enable or disable lints depending on other attributes, or if you want to derive a trait only for certain targets, and implement it for the rest.

You can also check these configuration attributes in the code inside the logic by using the cfg!() macro. Simply use the same syntax as with attributes:

if cfg!(target_pointer_width = "32") {
do_something();
}
..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset
3.15.29.119