Groups | Search | Server Info | Keyboard shortcuts | Login | Register [http] [https] [nntp] [nntps]


Groups > comp.lang.c > #120617 > unrolled thread

Re: style question - includes

Started byjameskuyper@verizon.net
First post2017-09-30 12:25 -0700
Last post2017-10-02 16:11 -0400
Articles 9 — 5 participants

Back to article view | Back to comp.lang.c

This discussion starts older than the indexed window; earlier articles aren't shown. The article labeled Started by below is the oldest one visible, not the original post.


Contents

  Re: style question - includes jameskuyper@verizon.net - 2017-09-30 12:25 -0700
    Re: style question - includes Thiago Adams <thiago.adams@gmail.com> - 2017-09-30 13:40 -0700
    Re: style question - includes supercat@casperkitty.com - 2017-09-30 14:04 -0700
      Re: style question - includes Keith Thompson <kst-u@mib.org> - 2017-09-30 15:36 -0700
        Re: style question - includes supercat@casperkitty.com - 2017-10-01 16:07 -0700
          Re: style question - includes Keith Thompson <kst-u@mib.org> - 2017-10-01 19:28 -0700
            Re: style question - includes supercat@casperkitty.com - 2017-10-02 12:25 -0700
              Re: style question - includes Keith Thompson <kst-u@mib.org> - 2017-10-02 12:49 -0700
                Re: style question - includes "James R. Kuyper" <jameskuyper@verizon.net> - 2017-10-02 16:11 -0400

#120617 — Re: style question - includes

Fromjameskuyper@verizon.net
Date2017-09-30 12:25 -0700
SubjectRe: style question - includes
Message-ID<53b3579e-0720-48fc-8869-fde0c55f169a@googlegroups.com>
On Tuesday, August 22, 2017 at 12:39:47 PM UTC-4, Thiago Adams wrote:
> In my code, I generally use #include with relative paths.
> 
> For instance:
> 
> --MyLibFile1.h---
> #include "MyLibFile2.h"
> 
> I use #include <other.h> for external libraries.
> 
> I have seen some code using #include <> in the situation I 
> described with MyLibFile1.h including MyLibFile2.h.
> 
> Do you see some advantage on this style of include <> when the two 
> files are at fixed position from each other?

No. The distinction between absolute and relative file names has no particular
connection to the differences between #include<> and #include"".

There are differences between the two forms, and it's important to to know what
they are, when deciding which one to use. There's an implementation-defined set
of places that are searched for a header file when you use #include <>. There's
also an implementation-defined set of places that are searched when you use
#include "". However, when you use #include "", and the search fails, the
implementation must then re-process the directive as if you had used #include
<>. Note that standard headers can always be located using either form.

The full significance of those rules can only be understood by knowing what
places the particular implementation that you're using has defined as being
searched; there's not much that you can say that is portably true.

However, there are some things that you can say portably: the places that are
searched fall into three categories (some of which might be empty):
A. those that are searched only by #include ""
B. Those that are searched by #include<>, and also during the first search done
by #include "".
C. Those that are searched by #include<>, but are only searched by #include ""
during it's second search.

If there are any locations that are not in category B, a #include "" search
could take slightly longer than a #include <> search, which is a reason to favor
#include <> for those headers that it's guaranteed to find. On the other hand,
if the file you want to include is in one of the locations in category A, you
must used #include "".

Furthermore, if a file can be found in a location that is in category A, and a
file with the same name but different contents can be found in a location that's
in category C, then #include "" will find the first file, and ignore the second
one. If you want the first file to override the second one, then you should use
#include ""; if you need to ensure that only the second one is found, use
#include <>.
Note that "If a file with the same name as one of the [standard headers], not
provided as part of the implementation, is placed in any of the standard places
that are searched for included source files, the behavior is undefined."
(7.1.2p3). That means that you cannot deliberately override the standard headers
with defined behavior by putting a replacement in a place that would get
searched first.

You can minimize the chance of accidentally running afoul of 7.1.2p3 when
including standard headers by using the more restricted search provided by
#include <>. That is why I use #include<> for standard headers (including those
that are defined by POSIX rather than by the C standard), and #include "" for
all other header files.

[toc] | [next] | [standalone]


#120622

