-
-
Notifications
You must be signed in to change notification settings - Fork 619
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Default postblit errors everywhere, should be deprecated... #20838
Comments
Actually, right now, if you want code that works correctly in general, you use a postblit constructor and not a copy constructor. The reason for this is that dynamic arrays and associative arrays do not support copy constructors properly. So, while I agree that we would ideally be using copy constructors, as far as the language goes, their implementation has yet to be completed, and I would strongly advise that code in general use postblit constructors until all of the druntime hooks have been fixed; otherwise, you're going to have some subtle bugs that could be a royal pain to track down. I wasted a ton of time at work when trying to add copy constructors to some code before I figured out that they simply don't work properly with dynamic arrays and associative arrays, and I had to switch to postblit constructors. I would advise that everyone else do the same unless they know for a fact that the types in question are not going to be used with either dynamic arrays or associative arrays. IMHO, the ball was dropped big time when copy constructors were added to the language, since core language features were not updated to work with them, and they clearly weren't tested with them, or the problem would have been caught. And I'm fairly certain that there are similar problems with move constructors too, particularly since some of the druntime hooks use |
Hmmm. I've never used a dynamic array or an associative array, so I guess I haven't noticed that :/ So... what's going on with copy constructors if they don't work? They've been in a for a long time! Regarding move constructor issues; it's an experimental/unreleased feature, there's definitely a bunch of library work to do when the core mechanics feel solid. |
The basic language feature works if you're just dealing with a struct on the stack, but not all language features work with it. AFAIK, if you're not using dynamic arrays (and actually, static arrays might have the same problem, though I don't recall looking into that, so I don't know), and you're not using associative arrays, then you're probably fine. As with any language feature, it's possible that there are bugs that aren't known, but the part that I know is broken is that the druntime side of things simply was not implemented when copy constructors were added. When some of the druntime hooks were templatized, those were made to handle copy constructors in addition to postblit constructors, but So, if you're just passing around structs on the stack or dealing with them on the heap directly rather than in any kind of array, and you aren't interacting with the druntime hooks anywhere, then AFAIK, you're fine. But most people writing D code are going to be using dynamic arrays and associative arrays in at least some of their code, and those are simply broken with regards to copy constructors right now. It seems like when Walter (or whoever implemented copy constructors) implemented them, he completely forgot about the druntime hooks or just never got around to them. I did bring it up in a DLF meeting a few months ago with regards to move constructors precisely because I was hoping that they wouldn't fall into the same trap, but since In the ideal scenario here, we just templatize all of the druntime hooks and ditch
Honestly, that's part of why I was really pissed when I figured out that dynamic arrays and associative arrays don't work properly with them - especially since it caused me to waste a ton of time at work, because I'd wrongly assumed that they worked properly given that the feature wasn't new. The spec even currently tells folks that they should use copy constructors instead of postblit constructors (and I really should take the time to update what it says to make the situation clearer). So, it looks to me like when copy constructors were implemented, all that was really considered was structs on the stack and not all of the various language features that interact with structs, since it wouldn't have taken much testing to see that dynamic arrays and associative arrays couldn't handle them properly. And for better or worse, it's less obvious now, since they partially work with dynamic arrays thanks to some of the hooks being templatized, but clearly, when they were introduced, no such testing was done, because otherwise, it would have been obvious that the hooks had been forgotten.
Well, do whatever you need to do, but anyone who's in a situation where they actually need both copy or move constructors and features that require that the druntime hooks use them appropriately is kind of screwed, because not all of the hooks are going to work with them properly. If you're not using druntime at all (and from some of what you've said previously, I suspect that you aren't), then you're probably fine. In my case though, I had to ditch copy constructors and switch to postblit constructors, much as I would have liked to use copy constructors. |
Right... well, this issue is much larger than I imagined, but not less relevant. |
@WalterBright it seems this category of issues is a general blocker to the progression of copy/move semantics. Can you work with @jmdavis and the people who know where this is at to address the outstanding issues relating to copy semantics? We can't really expect to complete the move semantics work while copy semantics are still pending. |
Code like this:
It's just a normal struct, but I get these errors:
String
andArray
have copy constructors (and recently, move constructors), postblits are old and dead.It's frustrating that I have to write
this(this) @disable;
in basically every struct I write.Can we delete this error message, and make sure the compiler never attempt to generate a default postblit?
It should only attempt to use postblit semantics if there was one explicitly implemented, and it shouldn't be implicitly generating one, that's long behind us.
It might be the case the the implicitly generated copy-constructor actually needs to call the postblit for fields that have a postblit specified...
Ie; for any fields that have a postblit, instead of doing a copy initialisation, do a blit and call postblit, only for that field?
I'd personally even go so far as a compiler option that makes postblit completely deprecated; surely it's time?
I have run into situations where copy/move semantics and postblit semantics conflict, and resolution has required some really gnarly workarounds.
The text was updated successfully, but these errors were encountered: