Re: Unused header file inclusion

Andres Freund <andres@anarazel.de>

From: Andres Freund <andres@anarazel.de>
To: Tom Lane <tgl@sss.pgh.pa.us>
Cc: Alvaro Herrera <alvherre@2ndquadrant.com>, vignesh C <vignesh21@gmail.com>, Pg Hackers <pgsql-hackers@postgresql.org>
Date: 2019-08-03T19:37:33Z
Lists: pgsql-hackers

Attachments

Hi,

On 2019-07-31 19:25:01 -0400, Tom Lane wrote:
> Andres Freund <andres@anarazel.de> writes:
> > On 2019-07-31 16:55:31 -0400, Tom Lane wrote:
> >> Yeah.  I seem to recall a proposal that nodes.h should contain
> >> 
> >> typedef struct Foo Foo;
> >> 
> >> for every node type Foo, and then the other headers would just
> >> fill in the structs, and we could get rid of a lot of ad-hoc
> >> forward struct declarations and other hackery.
> 
> > That to me just seems objectively worse. Now adding a new struct as a
> > minor implementation detail of some subsystem doesn't just require
> > recompiling the relevant files, but just about all of pg.
> 
> Er, what?  This list of typedefs would change exactly when enum NodeTag
> changes, so AFAICS your objection is bogus.

> It's true that this proposal doesn't help for structs that aren't Nodes,
> but my sense is that > 90% of our ad-hoc struct references are for Nodes.

Ah, well, I somehow assumed you were talking about all nodes. I don't
think I agree with the 90% figure. In headers I feel like most the
references are to things like Relation, Snapshot, HeapTuple, etc.


> > Right now we really have weird dependencies between largely independent
> > subsystem.
> 
> Agreed, but I think fixing that will take some actually serious design
> work.  It's not going to mechanically fall out of changing typedef rules.

No, but without finding a more workable approach than what we're doing
often doing now wrt includes and forward declares, we'll have a lot
harder time to separate subsystems out more.


> > The only reason the explicit forward declaration is needed in the common
> > case of a 'struct foo*' parameter is that C has weird visibility rules
> > about the scope of forward declarations in paramters.
> 
> Yeah, but there's not much we can do about that, nor is getting rid
> of typedefs in favor of "struct" going to make it even a little bit
> better.

It imo pretty fundamentally does. You cannot redefine typedefs, but you
can forward declare structs.


E.g. in the attached series of patches, I'm removing a good portion of
unnecessary dependencies to fmgr.h. But to actually make a difference
that requires referencing two structs without including the header - and
I don't think restructing fmgr.h into two headers is a particularly
attractive alternative (would make it a lot more work and a lot more
invasive).

Think the first three are pretty clearly a good idea, I'm a bit less
sanguine about the fourth:
Headers like utils/timestamp.h are often included just because we need a
TimestampTz type somewhere, or call GetCurrentTimestamp(). Approximately
none of these need the PG_GETARG_* macros, which are the only reason for
including fmgr.h in these headers.  As they're macros that's not
actually needed, although I think normally good style. But I' think here
avoiding exposing fmgr.h to more headers is a bigger win.

Greetings,

Andres Freund

Commits

  1. Add fmgr.h include to selfuncs.h.

  2. Add "headerscheck" script to test header-file compilability under C.

  3. Fix failure-to-compile-standalone in scripts_parallel.h.

  4. Remove fmgr.h includes from headers that don't really need it.

  5. Don't include utils/array.h from acl.h.

  6. Remove redundant prototypes for SQL callable functions.

  7. Remove unnecessary #include <limits.h>

  8. Teach tuplesort.c about "top N" sorting, in which only the first N tuples