FromThiago Adams <thiago.adams@gmail.com>
Date2017-09-30 13:40 -0700
Message-ID<63a3492a-0118-4627-ba5c-417cf97f06f7@googlegroups.com>
In reply to#120617
On Saturday, September 30, 2017 at 4:25:25 PM UTC-3, james...@verizon.net wrote:
> On Tuesday, August 22, 2017 at 12:39:47 PM UTC-4, Thiago Adams wrote:
> > In my code, I generally use #include with relative paths.
> > 
> > For instance:
> > 
> > --MyLibFile1.h---
> > #include "MyLibFile2.h"
> > 
> > I use #include <other.h> for external libraries.
> > 
> > I have seen some code using #include <> in the situation I 
> > described with MyLibFile1.h including MyLibFile2.h.
> > 
> > Do you see some advantage on this style of include <> when the two 
> > files are at fixed position from each other?
> 
> No. The distinction between absolute and relative file names has no particular
> connection to the differences between #include<> and #include"".

I have seen both styles. I guess I understand well the differences,
so my question is more about style, not how it works.

I think some people like to use < >  so they can change 
if they want some libraries inside the same dir of project
or separated.

#include  <mylib1.h>

then they can choose if they want to copy-paste mylib1.h
to the project folder or keep it separately.

Generally I copy, them I get static "version" of the lib.
and I use #include "\MyLib\MyLib.h"
I avoid to share. (But then if lib1 is updated I have to copy)

[toc] | [prev] | [next] | [standalone]


#120627

Fromsupercat@casperkitty.com
Date2017-09-30 14:04 -0700
Message-ID<7e264fae-2cac-449a-a453-432302ea79ce@googlegroups.com>
In reply to#120617
On Saturday, September 30, 2017 at 2:25:25 PM UTC-5, james...@verizon.net wrote:
> However, there are some things that you can say portably: the places that are
> searched fall into three categories (some of which might be empty):
> A. those that are searched only by #include ""
> B. Those that are searched by #include<>, and also during the first search done
> by #include "".
> C. Those that are searched by #include<>, but are only searched by #include ""
> during it's second search.

By my understanding, an implementation would allow an implementation
to process e.g. #include <stdio.h> by defining a bunch of macros and
outputting an intrinsic to define a bunch of identifiers.  I would
expect that even (especially!) in the 1980s such an approach could
have greatly cut down on compilation times (in the days before prototypes,
most headers were short enough that simply processing them directly
wasn't too bad).  I don't think an implementation is required to let
programmers process files as literal includes when using the <filename.h>
form; all that's necessary is that the specific names in the Standard
work as described therein.

[toc] | [prev] | [next] | [standalone]


#120633

FromKeith Thompson <kst-u@mib.org>
Date2017-09-30 15:36 -0700
Message-ID<lnvajzstja.fsf@kst-u.example.com>
In reply to#120627
supercat@casperkitty.com writes:
> On Saturday, September 30, 2017 at 2:25:25 PM UTC-5, james...@verizon.net wrote:
>> However, there are some things that you can say portably: the places that are
>> searched fall into three categories (some of which might be empty):
>> A. those that are searched only by #include ""
>> B. Those that are searched by #include<>, and also during the first search done
>> by #include "".
>> C. Those that are searched by #include<>, but are only searched by #include ""
>> during it's second search.
>
> By my understanding, an implementation would allow an implementation
> to process e.g. #include <stdio.h> by defining a bunch of macros and
> outputting an intrinsic to define a bunch of identifiers.

Right.  N1570 6.10.2 says that #include <...> searches for a *header*,
while #include "..." searches for a *source file* (and falls back to the
<...> search).  I don't think the standard defines what a "header" is,
which means it can be anything that acts like an includable source file.

[...]

-- 
Keith Thompson (The_Other_Keith) kst-u@mib.org  <http://www.ghoti.net/~kst>
Working, but not speaking, for JetHead Development, Inc.
"We must do something.  This is something.  Therefore, we must do this."
    -- Antony Jay and Jonathan Lynn, "Yes Minister"

[toc] | [prev] | [next] | [standalone]


#120674

Fromsupercat@casperkitty.com
Date2017-10-01 16:07 -0700
Message-ID<95591c55-890b-496e-8f94-5f5241516849@googlegroups.com>
In reply to#120633
On Saturday, September 30, 2017 at 5:36:49 PM UTC-5, Keith Thompson wrote:
> Right.  N1570 6.10.2 says that #include <...> searches for a *header*,
> while #include "..." searches for a *source file* (and falls back to the
> <...> search).  I don't think the standard defines what a "header" is,
> which means it can be anything that acts like an includable source file.

