-
Notifications
You must be signed in to change notification settings - Fork 5.4k
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
library writers should include their own headers as users of their library would #1609
Comments
I opened this issue from feedback on SF.12: We need a new guideline to cover how library creators should manage their headers and includes:
I did not add it to SF.12 because SF.12 tells you what to use if you're accessing a file at a local path. it does not tell you whether or not you should access a file from the local path or <> search path (typically there's not ambiguity and there is only one file that exists, but if there is multiple, the user must decide what they want; however this is not the case for library creators who reference their own headers... they must choose to reference them from the same path their users will) |
So what? Even installed, the relative paths between the headers inside a library usually remain the same, so there is no reason why a library header must use the angle bracket form. Personally I don't have a strong feeling one way or the other and never had to decide this convention for any project of significant size. However I will say, that with the |
I should clarify that this stems as a corollary from Without that PR, the title could be more along the lines of "the library writer must include their headers along the user-defined search path and not the local search available to the library writer"
the relative paths may remain the same, but those relative paths are not available to the user: the writer can include bar.h from foo.h as #include "bar.h". but then it will break user code: because when user code sees the statement #include "bar.h" from foo.h, it has no such include "bar.h". Note, the user should not modify the include search path so that #include "bar.h" actually resolves because if they did that, then all libraries providing "bar.h" would collide. (instead, the recommendation as in the above example is to modify the search path so that the header is found uniquely under a namespace like "author/library/header.h") Instead, the library writer must include bar.h as the user would: This way, when user code includes foo.h the include of bar.h will be found in the same way the user found foo.h. My proposed changes to SF.12 are to use <> for user includes and "" for local includes because this resolves disambiguity of what users intended (did you mean to include from the header search path, or locally?) Taking both guidelines together (this issue and the proposed SF.12 PR), you get "library writers should always include their headers using <>" |
Have you actually verified your claim? Either I completely misunderstand you or this is plainly not true. Relative include statements are resolved always relative to the header in which they are written. Doesn't matter how that particular header was found in the first place. |
Yes, you're right. I'm way off here and I'll need follow up with the original poster (Quux) on what they meant. I may have been misinterpreting this behavior from that. or I may have been thinking of an unrelated common practice like: but that neither has impact on SF.12 or this issue at hand. I can see your point for doing it the other way -- at least if foo.h includes "bar.h" it can be assured it is the bar collocated with foo.h versus picking up whatever bar.h happens to live at <author/lib/bar.h> (although this would very likely be the same bar.h) Thanks for making me work the example. I'm going to close this issue and circle back with the original poster. |
Edit:
This is a follow up from a comment on e47463c
Where library writers are including their own headers, they should prefer to do so the same way they would expect their users to. So for example, if you are creating foo.h and bar.h as part of some_lib, even though you could include bar.h locally as #include "bar.h" your users will not have bar.h at this local path. Instead, if you would expect your users to consume foo.h as "#include <author/library/foo.h>" then from foo.h, you should include bar.h as "#include <author/library/bar.h>"
Taking this guidance (that we should add to the GSL) combined with my PR to SF.12 this then translates succinctly to "if you're writing a library, you must use the angle-bracket form" because it encapsulates that if you're using the <> form it implies you are not including via the local relative path. From the original post:
If you're writing a library, you must use the angle-bracket form:
This line will work no matter whether
mine/mine.h
is located in~/sourcetree/src/
or in/usr/include
— basically, if anybody ever includes this file via#include <mine/mine.h>
, then we automatically know that the exact same include-search-path will be able to find<mine/detail.h>
. On the other hand, doing#include "detail.h"
might or might not work (depending on compiler options that ought to be irrelevant to us as library writers).Originally posted by @Quuxplusone in #1596 (comment)
The text was updated successfully, but these errors were encountered: