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


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

Meta-C question about header order

Started byJens Schweikhardt <usenet@schweikhardt.net>
First post2014-04-12 19:37 +0000
Last post2014-06-10 09:40 -0700
Articles 20 on this page of 69 — 15 participants

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


Contents

  Meta-C question about header order Jens Schweikhardt <usenet@schweikhardt.net> - 2014-04-12 19:37 +0000
    Re: Meta-C question about header order Keith Thompson <kst-u@mib.org> - 2014-04-12 13:51 -0700
      Re: Meta-C question about header order glen herrmannsfeldt <gah@ugcs.caltech.edu> - 2014-04-13 00:11 +0000
      Re: Meta-C question about header order Jens Schweikhardt <usenet@schweikhardt.net> - 2014-04-13 11:40 +0000
        Re: Meta-C question about header order "BartC" <bc@freeuk.com> - 2014-04-13 13:10 +0100
        Re: Meta-C question about header order Malcolm McLean <malcolm.mclean5@btinternet.com> - 2014-04-13 06:29 -0700
        Re: Meta-C question about header order Kaz Kylheku <kaz@kylheku.com> - 2014-04-13 14:41 +0000
      Re: Meta-C question about header order Ken Brody <kenbrody@spamcop.net> - 2014-04-15 10:36 -0400
    Re: Meta-C question about header order Richard Damon <Richard@Damon-Family.org> - 2014-04-12 16:58 -0400
      Re: Meta-C question about header order Kaz Kylheku <kaz@kylheku.com> - 2014-04-13 03:40 +0000
        Re: Meta-C question about header order Ian Collins <ian-news@hotmail.com> - 2014-04-13 16:26 +1200
          Re: Meta-C question about header order Kaz Kylheku <kaz@kylheku.com> - 2014-04-13 05:02 +0000
            Re: Meta-C question about header order Ian Collins <ian-news@hotmail.com> - 2014-04-13 17:21 +1200
              Re: Meta-C question about header order Ken Brody <kenbrody@spamcop.net> - 2014-04-15 10:59 -0400
              Re: Meta-C question about header order Ken Brody <kenbrody@spamcop.net> - 2014-04-15 11:02 -0400
            Re: Meta-C question about header order Ken Brody <kenbrody@spamcop.net> - 2014-04-15 10:59 -0400
              Re: Meta-C question about header order Malcolm McLean <malcolm.mclean5@btinternet.com> - 2014-04-15 08:26 -0700
              Re: Meta-C question about header order Kaz Kylheku <kaz@kylheku.com> - 2014-04-15 15:56 +0000
        Re: Meta-C question about header order Jens Schweikhardt <usenet@schweikhardt.net> - 2014-04-13 11:34 +0000
        Re: Meta-C question about header order Richard Damon <Richard@Damon-Family.org> - 2014-04-13 15:04 -0400
        Re: Meta-C question about header order Ken Brody <kenbrody@spamcop.net> - 2014-04-15 10:52 -0400
    Re: Meta-C question about header order Ian Collins <ian-news@hotmail.com> - 2014-04-13 11:09 +1200
      Re: Meta-C question about header order Jens Schweikhardt <usenet@schweikhardt.net> - 2014-04-13 11:47 +0000
        Re: Meta-C question about header order Ian Collins <ian-news@hotmail.com> - 2014-04-14 08:54 +1200
          Re: Meta-C question about header order Kaz Kylheku <kaz@kylheku.com> - 2014-04-13 21:37 +0000
            Re: Meta-C question about header order Ian Collins <ian-news@hotmail.com> - 2014-04-14 09:49 +1200
          Re: Meta-C question about header order Jens Schweikhardt <usenet@schweikhardt.net> - 2014-04-14 19:17 +0000
            Re: Meta-C question about header order Ian Collins <ian-news@hotmail.com> - 2014-04-15 10:24 +1200
              Re: Meta-C question about header order Jens Schweikhardt <usenet@schweikhardt.net> - 2014-04-16 19:58 +0000
            Re: Meta-C question about header order Richard Damon <Richard@Damon-Family.org> - 2014-04-14 21:45 -0400
    Re: Meta-C question about header order luser- -droog <luser.droog@gmail.com> - 2014-04-12 16:48 -0700
      Re: Meta-C question about header order Jens Schweikhardt <usenet@schweikhardt.net> - 2014-04-13 11:52 +0000
    Re: Meta-C question about header order Kaz Kylheku <kaz@kylheku.com> - 2014-04-13 01:04 +0000
    Re: Meta-C question about header order "BartC" <bc@freeuk.com> - 2014-04-13 10:15 +0100
      Re: Meta-C question about header order Malcolm McLean <malcolm.mclean5@btinternet.com> - 2014-04-13 04:06 -0700
      Re: Meta-C question about header order Jens Schweikhardt <usenet@schweikhardt.net> - 2014-04-13 12:01 +0000
        Re: Meta-C question about header order "BartC" <bc@freeuk.com> - 2014-04-13 13:46 +0100
          Re: Meta-C question about header order Jens Schweikhardt <usenet@schweikhardt.net> - 2014-04-13 13:58 +0000
    Re: Meta-C question about header order Jens Schweikhardt <usenet@schweikhardt.net> - 2014-04-13 11:29 +0000
      Re: Meta-C question about header order Martin Shobe <martin.shobe@yahoo.com> - 2014-04-13 08:48 -0500
        Re: Meta-C question about header order Jens Schweikhardt <usenet@schweikhardt.net> - 2014-04-13 14:25 +0000
          Re: Meta-C question about header order Kaz Kylheku <kaz@kylheku.com> - 2014-04-13 15:02 +0000
          Re: Meta-C question about header order Martin Shobe <martin.shobe@yahoo.com> - 2014-04-13 21:45 -0500
            Re: Meta-C question about header order Malcolm McLean <malcolm.mclean5@btinternet.com> - 2014-04-14 01:16 -0700
              Re: Meta-C question about header order "BartC" <bc@freeuk.com> - 2014-04-14 10:16 +0100
              Re: Meta-C question about header order Richard Damon <Richard@Damon-Family.org> - 2014-04-14 21:33 -0400
            Re: Meta-C question about header order Kaz Kylheku <kaz@kylheku.com> - 2014-04-14 16:25 +0000
              Re: Meta-C question about header order Malcolm McLean <malcolm.mclean5@btinternet.com> - 2014-04-14 09:47 -0700
              Re: Meta-C question about header order Martin Shobe <martin.shobe@yahoo.com> - 2014-04-14 13:29 -0500
                Re: Meta-C question about header order Kaz Kylheku <kaz@kylheku.com> - 2014-04-14 19:31 +0000
                  Re: Meta-C question about header order Les Cargill <lcargill99@comcast.com> - 2014-04-14 20:03 -0500
                    Re: Meta-C question about header order Kaz Kylheku <kaz@kylheku.com> - 2014-04-15 01:04 +0000
                Re: Meta-C question about header order Keith Thompson <kst-u@mib.org> - 2014-04-14 15:15 -0700
              Re: Meta-C question about header order Richard Damon <Richard@Damon-Family.org> - 2014-04-14 22:01 -0400
              Re: Meta-C question about header order "BartC" <bc@freeuk.com> - 2014-04-15 09:51 +0100
                Re: Meta-C question about header order Malcolm McLean <malcolm.mclean5@btinternet.com> - 2014-04-15 06:01 -0700
                  Re: Meta-C question about header order "BartC" <bc@freeuk.com> - 2014-04-15 14:29 +0100
                    Re: Meta-C question about header order Malcolm McLean <malcolm.mclean5@btinternet.com> - 2014-04-15 10:38 -0700
                    Re: Meta-C question about header order Kaz Kylheku <kaz@kylheku.com> - 2014-04-15 18:27 +0000
                      Re: Meta-C question about header order Malcolm McLean <malcolm.mclean5@btinternet.com> - 2014-04-15 12:45 -0700
                        Re: Meta-C question about header order ralph <nt_consulting@yahoo.com> - 2014-04-15 22:02 -0500
            Re: Meta-C question about header order Jens Schweikhardt <usenet@schweikhardt.net> - 2014-04-14 17:44 +0000
    Re: Meta-C question about header order Tim Rentsch <txr@alumni.caltech.edu> - 2014-04-19 01:25 -0700
      Re: Meta-C question about header order Richard Damon <Richard@Damon-Family.org> - 2014-04-19 10:30 -0400
        Re: Meta-C question about header order Jens Schweikhardt <usenet@schweikhardt.net> - 2014-04-23 19:47 +0000
          Re: Meta-C question about header order James Kuyper <jameskuyper@verizon.net> - 2014-04-23 15:53 -0400
        Re: Meta-C question about header order Tim Rentsch <txr@alumni.caltech.edu> - 2014-06-10 09:25 -0700
      Re: Meta-C question about header order Jens Schweikhardt <usenet@schweikhardt.net> - 2014-04-23 19:27 +0000
        Re: Meta-C question about header order Tim Rentsch <txr@alumni.caltech.edu> - 2014-06-10 09:40 -0700

