Обсуждение: style for typedef of function that will be pointed to

Поиск
Список
Период
Сортировка

style for typedef of function that will be pointed to

От
Chapman Flack
Дата:
Hi,

From everything I've seen, the PostgreSQL style seems to be to include
the * in a typedef for a function type to which pointers will be held:

typedef void (*Furbinator)(char *furbee);

struct Methods
{
    Furbinator furbinate;
};


An alternative I've sometimes used elsewhere is to typedef the function
type itself, and use the * when declaring a pointer to it:

typedef void Furbinator(char *furbee);

struct Methods
{
    Furbinator *furbinate;
};


What I like about that form is it allows reusing the typedef to prototype
any implementing function:

static Furbinator _furbinator0;
static void _furbinator0(char *furbee)
{
}

It doesn't completely eliminate repeating myself, because the function
definition still has to be spelled out. But it's a bit less repetitive,
and makes it visibly explicit that this function is to be a Furbinator,
and if I get the repeating-myself part wrong, the compiler catches it
right on the spot, not only when I try to assign it later to some
*Furbinator-typed field.

Use of the thing doesn't look any different, thanks to the equivalence
of a function name and its address:

    methods.furbinate = _furbinator0;

Naturally, I'm not proposing any change of existing usages, nor would
I presume to ever submit a patch using the different style.
If anything, maybe I'd consider adding some new code in this style
in PL/Java, which as an out-of-tree extension maybe isn't bound by
every jot and tittle of PG style, but generally has followed
the documented coding conventions. They seem to be silent on this
one point.

So what I'm curious about is: is there a story to how PG settled on
the style it uses? Is the typedef-the-function-itself style considered
objectionable? For any reason other than being different? If there were
compilers at one time that didn't like it, are there still any?
Any that matter?

I've found two outside references taking different positions.

The Ghostscript project has coding guidelines [0] recommending against,
saying "Many compilers don't handle this correctly -- they will give
errors, or do the wrong thing, ...". I can't easily tell what year
that guideline was written. Ghostscript goes back a long way.

The SquareSpace OpenSync coding standard [1] describes both styles
(p. 34) and the benefits of the typedef-the-function-itself style
(p. 35), without seeming to quite take any final position between them.

Regards,
-Chap



[0] https://www.ghostscript.com/doc/9.50/C-style.htm
[1] https://www.opensync.io/s/EDE-020-041-501_OpenSync_Coding_Standard.pdf



Re: style for typedef of function that will be pointed to

От
Tom Lane
Дата:
Chapman Flack <chap@anastigmatix.net> writes:
> From everything I've seen, the PostgreSQL style seems to be to include
> the * in a typedef for a function type to which pointers will be held:
> typedef void (*Furbinator)(char *furbee);

Yup.

> An alternative I've sometimes used elsewhere is to typedef the function
> type itself, and use the * when declaring a pointer to it:
> typedef void Furbinator(char *furbee);

Is that legal C?  I doubt that it was before C99 or so.  As noted
in the Ghostscript docs you came across, it certainly wouldn't have
been portable back in the day.

> So what I'm curious about is: is there a story to how PG settled on
> the style it uses?

See above.

            regards, tom lane



Re: style for typedef of function that will be pointed to

От
Chapman Flack
Дата:
On 10/05/21 13:47, Tom Lane wrote:
>> An alternative I've sometimes used elsewhere is to typedef the function
>> type itself, and use the * when declaring a pointer to it:
>> typedef void Furbinator(char *furbee);
> 
> Is that legal C?  I doubt that it was before C99 or so.  As noted
> in the Ghostscript docs you came across, it certainly wouldn't have
> been portable back in the day.


It compiles silently for me with gcc --std=c89 -Wpedantic

I think that's the oldest standard I can ask gcc about. Per the manpage,
'c89' is ISO C90 without its amendment 1, and without any gnuisms.

Regards,
-Chap



Re: style for typedef of function that will be pointed to

От
Chapman Flack
Дата:
On 10/05/21 14:00, Chapman Flack wrote:
> On 10/05/21 13:47, Tom Lane wrote:
>>> An alternative I've sometimes used elsewhere is to typedef the function
>>> type itself, and use the * when declaring a pointer to it:
>>> typedef void Furbinator(char *furbee);
>>
>> Is that legal C?  I doubt that it was before C99 or so.  As noted
>> in the Ghostscript docs you came across, it certainly wouldn't have
>> been portable back in the day.
> 
> It compiles silently for me with gcc --std=c89 -Wpedantic
> 
> I think that's the oldest standard I can ask gcc about. Per the manpage,
> 'c89' is ISO C90 without its amendment 1, and without any gnuisms.

There are some places in the tree where AssertVariableIsOfType is being
cleverly used to achieve the same thing:

void
_PG_output_plugin_init(OutputPluginCallbacks *cb)
{
  AssertVariableIsOfType(&_PG_output_plugin_init, LogicalOutputPluginInit);


void
_PG_archive_module_init(ArchiveModuleCallbacks *cb)
{
  AssertVariableIsOfType(&_PG_archive_module_init, ArchiveModuleInit);


While clever, doesn't it seem like a strained way to avoid just saying:

typedef void ArchiveModuleInit(ArchiveModuleCallbacks *cb);


ArchiveModuleInit _PG_archive_module_init;

void
_PG_archive_module_init(ArchiveModuleCallbacks *cb)
{


if indeed compilers C90 and later are happy with the straight typedef?

Not that one would go changing existing declarations. But perhaps it
could be on the table for new ones?

Regards,
-Chap