As a further note, inclusion of headers is only allowed in certain contexts,
while source files may be included in many other contexts.  For example,
given

const int build_count = 0
#include "counter.inc"
;

a compiler would be required to process the inclusion as though the #include
directive were replaced by the contents of counter.inc, despite the fact that
the directive is in a weird context.  If counter.inc is generated by a shell
script

   echo +1 >> counter.inc

which runs every time the program is compiled, such a context might be
perfectly useful.  By contrast, the Standard would impose no requirement
about what should happen if code tried to #include <stdio.h> in the spot
above.  Such action might yield behavior consistent with the effects of
inserting the text of a valid <stdio.h> header there, but it need not do
so.  It could also simply produce a "Headers may not be included in this
context" diagnostic whether or not there would be any way to write a file
that would be able to detect the context where it was included.

[toc] | [prev] | [next] | [standalone]


#120677

FromKeith Thompson <kst-u@mib.org>
Date2017-10-01 19:28 -0700
Message-ID<lnfub2s2p8.fsf@kst-u.example.com>
In reply to#120674
supercat@casperkitty.com writes:
> On Saturday, September 30, 2017 at 5:36:49 PM UTC-5, Keith Thompson wrote:
>> Right.  N1570 6.10.2 says that #include <...> searches for a *header*,
>> while #include "..." searches for a *source file* (and falls back to the
>> <...> search).  I don't think the standard defines what a "header" is,
>> which means it can be anything that acts like an includable source file.
>
> As a further note, inclusion of headers is only allowed in certain contexts,
> while source files may be included in many other contexts.