Page 2 of 4 — ← Prev page 1 [2] 3 4  Next page →


#42967

FromKen Brody <kenbrody@spamcop.net>
Date2014-04-15 10:52 -0400
Message-ID<lijh3j$ee8$1@dont-email.me>
In reply to#42855
On 4/12/2014 11:40 PM, Kaz Kylheku wrote:
> On 2014-04-12, Richard Damon <Richard@Damon-Family.org> wrote:
>> On 4/12/14, 3:37 PM, Jens Schweikhardt wrote:
>>> hello, world\n
>>>
>>> consider a small project of 100 C source and 100 header files.
>>> The coding rules require that only C files include headers,
>>> headers are not allowed to include other headers (not sure if
>>> this is 100% the "IWYU - Include What You Use" paradigma).
>>>
>>
>> A rule that says that a header can NOT include other headers, even if it
>> depends on the contents of that header is, in my mind, totally broken.
>
> I used to think so fresh out of school.
>
> But actually, this style is superior because leads to much cleaner code
> organization and faster compilation. It keeps everything "tight".

I disagree there.  Yes, perhaps including <my_entire_library_header.h> might 
not be the best idea if you want a "tight" compile.  (Though I see no 
problem having such a header, and allowing the user to decide.)  However, 
there's no reason you can't break down headers into functional groupings 
(which, admittedly, might contain some things you don't use), and which in 
turn #include those other headers that are needed.

Why should you require that every source module which uses your library know 
which other parts of your library are required?  And, should an update to 
your library mean that one of the headers now depends on an additional 
header, why should the user have to go through every source module and add it?

> I chose this approach in the TXR project, and am very pleased with it.
> I understand now why some people recommend it.

If it works for you, go for it.

[...]
> Also, the dependencies are easy to understand. If you look at the
> list of #include directives at the top of a .c file, those are
> the files which, if they are touched, will trigger a re-compile
> of this file. And no others!
>
> It's easy to generate a dependency makefile. If we have a foo.c
> with these contents:
>
>    #include <stdio.h>
>    #include "a.h"
>    #include "b.h"
>    #include "foo.h"
>
> then the dependency rule is precisely this:
>
>    foo.o: foo.c a.h b.h foo.h

My complaint, as noted above, is what happens if "foo." version 2.0 requires 
"c.h" as well?

> Done! At a glance we know all the dependencies. Our regular confrontation with
> these dependencies in every source file prevents us from screwing up the
> program with a spaghetti of creeping dependencies.

Honestly, I think it's just the opposite.  When you add a dependency, "we" 
need to now update every module that used the now-dependent header.  The 
"creeping dependencies" will happen as a project/library grows.  It's just a 
matter of whether "we" need to know about it, or if the implementation "just 
does it".

[...]

-- 
Kenneth Brody

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


#42829

FromIan Collins <ian-news@hotmail.com>
Date2014-04-13 11:09 +1200
Message-ID<bqtvckFb55cU5@mid.individual.net>
In reply to#42821
Jens Schweikhardt wrote:
> hello, world\n
>
> consider a small project of 100 C source and 100 header files.
> The coding rules require that only C files include headers,
> headers are not allowed to include other headers (not sure if
> this is 100% the "IWYU - Include What You Use" paradigma).

I agree with the other comments of the folly of this rule.  Don't do it!

Just take a look at some of your system headers, or popular open source 
library headers and consider whether you want all of the conditional 
includes and other and unnecessary nonsense in all of your source files?

-- 
Ian Collins

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


#42868

FromJens Schweikhardt <usenet@schweikhardt.net>
Date2014-04-13 11:47 +0000
Message-ID<bqvbraFhg97U4@mid.individual.net>
In reply to#42829
Ian Collins <ian-news@hotmail.com> wrote
	in <bqtvckFb55cU5@mid.individual.net>:
# Jens Schweikhardt wrote:
#> hello, world\n
#>
#> consider a small project of 100 C source and 100 header files.
#> The coding rules require that only C files include headers,
#> headers are not allowed to include other headers (not sure if
#> this is 100% the "IWYU - Include What You Use" paradigma).
# 
# I agree with the other comments of the folly of this rule.  Don't do it!
# 
# Just take a look at some of your system headers, or popular open source 
# library headers and consider whether you want all of the conditional 
# includes and other and unnecessary nonsense in all of your source files?

The "unnecessary nonsense" is all the #ifndef crap in third party
headers. Looking at system headers makes me cringe. It's not a role
model.

There's a reason why the lint we use (Gimpel's FlexeLint) has an option
to warn about repeated use of headers along arbitrary include chains. I
realize beauty is in the eyes of the beholder, but I suspect that all
the participants of this thread calling my approach stupid haven't
really given much thought to it. There are many advantages to it (see my
other posts in this thread).

