Hi!
Lately, I've pushed some commits ([1], [2], [3]) that change syntax used
for some includes. I wanted to share my rationale behind that, along
with some notes about past discussion on this topic.
The topic is using one of two syntaxes described for #include directive
in standard (section [cpp.include]): in angular brackets <> vs in quotes
"". The standard reads:
2 A preprocessing directive of the form
# include < h-char-sequence > new-line
searches a sequence of implementation-defined places for a header
identified uniquely by the specified sequence
between the < and > delimiters, and causes the replacement of that
directive by the entire contents of the
header. How the places are specified or the header identified is
implementation-defined.
3 A preprocessing directive of the form
# include " q-char-sequence " new-line
causes the replacement of that directive by the entire contents of
the source file identified by the specified
sequence between the " delimiters. The named source file is searched
for in an implementation-defined
manner. If this search is not supported, or if the search fails, the
directive is reprocessed as if it read
# include < h-char-sequence > new-line
with the identical contained sequence (including > characters, if
any) from the original directive.
...
[ Note: Although an implementation may provide a mechanism for making
arbitrary source files available to
the < > search, in general programmers should use the < > form for
headers provided with the implementation,
and the " " form for sources outside the control of the implementation.
The discussion that took place at [4] raised some concerns on possible
problems due to inconsistent treatment of the quoted syntax in MS
compiler vs gcc. Namely, [5] states, that
The preprocessor searches for include files in this order:
1) In the same directory as the file that contains the #include
statement.
2) In the directories of the currently opened include files, in the
reverse order in which they were opened. The search begins in the
directory of the parent include file and continues upward through the
directories of any grandparent include files.
3) Along the path that's specified by each /I compiler option.
4) Along the paths that are specified by the INCLUDE environment
variable.
while [6] reads about quoted syntax:
This variant is used for header files of your own program. It
searches for a file named file first in the directory containing the
current file, then in the quote directories and then the same
directories used for <file>. You can prepend directories to the list of
quote directories with the -iquote option.
So, it is speculated that these differences might result in very hard to
trace bugs. Thus, it was suggested to use <> syntax uniformly, to avoid
that possibility.
However, doing so creates some problems, at least with IDE integration
with VisualStudio. The generated project, naturally, doesn't add
file-specific include paths to each file, to include the files'
directories. This makes the includes of headers sitting in the same
directory as the source file, referenced using <> syntax, to fail in the
editor's parser, and errors (failed includes + unknown identifiers)
being highlighted (underlined with red) in editor window. This impairs
the ease of use of the IDE aids (e.g., Intellisense, and error
highlighting that gets masked by false errors throughout the code).
Here I propose an updated rule to follow in the use of includes in the
project's code:
1. Use *only* <> syntax for any include that resides in include paths
explicitly defined in the module's mk file (gb_Library_set_include),
global includes ($INCLUDE), e.g., /include, and system headers (<vector>
or <Windows.h>) - these are interface headers.
As all implementations agree to use both implementation include places
and -I-defined places as search paths for <> syntax, this will likely
not allow inconsistency problems (and is actually what is used now in
most of the code).
2. Use *only* <> syntax for includes inside headers that reside in such
places (e.g., no header in /include should include other headers using
"" itself). This is aimed to prevent cases where some header placed in
the current source's directory would conflict with an include referred
from a global interface header.
3. *Always* use "" syntax *only* for includes that refer to headers
placed next to the current source in the same directory (or
subdirectories), i.e. that would be found using the "." entry of -I
switch. These are implementation headers. This applies to both includes
in c[xx] files as well as in h[xx] residing in directories like
/sw/source/core/access (as opposed to those in /sw/inc).
As all implementations search current source's directory first for
includes referred using "" syntax, as a side effect, these rules will
(1) speed up searching for same-directory implementation headers (which
is intended when "" is used) - the results will be immediately
available; and (2) somewhat speed up searching for interface includes
that will be converted from current "" syntax to <>, because their
search path will not be prepended with current source's directory.
Please share your opinions and concerns on this matter. I hope to
continue implementing this policy in my future commits, to improve my
coding experience using VS IDE.
I was asked to put the policy into README.md. Please advise, which
README.md is suitable for such information (I assume, the one in /, but
probably it's worth creating one in /include ?).
Thank you for consideration.
[1]
https://cgit.freedesktop.org/libreoffice/core/commit/?id=633f405701fc5cadfa73e950f7a8c122ad01c149
[2]
https://cgit.freedesktop.org/libreoffice/core/commit/?id=68d61a93819fd502630083a7080f099c4c218092
[3]
https://cgit.freedesktop.org/libreoffice/core/commit/?id=b567cfb980435df131d776915bce9152135bdf0f
[4] https://bugs.documentfoundation.org/show_bug.cgi?id=65108
[5] https://msdn.microsoft.com/en-us/library/36k2cdd4
[6] https://gcc.gnu.org/onlinedocs/cpp/Include-Syntax.html
--
Best regards,
Mike Kaganski
Context
- C[++]: Normalizing include syntax ("" vs <>) · Kaganski Mike
Privacy Policy |
Impressum (Legal Info) |
Copyright information: Unless otherwise specified, all text and images
on this website are licensed under the
Creative Commons Attribution-Share Alike 3.0 License.
This does not include the source code of LibreOffice, which is
licensed under the Mozilla Public License (
MPLv2).
"LibreOffice" and "The Document Foundation" are
registered trademarks of their corresponding registered owners or are
in actual use as trademarks in one or more countries. Their respective
logos and icons are also subject to international copyright laws. Use
thereof is explained in our
trademark policy.