There are restriction on where the language-defined standard headers can
meaningfully be included.  I don't think there's any such restriction on
where other headers can be included (though particular headers might
impose their own restrictions0.

[...]

>      It could also simply produce a "Headers may not be included in this
> context" diagnostic whether or not there would be any way to write a file
> that would be able to detect the context where it was included.

Have you seen such a diagnostic?

-- 
Keith Thompson (The_Other_Keith) kst-u@mib.org  <http://www.ghoti.net/~kst>
Working, but not speaking, for JetHead Development, Inc.
"We must do something.  This is something.  Therefore, we must do this."
    -- Antony Jay and Jonathan Lynn, "Yes Minister"

[toc] | [prev] | [next] | [standalone]


#120706

Fromsupercat@casperkitty.com
Date2017-10-02 12:25 -0700
Message-ID<f8f6de40-09bb-406b-bce7-a1d124a5618f@googlegroups.com>
In reply to#120677
On Sunday, October 1, 2017 at 9:29:46 PM UTC-5, Keith Thompson wrote:
> supercat@casperkitty.com writes:
> > On Saturday, September 30, 2017 at 5:36:49 PM UTC-5, Keith Thompson wrote:
> >> Right.  N1570 6.10.2 says that #include <...> searches for a *header*,
> >> while #include "..." searches for a *source file* (and falls back to the
> >> <...> search).  I don't think the standard defines what a "header" is,
> >> which means it can be anything that acts like an includable source file.
> >
> > As a further note, inclusion of headers is only allowed in certain contexts,
> > while source files may be included in many other contexts.
> 
> There are restriction on where the language-defined standard headers can
> meaningfully be included.  I don't think there's any such restriction on
> where other headers can be included (though particular headers might
> impose their own restrictions0.

Does the Standard say anything about the effect of including any headers
other than the ones listed therein?

> >      It could also simply produce a "Headers may not be included in this
> > context" diagnostic whether or not there would be any way to write a file
> > that would be able to detect the context where it was included.
> 
> Have you seen such a diagnostic?

Every system I've used has processed the <> form of #include by inserting
text from a file stored someplace.  I find it somewhat curious that I've
never seen system do anything else, given that that standard-header file
processing used to represent a significant fraction of overall compilation
time, but the Standard would certainly allow such behavior, and would
expect that systems which process headers in a way different from files
would have different diagnostics associated with them.

[toc] | [prev] | [next] | [standalone]


#120711

FromKeith Thompson <kst-u@mib.org>
Date2017-10-02 12:49 -0700
Message-ID<ln3771s52y.fsf@kst-u.example.com>
In reply to#120706
supercat@casperkitty.com writes:
> On Sunday, October 1, 2017 at 9:29:46 PM UTC-5, Keith Thompson wrote:
>> supercat@casperkitty.com writes:
>> > On Saturday, September 30, 2017 at 5:36:49 PM UTC-5, Keith Thompson wrote:
>> >> Right.  N1570 6.10.2 says that #include <...> searches for a *header*,
>> >> while #include "..." searches for a *source file* (and falls back to the
>> >> <...> search).  I don't think the standard defines what a "header" is,
>> >> which means it can be anything that acts like an includable source file.
>> >
>> > As a further note, inclusion of headers is only allowed in certain contexts,
>> > while source files may be included in many other contexts.
>> 
>> There are restriction on where the language-defined standard headers can
>> meaningfully be included.  I don't think there's any such restriction on
>> where other headers can be included (though particular headers might
>> impose their own restrictions0.
>
> Does the Standard say anything about the effect of including any headers
> other than the ones listed therein?

Yes, C11 6.10.2p2:

    ... and causes the replacement of that directive by the entire
    contents of the header.

Of course the effect depends on the contents of the header.

>> >      It could also simply produce a "Headers may not be included in this
>> > context" diagnostic whether or not there would be any way to write a file
>> > that would be able to detect the context where it was included.
>> 
>> Have you seen such a diagnostic?
>
> Every system I've used has processed the <> form of #include by inserting
> text from a file stored someplace.  I find it somewhat curious that I've
> never seen system do anything else, given that that standard-header file
> processing used to represent a significant fraction of overall compilation
> time, but the Standard would certainly allow such behavior, and would
> expect that systems which process headers in a way different from files
> would have different diagnostics associated with them.

You could have just said "no".

6.10.2 says nothing about the context in which a header may be included.
It imposes some rules for the standard headers.

7.1.2p4 is a bit ambiguous:

    Standard headers may be included in any order; each may
    be included more than once in a given scope, with no effect
    different from being included only once, except that the effect
    of including <assert.h> depends on the definition of NDEBUG
    (see 7.2). If used, a header shall be included outside of
    any external declaration or definition, and it shall first be
    included before the first reference to any of the functions or
    objects it declares, or to any of the types or macros it defines.

I *think* that the second sentence is meant to apply to the standard
headers, not to headers in general (which might be supplied by the
implementation or by the programmer), but inserting the word "standard"
would improve the clarity.  For example, I think that this:

    int n =
    #include <value_of_n.h>
    ;

should be valid if the header contains nothing but the constant 42.
(Of course that's a contrived example.  It's easy to think of more
plausible examples.)

-- 
Keith Thompson (The_Other_Keith) kst-u@mib.org  <http://www.ghoti.net/~kst>
Working, but not speaking, for JetHead Development, Inc.
"We must do something.  This is something.  Therefore, we must do this."
    -- Antony Jay and Jonathan Lynn, "Yes Minister"

[toc] | [prev] | [next] | [standalone]


#120712

From"James R. Kuyper" <jameskuyper@verizon.net>
Date2017-10-02 16:11 -0400
Message-ID<224edd85-454d-d754-9dfc-a68f0aebb77f@verizon.net>
In reply to#120711
On 2017-10-02 15:49, Keith Thompson wrote:
...
> I *think* that the second sentence is meant to apply to the standard
> headers, not to headers in general (which might be supplied by the
> implementation or by the programmer), but inserting the word "standard"
> would improve the clarity.  For example, I think that this:
> 
>      int n =
>      #include <value_of_n.h>
>      ;
> 
> should be valid if the header contains nothing but the constant 42.
> (Of course that's a contrived example.  It's easy to think of more
> plausible examples.)
> 

"Each library function is declared, with a type that includes a 
prototype, in a header, 182) whose contents are made available by the 
#include preprocessing directive. ..." (7.1.2p1). The term "header" is 
italicized, to indicate that this clause serves as the official 
definition of the term. The standard says a great many things about 
"library functions", and most of them seem rather unreasonable unless 
they apply only to functions that are part of the C standard library. 
Interpreting those statements as applying to arbitrary libraries imposes 
a lot of requirements that are frequently violated by real-world libraries.
If you read supercat's message with the belief that "header" can only 
refer to C standard library headers, it makes a lot more sense.

[toc] | [prev] | [standalone]


Back to top | Article view | comp.lang.c


csiph-web