Regards,

	Jens
-- 
Jens Schweikhardt http://www.schweikhardt.net/
SIGSIG -- signature too long (core dumped)

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


#42883

FromIan Collins <ian-news@hotmail.com>
Date2014-04-14 08:54 +1200
Message-ID<br0bsvFh48mU1@mid.individual.net>
In reply to#42868
Jens Schweikhardt wrote:
> Ian Collins <ian-news@hotmail.com> wrote
> 	in <bqtvckFb55cU5@mid.individual.net>:
> # Jens Schweikhardt wrote:
> #> hello, world\n
> #>
> #> consider a small project of 100 C source and 100 header files.
> #> The coding rules require that only C files include headers,
> #> headers are not allowed to include other headers (not sure if
> #> this is 100% the "IWYU - Include What You Use" paradigma).
> #
> # I agree with the other comments of the folly of this rule.  Don't do it!
> #
> # Just take a look at some of your system headers, or popular open source
> # library headers and consider whether you want all of the conditional
> # includes and other and unnecessary nonsense in all of your source files?
>
> The "unnecessary nonsense" is all the #ifndef crap in third party
> headers. Looking at system headers makes me cringe. It's not a role
> model.

Have you ever written or had to maintain cross platform software?

> There's a reason why the lint we use (Gimpel's FlexeLint) has an option
> to warn about repeated use of headers along arbitrary include chains. I
> realize beauty is in the eyes of the beholder, but I suspect that all
> the participants of this thread calling my approach stupid haven't
> really given much thought to it. There are many advantages to it (see my
> other posts in this thread).

Probably quite a few of us have spent many decades developing and 
maintaining a variety of code bases.  Sure there was a time when opening 
and reading headers took seconds rather than the micro-seconds it takes 
today.  These days developer time is way more valuable than machine 
time.  Having to update every source file that includes a header when a 
dependency changes or a new platform type is added is pure folly.

-- 
Ian Collins

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


#42887

FromKaz Kylheku <kaz@kylheku.com>
Date2014-04-13 21:37 +0000
Message-ID<20140413141503.995@kylheku.com>
In reply to#42883
On 2014-04-13, Ian Collins <ian-news@hotmail.com> wrote:
> Jens Schweikhardt wrote:
>> Ian Collins <ian-news@hotmail.com> wrote
>> 	in <bqtvckFb55cU5@mid.individual.net>:
>> # Jens Schweikhardt wrote:
>> #> hello, world\n
>> #>
>> #> consider a small project of 100 C source and 100 header files.
>> #> The coding rules require that only C files include headers,
>> #> headers are not allowed to include other headers (not sure if
>> #> this is 100% the "IWYU - Include What You Use" paradigma).
>> #
>> # I agree with the other comments of the folly of this rule.  Don't do it!
>> #
>> # Just take a look at some of your system headers, or popular open source
>> # library headers and consider whether you want all of the conditional
>> # includes and other and unnecessary nonsense in all of your source files?
>>
>> The "unnecessary nonsense" is all the #ifndef crap in third party
>> headers. Looking at system headers makes me cringe. It's not a role
>> model.
>
> Have you ever written or had to maintain cross platform software?

I have.

>> There's a reason why the lint we use (Gimpel's FlexeLint) has an option
>> to warn about repeated use of headers along arbitrary include chains. I
>> realize beauty is in the eyes of the beholder, but I suspect that all
>> the participants of this thread calling my approach stupid haven't
>> really given much thought to it. There are many advantages to it (see my
>> other posts in this thread).
>
> Probably quite a few of us have spent many decades developing and 
> maintaining a variety of code bases.  Sure there was a time when opening 
> and reading headers took seconds rather than the micro-seconds it takes 
> today. 

Everything has sped up. The *proportional* time wasted scanning headers
redundantly is still there.

> These days developer time is way more valuable than machine 
> time.  Having to update every source file that includes a header when a 
> dependency changes or a new platform type is added is pure folly.

Having to update every source file prevents the folly of making these kinds of
changes on a regular basis.

When programmers make changes that affect every translation unit, maybe they
should be "punished" by having to make an edit to the root source file of every
translation unit.

Otherwise they have this sense that "gee, I'm just changing a few lines of code
in a just one file; there is hardly any impact".

