Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

D - pure classes and structs

Tags:

d

Out of idle curiosity, I've typed in the following piece of code:

pure struct Foo{ }
pure class Bar{ }

This, apparently, compiles with both DMD and LDC. I have no idea what it does (if it does), as calling impure functions from such structs/classes is OK. So, what does attaching pure to a class or a struct change?


1 Answers

In general, D has a tendency to ignore attributes when they don't apply, if nothing else, because generic code is easier to write that way (at times, it avoids having to write a bunch of static ifs just to avoid applying attributes to code where they wouldn't have any effect) - one example being that you can put static on a pretty much any declaration at module level, but it doesn't actually do anything for most of them, and the compiler doesn't complain about it.

However, for whatever reason, the way that attributes get applied when you mark a struct or class with them is a bit inconsistent. For instance, if you marked a struct or class with @safe, then every function in that struct or class will be @safe unless it's marked with @trusted or @system. In contrast, if you mark the class or struct with pure, it does absolutely nothing - just like with static. It's simply ignored.

My best guess as to why something like @safe is applied to all of the functions inside the struct or class, whereas an attribute like pure or nothrow is ignored is that @safe, @trusted, and @system can be undone on specific functions within the struct or class by using a different attribute explicitly on that function, whereas for most attributes, there is no way to reverse them.

Unfortunately however, the fact that you can mark a class or struct with attributes when they either don't apply or when they apply just to the declarations within the class or struct and not the class or struct itself does tend to confuse people (e.g. some people think that immutable class C {..} means something special for the class, when all it means is that the declarations within the class are immutable; it would be no different from doing class C { immutable { ... } }). So, ultimately, you have to be familiar with what each attribute actually does to know when they actually apply to the class or struct, when they really just apply to the declarations inside the class or struct, and when they're simply ignored.

Personally, I never apply attributes to a class or struct unless they're specifically meant to apply to the struct or class and not on the functions within it (e.g. final on a class means something separate from putting it on the functions within that class), and the number of attributes that actually apply to a struct or class is pretty small. static does in some contexts (just not at module level), abstract and final do for classes, and the access modifiers (public, private, etc.) do. Per TDPL, synchronized is also supposed to be special for the class, but synchronized classes have never really been implemented (just synchronized functions). So, I might have missed one, but off the top of my head, that's the full list of attributes that can actually apply to a struct or class, and all of the others are either ignored or apply to the declarations within the struct or class but not to the struct or class itself.

like image 101
Jonathan M Davis Avatar answered Apr 18 '26 08:04

Jonathan M Davis



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!