Groups | Search | Server Info | Keyboard shortcuts | Login | Register [http] [https] [nntp] [nntps]
Groups > comp.lang.c > #42821 > unrolled thread
| Started by | Jens Schweikhardt <usenet@schweikhardt.net> |
|---|---|
| First post | 2014-04-12 19:37 +0000 |
| Last post | 2014-06-10 09:40 -0700 |
| Articles | 20 on this page of 69 — 15 participants |
Back to article view | Back to comp.lang.c
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 →
| From | Ken Brody <kenbrody@spamcop.net> |
|---|---|
| Date | 2014-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]
| From | Ian Collins <ian-news@hotmail.com> |
|---|---|
| Date | 2014-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]
| From | Jens Schweikhardt <usenet@schweikhardt.net> |
|---|---|
| Date | 2014-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]
| From | Ian Collins <ian-news@hotmail.com> |
|---|---|
| Date | 2014-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]
| From | Kaz Kylheku <kaz@kylheku.com> |
|---|---|
| Date | 2014-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]
| From | Ian Collins <ian-news@hotmail.com> |
|---|---|
| Date | 2014-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]
| From | Jens Schweikhardt <usenet@schweikhardt.net> |
|---|---|
| Date | 2014-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]
| From | Ian Collins <ian-news@hotmail.com> |
|---|---|
| Date | 2014-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]
| From | Jens Schweikhardt <usenet@schweikhardt.net> |
|---|---|
| Date | 2014-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]
| From | Richard Damon <Richard@Damon-Family.org> |
|---|---|
| Date | 2014-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]
| From | luser- -droog <luser.droog@gmail.com> |
|---|---|
| Date | 2014-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]
| From | Jens Schweikhardt <usenet@schweikhardt.net> |
|---|---|
| Date | 2014-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]
| From | Kaz Kylheku <kaz@kylheku.com> |
|---|---|
| Date | 2014-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]
| From | "BartC" <bc@freeuk.com> |
|---|---|
| Date | 2014-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]
| From | Malcolm McLean <malcolm.mclean5@btinternet.com> |
|---|---|
| Date | 2014-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]
| From | Jens Schweikhardt <usenet@schweikhardt.net> |
|---|---|
| Date | 2014-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]
| From | "BartC" <bc@freeuk.com> |
|---|---|
| Date | 2014-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]
| From | Jens Schweikhardt <usenet@schweikhardt.net> |
|---|---|
| Date | 2014-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]
| From | Jens Schweikhardt <usenet@schweikhardt.net> |
|---|---|
| Date | 2014-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]
| From | Martin Shobe <martin.shobe@yahoo.com> |
|---|---|
| Date | 2014-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