If you have to do this a lot, your program is badly designed.

If adding a new platform type affects your header file inclusion in many files,
that indicates that you're failing to isolate the platform-specific stuff
as well as it could be.  Perhaps your types are not opaque, and their
non-opaque bits are polluted with platform-specific types.  So, yes, it hurts
to add a new platform because you have to confront the fact that it affects
every translation unit.

None of this stuff is a problem if you design for minimal dependencies.
Just because some module A uses B, that doesn't always mean that the A
interface has to use the B interface ("a.c" requires "b.h", but "a.h" doesn't
have to require "b.h").

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


#42888

FromIan Collins <ian-news@hotmail.com>
Date2014-04-14 09:49 +1200
Message-ID<br0f3eFh48mU3@mid.individual.net>
In reply to#42887
Kaz Kylheku wrote:
> On 2014-04-13, Ian Collins <ian-news@hotmail.com> wrote:
>> Jens Schweikhardt wrote:
>>> Ian Collins <ian-news@hotmail.com> wrote
>>> 	in <bqtvckFb55cU5@mid.individual.net>:
>>> # Jens Schweikhardt wrote:
>>> #> hello, world\n
>>> #>
>>> #> consider a small project of 100 C source and 100 header files.
>>> #> The coding rules require that only C files include headers,
>>> #> headers are not allowed to include other headers (not sure if
>>> #> this is 100% the "IWYU - Include What You Use" paradigma).
>>> #
>>> # I agree with the other comments of the folly of this rule.  Don't do it!
>>> #
>>> # Just take a look at some of your system headers, or popular open source
>>> # library headers and consider whether you want all of the conditional
>>> # includes and other and unnecessary nonsense in all of your source files?
>>>
>>> The "unnecessary nonsense" is all the #ifndef crap in third party
>>> headers. Looking at system headers makes me cringe. It's not a role
>>> model.
>>
>> Have you ever written or had to maintain cross platform software?
>
> I have.
>
>>> There's a reason why the lint we use (Gimpel's FlexeLint) has an option
>>> to warn about repeated use of headers along arbitrary include chains. I
>>> realize beauty is in the eyes of the beholder, but I suspect that all
>>> the participants of this thread calling my approach stupid haven't
>>> really given much thought to it. There are many advantages to it (see my
>>> other posts in this thread).
>>
>> Probably quite a few of us have spent many decades developing and
>> maintaining a variety of code bases.  Sure there was a time when opening
>> and reading headers took seconds rather than the micro-seconds it takes
>> today.
>
> Everything has sped up. The *proportional* time wasted scanning headers
> redundantly is still there.

The time is micro-seconds.  Unless you have millions of includes, you 
won't be able to measure it.

>> These days developer time is way more valuable than machine
>> time.  Having to update every source file that includes a header when a
>> dependency changes or a new platform type is added is pure folly.
>
> Having to update every source file prevents the folly of making these kinds of
> changes on a regular basis.

It also makes simple design improvements a major arse ache.

> When programmers make changes that affect every translation unit, maybe they
> should be "punished" by having to make an edit to the root source file of every
> translation unit.

Why?  If the change fixes a bug, or improves the design they should be 
congratulated, not punished.

> Otherwise they have this sense that "gee, I'm just changing a few lines of code
> in a just one file; there is hardly any impact".

Well there isn't if the includes are managed sensibly...

> If you have to do this a lot, your program is badly designed.

Or evolving.  Most of my requirements are very vague, the client doesn't 
really know what they want until they start seeing the code in action.

-- 
Ian Collins

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


#42905

FromJens Schweikhardt <usenet@schweikhardt.net>
Date2014-04-14 19:17 +0000
Message-ID<br2qhnF8uajU2@mid.individual.net>
In reply to#42883
Ian Collins <ian-news@hotmail.com> wrote
	in <br0bsvFh48mU1@mid.individual.net>:
# Jens Schweikhardt wrote:
#> Ian Collins <ian-news@hotmail.com> wrote
#>       in <bqtvckFb55cU5@mid.individual.net>:
#> # Jens Schweikhardt wrote:
#> #> hello, world\n
#> #>
#> #> consider a small project of 100 C source and 100 header files.
#> #> The coding rules require that only C files include headers,
#> #> headers are not allowed to include other headers (not sure if
#> #> this is 100% the "IWYU - Include What You Use" paradigma).
#> #
#> # I agree with the other comments of the folly of this rule.  Don't do it!
#> #
#> # Just take a look at some of your system headers, or popular open source
#> # library headers and consider whether you want all of the conditional
#> # includes and other and unnecessary nonsense in all of your source files?
#>
#> The "unnecessary nonsense" is all the #ifndef crap in third party
#> headers. Looking at system headers makes me cringe. It's not a role
#> model.
# 
# Have you ever written or had to maintain cross platform software?

While at Sun Microsystems, I maintained VirtualBox. Does that qualify?
I also believe that the SW engineers that came up with the idea
of automated IWYU are not exactly misguided. They argue their case
in https://www.youtube.com/watch?v=JWEXAAw58XA
(with C++ examples, where the paradigma works even better).  On
http://www.eclipsecon.org/2013/category/tags/cdt-c-c-refactoring-include-includes-iwyu
there's a Google engineer's presentation using it for CDT.
Apparently, some people realize the potential.

...
# Probably quite a few of us have spent many decades developing and 
# maintaining a variety of code bases.  Sure there was a time when opening 
# and reading headers took seconds rather than the micro-seconds it takes 
# today.
# These days developer time is way more valuable than machine 
# time.

The whole idea is not about editor loading time. I'd say it's not even
in the first place about compile time minimization. But that's a welcome
and free side effect. For me the best benefit is improved
identifiability of refactoring opportunities, interface accumulation,
code collecting fat.

To all the people who think the "headers don't include headers" rule
is a folly, honestly, did you actually try it for a non-trivial code
base or are you possibly prejudiced? I encourage you to actually try
it. You might be in for a surprise. Granted, converting an existing
project is making a pig fly. But with enough thrust...
To be absolutely clear: it's not about system or third party stuff, it's
about your project's interfaces.


