On Tuesday, 22 March 2016 at 02:05:20 UTC, Jakob Ovrum wrote:
On Monday, 21 March 2016 at 22:58:35 UTC, Jonathan M Davis wrote:
I'm inclined to think that folks should think twice before apply attributes en masse like that.

Why?

It makes it harder to know which attributes are actually being applied to a function, and it makes it way easier to accidentally apply attributes to a function. By putting them on the functions directly, it's very clear exactly which attributes apply, and you're not going to accidentally apply them to anything. And that becomes more critical as the file is maintained, because while you may know about all of those blanketed attributes when you first write the file, you may not realize that they're there later, and even if you do, someone else working on that file may not realize it. We've run into this with Phobos PRs where someone does the wrong thing, because they don't realize that an attribute has been applied to en masse.

It makes it _way_ too easy to miss that the attribute is being applied when it's somewhere else entirely in the file.

This isn't a problem for anything but @trusted.

It's worse for @trusted, but it's a problem any attributes that are involved with attribute inference. By putting something like pure: or nothrow: in the file, you risk accidentally marking any function that uses attribute inference as having that attribute. And while the compiler will error out in many cases, if you're dealing with templates, it's far too easy to not catch the problem. Your unit tests may very well work perfectly fine with those attributes, whereas a different set of template arguments would fail to compile thanks to those accidentally applied attributes, and you won't catch it until you (or someone else using your code) tries to use that function with template arguments that don't work with those attributes.

Another area where it causes problems is inheritance. Which attributes go on a base class function affect derived classes, possibly putting restrictions on derived classes that you don't want them to have. By using blanket attributes, it becomes easy to accidentally mark virtual functions as pure, nothrow, etc. and have those unit tests work just fine but then end up with someone else being screwed when they go to use that class, because those accidental attributes conflict with what they're trying to do. We have enough problems with making the right choices about which attributes go on virtual functions without having problems with them being applied accidentally.

I can understand someone wanting to reduce the number of annotations that they need to put on declarations in D, but from what I've seen, blanket attributes are a maintenance problem, and I think that we're almost always far better off without them. You shouldn't have to search through the file to figure out which attributes apply to a function, otherwise you end up with an increase in the number of mistakes related to attributes, some of which will be quickly caught and many of which won't be.

- Jonathan M Davis

Reply via email to