On Friday, November 23, 2018 2:47:51 PM MST Tony via Digitalmars-d-learn wrote: > In std.compiler there is this code: > > /// Which vendor produced this compiler. > version(StdDdoc) Vendor vendor; > else version(DigitalMars) Vendor vendor = Vendor.digitalMars; > else version(GNU) Vendor vendor = Vendor.gnu; > else version(LDC) Vendor vendor = Vendor.llvm; > else version(D_NET) Vendor vendor = Vendor.dotNET; > else version(SDC) Vendor vendor = Vendor.sdc; > else Vendor vendor = Vendor.unknown; > > What is the situation in which the identifier StdDoc is set?
It's a Phobos-only replacement for the D_Ddoc version identifier and is defined as part of the Phobos build. As the others have been complaining about in this thread, ddoc is set up so that it takes whatever version is currently being compiled. So, version(D_Ddoc) is the standard way to provide documentation that is agnostic of the platform in the cases where a documented symbol doesn't exist on all platforms, or its definition differs such that it needs separate declarations - e.g. if the values of members in an enum differ across systems, then you're forced to provide completely separate enum declarations for the entire enum. If you have separate declarations on different platforms, then in general there are only three choices 1. Duplicate the documentation. 2. Set it up so that your documentation can only be built on one platform. 3. Use version(D_Ddoc) to provide a separate declaration just for the documentation. There are some cases where you can put the documentation outside the version block and have it work - e.g. /// my documentation version(linux) int foo(string bar) { ... } else version(Windows) int foo(string bar) { ... } else ... but that only works when you only need to document the top-level symbol (such as with a function). It does not work with anything that needs to have symbols inside it documented (such as with a struct, class, or enum). Fortunately, most code does need to be versioned like this (especially if you're trying to write platform-independent code like we try to do with Phobos), and often, when you do need to version stuff, it's inside implementations, but sometimes it does affect the top level. std.file has this problem in a few places as does std.datetime with WindowsTimeZone (since it only exists on Windows). The solution the language provides is to use version(D_Ddoc) to version such documentation. And that's what Phobos used to do. The problem is that once you start using version(D_Ddoc), you _must_ have a separate documentation build. You can't build your documentation as part of your normal build, because you'd be getting the version(D_Ddoc) stubs instead of the correct implementation for your platform (or instead of nothing at all if that platform isn't supposed to have that particular symbol). Phobos already had a separate documentation build because of how it generates the documentation for the website, but many people's projects do not. Most projects don't ever need to use version(D_Ddoc), because they don't have symbols that are platform-dependent, and so before Phobos started using it, they could compile their documentation as part of their normal build just fine, because version(D_Ddoc) wasn't in their code anywhere. But as soon as Phobos started using it, their code broke. If they had had a separate documentation build, then they wouldn't have had any problems, but as it was, their code was broken. So, for better or worse, rather than saying that it was just bad practice to do the documentation build as part of your normal build (and I would strongly argue that building the documentation as part of the normal build is bad practice given how doing so defines a new version identifier that can affect the build), it was decided that Phobos would stop using version(D_Ddoc) as the language intended and instead use its own custom, version identifier for the documentation - which is why we now have version(StdDoc) in Phobos and version(CoreDdoc) in druntime. With this change, anyone building with the -D flag as part of their normal build doesn't end up with version(D_Ddoc) screwing up their code because of druntime or Phobos. Some other project they depend on could screw it up, and if they ever use version(D_Ddoc) in their code, they'll have trouble again, but Phobos and druntime aren't going to mess them up in that regard. And while version(D_Ddoc) is the standard solution, because of this general problem with folks using -D with their normal build, it's arguably best practice at this point to create your own version identifier for your own documentation for any library that you release that needs to version its documentation. Otherwise, anyone using your library will have the same problems that resulted in Phobos switching from version(D_Ddoc) to version(StdDdoc) - which if anything shows that things work here probably should have been handled differently. Really, the way that -D is designed is similar to -unittest in that they're both intended to be used for builds other than your normal build. They create their own version identifiers and can change how the code compiles. And as such really should not be used as part of the normal build. But just like -unittest runs the unit tests by making them run before main, thus making it so that you can technically have the unit tests be part of your normal build (even if it's unwise), you can have the documentation as part of your normal build (even if it's unwise). Arguably, just like the complaints that Adam Ruppe and H.S. Teoh are making elsewhere in the thread, this aspect of how the compiler and language are designed to work is not the best designed. It works just fine if you understand the pitfalls, but having the unit tests and documentation treated in such a way that they can be part of the normal build instead of always replacing the normal build definitely is an area that sometimes causes problems for people. - Jonathan M Davis