Regards,

	Jens
-- 
Jens Schweikhardt http://www.schweikhardt.net/
SIGSIG -- signature too long (core dumped)

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


#42920

FromIan Collins <ian-news@hotmail.com>
Date2014-04-15 10:24 +1200
Message-ID<br35h3F3g7rU3@mid.individual.net>
In reply to#42905
Jens Schweikhardt wrote:
> Ian Collins <ian-news@hotmail.com> wrote
> #
> # Have you ever written or had to maintain cross platform software?
>
> While at Sun Microsystems, I maintained VirtualBox. Does that qualify?

Undoubtedly! What rule does that project follow?

> ....
> # Probably quite a few of us have spent many decades developing and
> # maintaining a variety of code bases.  Sure there was a time when opening
> # and reading headers took seconds rather than the micro-seconds it takes
> # today.
> # These days developer time is way more valuable than machine
> # time.
>
> The whole idea is not about editor loading time. I'd say it's not even
> in the first place about compile time minimization. But that's a welcome
> and free side effect. For me the best benefit is improved
> identifiability of refactoring opportunities, interface accumulation,
> code collecting fat.

I guess it really is little more than a matter of taste and preferred 
working practices.  I can't really see how it improves refactoring 
opportunities, but I'm open to suggestions given I spend as much time 
refactoring as writing new code.

> To all the people who think the "headers don't include headers" rule
> is a folly, honestly, did you actually try it for a non-trivial code
> base or are you possibly prejudiced? I encourage you to actually try
> it. You might be in for a surprise. Granted, converting an existing
> project is making a pig fly. But with enough thrust...

I have and I found it painful.  It probably doesn't suit the type of 
work I do where the project requirements tend to be extremely vague and 
the design evolves over time.  I can see it working much better when 
coding to an existing design.

-- 
Ian Collins

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


#43024

FromJens Schweikhardt <usenet@schweikhardt.net>
Date2014-04-16 19:58 +0000
Message-ID<br85o0FeiroU1@mid.individual.net>
In reply to#42920
Ian Collins <ian-news@hotmail.com> wrote
	in <br35h3F3g7rU3@mid.individual.net>:
# Jens Schweikhardt wrote:
#> Ian Collins <ian-news@hotmail.com> wrote
#> #
#> # Have you ever written or had to maintain cross platform software?
#>
#> While at Sun Microsystems, I maintained VirtualBox. Does that qualify?
# 
# Undoubtedly! What rule does that project follow?

BYO - Bring your own :-) Bring a libc. Bring a make. Bring a shell.
Bring half of the POSIX toolbox.

As for header inclusion, no explicit rule was stated. But it was (and
still is, AFAICT) not the "headers don't include headers" rule but the
approach preferred by most of the participants in this thread, basically
include whatever you need when you need it.

I really wonder what (big) projects would benefit from IWYU (which I
understand now to be not exactly equivalent to "headers don't include
headers"). Mozilla, I'm told, is experimenting with it. It could
possibly do wonders to {Libre,Open,Star,*)Office on the compile-time
front.


Regards,

	Jens
-- 
Jens Schweikhardt http://www.schweikhardt.net/
SIGSIG -- signature too long (core dumped)

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


#42938

FromRichard Damon <Richard@Damon-Family.org>
Date2014-04-14 21:45 -0400
Message-ID<4b03v.89437$86.2650@en-nntp-16.dc1.easynews.com>
In reply to#42905
On 4/14/14, 3:17 PM, Jens Schweikhardt wrote:
> Ian Collins <ian-news@hotmail.com> wrote
> 	in <br0bsvFh48mU1@mid.individual.net>:
> # Jens Schweikhardt wrote:
> #> Ian Collins <ian-news@hotmail.com> wrote
> #>       in <bqtvckFb55cU5@mid.individual.net>:
> #> # Jens Schweikhardt wrote:
> #> #> hello, world\n
> #> #>
> #> #> consider a small project of 100 C source and 100 header files.
> #> #> The coding rules require that only C files include headers,
> #> #> headers are not allowed to include other headers (not sure if
> #> #> this is 100% the "IWYU - Include What You Use" paradigma).
> #> #
> #> # I agree with the other comments of the folly of this rule.  Don't do it!
> #> #
> #> # Just take a look at some of your system headers, or popular open source
> #> # library headers and consider whether you want all of the conditional
> #> # includes and other and unnecessary nonsense in all of your source files?
> #>
> #> The "unnecessary nonsense" is all the #ifndef crap in third party
> #> headers. Looking at system headers makes me cringe. It's not a role
> #> model.
> # 
> # Have you ever written or had to maintain cross platform software?
> 
> While at Sun Microsystems, I maintained VirtualBox. Does that qualify?
> I also believe that the SW engineers that came up with the idea
> of automated IWYU are not exactly misguided. They argue their case
> in https://www.youtube.com/watch?v=JWEXAAw58XA
> (with C++ examples, where the paradigma works even better).  On
> http://www.eclipsecon.org/2013/category/tags/cdt-c-c-refactoring-include-includes-iwyu
> there's a Google engineer's presentation using it for CDT.
> Apparently, some people realize the potential.
> 
...

> Regards,
> 
> 	Jens
> 

Actually, listening to this view, IWYU is NOT about flattening the
include tree, in fact the speaker talked about not removing includes
from the header that it needs, causing a leaking of dependencies!

The concept of IWYU is much more about doing dependency pruning by
seeing if you only use a foo*, then you can get away with just a forward
declare of foo, and not the full definition.

This IS a good concept, avoid adding unnecessary dependencies. In C++
this can be a bit harder, as a type name has more options of what it
might be (it could be a class, or a typedef for a template), making the
forward declare a bit tougher (so some classes come with a _fwd header),
but in C we are more apt to know that a type will be a struct, so if we
just need a pointer, we can forward declare it.

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


#42832

Fromluser- -droog <luser.droog@gmail.com>
Date2014-04-12 16:48 -0700
Message-ID<dd3c1fa9-bb1b-4e71-9f76-e21416a78ccb@googlegroups.com>
In reply to#42821
On Saturday, April 12, 2014 2:37:53 PM UTC-5, Jens Schweikhardt wrote:
> hello, world\n
> 
> consider a small project of 100 C source and 100 header files.
> The coding rules require that only C files include headers,
> headers are not allowed to include other headers (not sure if
> this is 100% the "IWYU - Include What You Use" paradigma).
> 
> The headers contain only what headers should contain:
> prototypes, typedefs, declarations, macro definitions.
> 
> The problem: given a set of headers, determine a sequence of
> #include directives that avoids syntax errors due to undeclared
> identifiers. I.e. if "foo.h" declares type foo_t and "bar.h" uses
> foo_t in a prototype, "bar.h" must be included before "foo.h".
> 
> I'm not a computer scientist, but it sounds as if this requires a
> topological sort of all the '"foo.h" needs "bar.h"' relations. Now the
> interesting part is: how to automate this, i.e. how to determine "this
> header declares identifiers A, B, C and requires X, Y, Z"? I looked
> at IWYU by google, but it requires a clang source tree plus some more
> hoop jumping and that's way too elephantine, so I gave up not knowing
> whether it would provide a solution.
> 
> Can you think of a lightweight way to solve this? Maybe using perl, the
> unix tool box, make, gmake, gcc, a C lexer?
> 

The way I've "solved" this in my postscript interpreter source,
is to use header guards and the preprocessor's #error directive
to describe what header needs to be included.

If header X needs Y to be previously included, then check for
Y's header guard and #error if not defined.

Y.h:

#ifndef Y_H
#define Y_H
//contents of Y
#endif


X.h:

#ifndef X_H
#define X_H

# ifndef Y_H
# error must include Y.h before X.h
# endif

#endif

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


#42869

FromJens Schweikhardt <usenet@schweikhardt.net>
Date2014-04-13 11:52 +0000
Message-ID<bqvc3vFhg97U5@mid.individual.net>
In reply to#42832
luser- -droog <luser.droog@gmail.com> wrote
	in <dd3c1fa9-bb1b-4e71-9f76-e21416a78ccb@googlegroups.com>:
...
# The way I've "solved" this in my postscript interpreter source,
# is to use header guards and the preprocessor's #error directive
# to describe what header needs to be included.
# 
# If header X needs Y to be previously included, then check for
# Y's header guard and #error if not defined.
# 
# Y.h:
# 
# #ifndef Y_H
# #define Y_H
# //contents of Y
# #endif
# 
# 
# X.h:
# 
# #ifndef X_H
# #define X_H
# 
# # ifndef Y_H
# # error must include Y.h before X.h
# # endif
# 
# #endif

That's an interesting approach. Thanks for sharing!

Regards,

	Jens
-- 
Jens Schweikhardt http://www.schweikhardt.net/
SIGSIG -- signature too long (core dumped)

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


#42848

FromKaz Kylheku <kaz@kylheku.com>
Date2014-04-13 01:04 +0000
Message-ID<20140412170319.463@kylheku.com>
In reply to#42821
On 2014-04-12, Jens Schweikhardt <usenet@schweikhardt.net> wrote:
>
> hello, world\n
>
> consider a small project of 100 C source and 100 header files.
> The coding rules require that only C files include headers,
> headers are not allowed to include other headers (not sure if
> this is 100% the "IWYU - Include What You Use" paradigma).
>
> The headers contain only what headers should contain:
> prototypes, typedefs, declarations, macro definitions.
>
> The problem: given a set of headers, determine a sequence of
> #include directives that avoids syntax errors due to undeclared
> identifiers. I.e. if "foo.h" declares type foo_t and "bar.h" uses
> foo_t in a prototype, "bar.h" must be included before "foo.h".

Projects organized according to this principle don't actually need to solve
this problem, because they start small, at which point it is easy to get the
order right by hand. Then they grow incrementally, whereby it is easy to
maintain the correct order. When a new source file is added, its section of
#include directives can be copied from another file and tweaked.

> I'm not a computer scientist, but it sounds as if this requires a
> topological sort of all the '"foo.h" needs "bar.h"' relations. Now the
> interesting part is: how to automate this, i.e. how to determine "this
> header declares identifiers A, B, C and requires X, Y, Z"? I looked
> at IWYU by google, but it requires a clang source tree plus some more
> hoop jumping and that's way too elephantine, so I gave up not knowing
> whether it would provide a solution.
>
> Can you think of a lightweight way to solve this? Maybe using perl, the
> unix tool box, make, gmake, gcc, a C lexer?

Here is possible algorithm, at least for reasonably well behaved
headers: iterate over the header files, and for each one compile a dummy
translation unit which includes it, to discover the set of header files file
which can be included without any of the other files. These are the "root" or
"stratum 0" headers in the dependency tree.

Next, find the set of headers which can be individually included if all these
"stratum 0" headers are already present. The set of these is "stratum 1".

Then iterate through the remaining strata.

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


#42863

From"BartC" <bc@freeuk.com>
Date2014-04-13 10:15 +0100
Message-ID<fCs2v.73133$ps2.60242@fx16.am4>
In reply to#42821
"Jens Schweikhardt" <usenet@schweikhardt.net> wrote in message
news:bqtj0hF60hpU1@mid.individual.net...

> consider a small project of 100 C source and 100 header files.
> The coding rules require that only C files include headers,
> headers are not allowed to include other headers

Whose rule is that? Because it seems to be broken by most standard headers.

(If I look at windows.h for example, it is a mess of conditional directives
and includes for 25 or 30 other files; I don't fancy having all that in my
own sources. Besides which, a different compiler will have a different
windows.h. You can't get away from the problem.)

 (not sure if
> this is 100% the "IWYU - Include What You Use" paradigma).
>
> The headers contain only what headers should contain:
> prototypes, typedefs, declarations, macro definitions.

The trouble, any of those could rely on 'something' which is in another
header. Yet the rest of the module does not directly use that 'something',
and shouldn't have to care about all those indirect includes (I'm not
allowed to use the word 'imports').

Should module A, needing to include library B, also have to include 29 other
include files that B uses?

And if A also needs library C, which uses some of those 29 files plus some
of its own, which order should these dozens of extra files appear in? 
Besides, a new update of B or C may have a different set of includes, but 
now you need to update all those extra includes in A.

It's best if these things are as self-contained as possible; A.c:

#include "B.h"
#include "C.h"

You don't even need to worry about whether B needs C, or C needs B, or even
if they have mutual dependencies.

> I'm not a computer scientist, but it sounds as if this requires a
> topological sort of all the '"foo.h" needs "bar.h"' relations. Now the
> interesting part is: how to automate this, i.e. how to determine "this
> header declares identifiers A, B, C and requires X, Y, Z"? I looked
> at IWYU by google, but it requires a clang source tree plus some more
> hoop jumping and that's way too elephantine, so I gave up not knowing
> whether it would provide a solution.
>
> Can you think of a lightweight way to solve this? Maybe using perl, the
> unix tool box, make, gmake, gcc, a C lexer?

I'm not sure it's even possible, because of the mutual or circular
dependencies I mentioned.

-- 
Bartc 

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


#42864

FromMalcolm McLean <malcolm.mclean5@btinternet.com>
Date2014-04-13 04:06 -0700
Message-ID<99db4398-0b1b-4dee-9bc8-17e9a7e15f64@googlegroups.com>
In reply to#42863
On Sunday, April 13, 2014 10:15:59 AM UTC+1, Bart wrote:
> 
> Whose rule is that? Because it seems to be broken by most standard headers.
> 
> (If I look at windows.h for example, it is a mess of conditional directives
> and includes for 25 or 30 other files; I don't fancy having all that in my
> own sources. Besides which, a different compiler will have a different
> windows.h. You can't get away from the problem.)
> 
It's case of one rule for libraries, one rule for user code.

Unless you work for Microsoft, you're unlikely to want to touch windows.h.
So the priority is ease for the application programmer, he wants to just
include "windows.h" and have everything work, including backwards 
compatibility. The MS programmer working on windows system files has a mess
to work through. 

If you're not writing a library, however, then the main audience is maintaining
programmers who come after you. It makes life easier far them if they have
a list of all the files a module depends on, and if by a simple text search
they can get a list of all modules that depend on it. Then it's easy to 
check manually whether a change will cause problems elsewhere.

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


#42870

FromJens Schweikhardt <usenet@schweikhardt.net>
Date2014-04-13 12:01 +0000
Message-ID<bqvckuFhg97U6@mid.individual.net>
In reply to#42863
BartC <bc@freeuk.com> wrote
	in <fCs2v.73133$ps2.60242@fx16.am4>:
# "Jens Schweikhardt" <usenet@schweikhardt.net> wrote in message
# news:bqtj0hF60hpU1@mid.individual.net...
# 
#> consider a small project of 100 C source and 100 header files.
#> The coding rules require that only C files include headers,
#> headers are not allowed to include other headers
# 
# Whose rule is that? Because it seems to be broken by most standard headers.

Those aren't the problem. It's a rule strictly for our project headers.
Third party libraries can do what they want.

# (If I look at windows.h for example, it is a mess of conditional directives
# and includes for 25 or 30 other files; I don't fancy having all that in my
# own sources. Besides which, a different compiler will have a different
# windows.h. You can't get away from the problem.)
# 
# (not sure if
#> this is 100% the "IWYU - Include What You Use" paradigma).
#>
#> The headers contain only what headers should contain:
#> prototypes, typedefs, declarations, macro definitions.
# 
# The trouble, any of those could rely on 'something' which is in another
# header. Yet the rest of the module does not directly use that 'something',
# and shouldn't have to care about all those indirect includes (I'm not
# allowed to use the word 'imports').
# 
# Should module A, needing to include library B, also have to include 29 other
# include files that B uses?

If it needs to, yes. I believe that this would be no different
with the "common include" rule. Eventually all the 29 headers
would be included. Most likely even *many times over.* Under
our rule each exactly once. Beauty!

...
#> Can you think of a lightweight way to solve this? Maybe using perl, the
#> unix tool box, make, gmake, gcc, a C lexer?
# 
# I'm not sure it's even possible, because of the mutual or circular
# dependencies I mentioned.

You can't have circular include dependencies, no matter what rule
you follow. In the end, all identifiers must be declared/defined
before use (modulo some esoteric situations like tag names in
prototype scope).

Regards,

	Jens
-- 
Jens Schweikhardt http://www.schweikhardt.net/
SIGSIG -- signature too long (core dumped)

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


#42872

From"BartC" <bc@freeuk.com>
Date2014-04-13 13:46 +0100
Message-ID<SGv2v.315640$Fk6.314323@fx22.am4>
In reply to#42870
"Jens Schweikhardt" <usenet@schweikhardt.net> wrote in message 
news:bqvckuFhg97U6@mid.individual.net...
> BartC <bc@freeuk.com> wrote

> # I'm not sure it's even possible, because of the mutual or circular
> # dependencies I mentioned.
>
> You can't have circular include dependencies, no matter what rule
> you follow. In the end, all identifiers must be declared/defined
> before use (modulo some esoteric situations like tag names in
> prototype scope).

Suppose you have two silly modules like a.c and b.c here:

//--a.c-----------------------
#include <stdio.h>
#include "b.h"

void function_a(float x) {
 printf("%f\n",x);
}

int main(void) {
function_b(56);
}
//----------------------------

//--b.c-----------------------
#include <stdio.h>
#include "a.h"

void function_b(float x) {
 function_a(x);
}
//----------------------------

with their respective header files:
//--a.h-----------------------
void function_a(float);
//----------------------------

//--b.h-----------------------
void function_b(float);
//----------------------------

What is the module hierarchy here? Now a.c contains main(), so that might be 
considered the root, but then b.c also depends on a.c. You can't have one 
without the other. And without an obvious external entry point such as 
main(), a.c and b.c could have the same hierarchical status.

-- 
BartC 

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


#42875

FromJens Schweikhardt <usenet@schweikhardt.net>
Date2014-04-13 13:58 +0000
Message-ID<bqvjgaFhg97U7@mid.individual.net>
In reply to#42872
BartC <bc@freeuk.com> wrote
	in <SGv2v.315640$Fk6.314323@fx22.am4>:
...
# What is the module hierarchy here? Now a.c contains main(), so that might be 
# considered the root, but then b.c also depends on a.c. You can't have one 
# without the other. And without an obvious external entry point such as 
# main(), a.c and b.c could have the same hierarchical status.

Such a concept of module hierarchy for C files is not something I
particularly worry about (I'd rather use "unit" := all C files in one
directory; but even that is pretty meaningless since not much follows
from it).

My thinking revolves around dependencies of headers, and these can be
resolved in your example. With doxygen's "includes" graph, each C File
is a root node and each of the included headers is a leaf. For the "is
included by" graph, each header is a root node, and all C files
including it are its direct leaves. Any tree has depth 2. It doesn't get
any simpler than that.

The trees of header dependencies are directed acyclic graphs.
The order of #include directives of a C file is a topological
sort of the required headers (usually a subset of all headers).

On another note, the concept of "module" is not precisely defined. Each
developer, each project, each author probably has their own
understanding of it. I avoid it when I can and rather think in terms of
public and private interfaces. That's a concept much better defined ("if
it's public I can call it from anywhere; if it's private I try to make
it static and call it only in that one file.") This is something you can
explain to and is understood by any developer knowing only the basics of
C. Keep it simple! The rope C gives us shouldn't be used to create knots
to strangle ourselves with.

Regards,

	Jens
-- 
Jens Schweikhardt http://www.schweikhardt.net/
SIGSIG -- signature too long (core dumped)

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


#42865

FromJens Schweikhardt <usenet@schweikhardt.net>
Date2014-04-13 11:29 +0000
Message-ID<bqvap4Fhg97U1@mid.individual.net>
In reply to#42821
Stefan Ram <ram@zedat.fu-berlin.de> wrote
	in <include-sort-20140412221141@ram.dialup.fu-berlin.de>:
# Jens Schweikhardt <usenet@schweikhardt.net> writes:
#>interesting part is: how to automate this, i.e. how to determine "this
#>header declares identifiers A, B, C and requires X, Y, Z"? I looked
# 
#  If you really deem this to be »interesting«, then go ahead
#  and write it.
# 
#>Can you think of a lightweight way to solve this? Maybe using perl, the
#>unix tool box, make, gmake, gcc, a C lexer?
# 
#  The common solution is IIRC: Allow that every header includes
#  all headers needed and use include-guards.

The "common solution" is quick and dirty. It leads to include spaghetti,
careless sprinkling of #include directives, useless #includes that are
actually not needed, horrific dependency generation for "make", longer
compile time, useless file system access churn, lint warnings about
repeated headers, the need for include guards, and other uglyness that
our rule avoids. There's also ample prior art in Unix, with sys/socket.h
requiring sys/types.h and so on. (I understand why ISO C takes a different
approach, but that's not the point; I'm strictly interested in the
code for the project.)

We have used doxygen to generate "A includes B" and "A is included by B"
graphs. The result was a big mess, uglier than hell, as soon as one
module needs access to just 10 other modules on average.

Now the graphs are one root with N leaves. Beauty!
Dependency generation is looking at the C file's includes. Beauty!
No more lint warning about repeated header inclusion. Beauty!
No need for include guards. Beauty!

I can live with a topological sort to flatten the dependency graphs.
It's a bit of rocket science to create it automatically, but hey,
I *am* in the rocket science business.

Regards,

	Jens
-- 
Jens Schweikhardt http://www.schweikhardt.net/
SIGSIG -- signature too long (core dumped)

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


#42874

FromMartin Shobe <martin.shobe@yahoo.com>
Date2014-04-13 08:48 -0500
Message-ID<lie4jc$2r1$1@dont-email.me>
In reply to#42865
On 4/13/2014 6:29 AM, Jens Schweikhardt wrote:
> Stefan Ram <ram@zedat.fu-berlin.de> wrote
> 	in <include-sort-20140412221141@ram.dialup.fu-berlin.de>:
> # Jens Schweikhardt <usenet@schweikhardt.net> writes:
> #>interesting part is: how to automate this, i.e. how to determine "this
> #>header declares identifiers A, B, C and requires X, Y, Z"? I looked
> #
> #  If you really deem this to be »interesting«, then go ahead
> #  and write it.
> #
> #>Can you think of a lightweight way to solve this? Maybe using perl, the
> #>unix tool box, make, gmake, gcc, a C lexer?
> #
> #  The common solution is IIRC: Allow that every header includes
> #  all headers needed and use include-guards.
>
> The "common solution" is quick and dirty. It leads to include spaghetti,
> careless sprinkling of #include directives, useless #includes that are
> actually not needed, horrific dependency generation for "make", longer
> compile time, useless file system access churn, lint warnings about
> repeated headers, the need for include guards, and other uglyness that
> our rule avoids. There's also ample prior art in Unix, with sys/socket.h
> requiring sys/types.h and so on. (I understand why ISO C takes a different
> approach, but that's not the point; I'm strictly interested in the
> code for the project.)
>
> We have used doxygen to generate "A includes B" and "A is included by B"
> graphs. The result was a big mess, uglier than hell, as soon as one
> module needs access to just 10 other modules on average.
>
> Now the graphs are one root with N leaves. Beauty!
> Dependency generation is looking at the C file's includes. Beauty!
> No more lint warning about repeated header inclusion. Beauty!
> No need for include guards. Beauty!

The problem is the dependencies are still that big, messy, uglier than 
hell graph doxygen generated. That graph now has to be kept in the heads 
of each and every developer. Really, really, really, ..., ugly!

Martin Shobe

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


Page 2 of 4 — ← Prev page 1 [2] 3 4  Next page →

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


csiph-web