Repository navigation
The CommonMark module cannot be built using gcc 15 and perl 5.40.1 #23192
Description
Activity
This looks like it's caused by a combination of gcc-15 and the
INTERFACE:XS feature.Can someone who has access to
gcc-15or later on Linux build a threaded perl-5.40.1 and attempt to install Common Mark. (I can only getgcc-14.)- added a commit that references this issue
on Apr 13, 2025 GCC 15 hasn't been released yet. But anyway, this issue is because GCC 15 bumped the default C standard version to C23, and in C23 the meaning of an empty prototype has changed.
- In the presence of the INTERFACE keyword (which allows the same XSUB to wrap multiple C functions by storing a pointer to the C function in every CV associated with that XSUB), the C code generated by the XS parser relies on the XSINTERFACE_CVT macro to declare a function pointer variable. In XSUB.h, this macro is defined as: #ifdef __cplusplus # define XSINTERFACE_CVT(ret,name) ret (*name)(...) #else # define XSINTERFACE_CVT(ret,name) ret (*name)() #endif Presumably gcc-15 is complaining about a pointer to a function which has non-zero number of args begin declared as some_type (*my_function_ptr_var)() Is there a portable way in C to tell the compiler not to complain about this, or so we need to make the generated C code in some way include the function arg types?…-- "I used to be with it, but then they changed what ‘it’ was, and now what I’m with isn’t it. And what’s ‘it’ seems weird and scary to me." -- Grandpa Simpson (It will happen to you too.)
- (Moving this discussion back onto problem ticket, rather than PR #23194) Leon wrote:I'm not sure this fix is right (I have to dig deeper for that), but I am very sure that the implementation of the `INTERFACE` feature is rather broken and should probably be fixed. xsubpp knows the types of the arguments of the function, it should be able to cast to the right type without needing this silly macro.It's complicated by the fact that there is also the INTERFACE_MACRO: XS keyword, which allows code to specify their own macros to replace the default XSINTERFACE_FUNC and XSINTERFACE_FUNC_SET macros. I'm not sure it would be possible to change things in a back-compat way for code which defines its own macros. On the other hand, the INTERFACE_MACRO appears to be almost completely unused on CPAN: just two distros, MIME-Fast and Wx. Compared with 16(*) CPAN distros which use the INTERFACE: keyword. So perhaps breaking the former is acceptable? In any event, I currently have a WIP branch which has over 100 commits and which almost completely rewrites the XS parser, and which I planned to merge post-5.42.0 release. It would be (I imagine) a royal pain to fix INTERFACE in blead and *then* rebase my branch over that. On the other hand, it would be nice to get some sort of basic fix into the 5.42.0 release. Presumably over the next 2 years, gcc-15 is going to become mainstream, and then 5.42.0 will start breaking on XS modules with INTERFACE. Could the proposed '...' fix or similar to XSUB.h be used now as a stop-gap measure, then I'd fix INTERFACE properly post 5.42.0???…-- But Pity stayed his hand. "It's a pity I've run out of bullets", he thought. -- "Bored of the Rings"
Could the proposed '...' fix or similar to XSUB.h be used now as a
stop-gap measure, then I'd fix INTERFACE properly post 5.42.0???That's not a good fix either, becaus vararg argument passing is not guaranteed to be the same as non-vararg argument passing. Most notably it isn't on Apple on ARM.
Reacted by Sam JamesOn the other hand, the INTERFACE_MACRO appears to be almost completely
unused on CPAN: just two distros, MIME-Fast and WxJust MIME::Fast, it's commented out (with
#if 0) in Wx.MIME::Fast looks to me like it needs to use PREFIX instead.
But also, it hasn't been updated in 20+ years (and gnome certainly hasn't been standing still in that period), and no passing entries are known on CPAN Testers. I think we can assume it's dead.
It's complicated by the fact that there is also the INTERFACE_MACRO:
Yeah I don't think it was possible to write a sensible
INTERFACE_MACRObefore vararg macros, but we can actually make something better now.Though I'm still not quite sure when someone would ever need this feature.
- On Mon, Apr 14, 2025 at 05:12:09AM -0700, Leon Timmermans wrote: Leont left a comment (Perl/perl5#23192) > Could the proposed '...' fix or similar to XSUB.h be used now as a stop-gap measure, then I'd fix INTERFACE properly post 5.42.0??? That's not a good fix either, becaus vararg argument passing is not guaranteed to be the same as non-vararg argument passing. Most notably it isn't on Apple on ARM.Thinking some more: C_ARGS is going to be a problem. For example, with: foo(int a, char *b) INTERFACE: ...... C_ARGS: munge(b), a, FOO_SOME_FLAG C_ARGS is just an uninterpreted string which is used as-is to generate the call to the real C function. We have no idea what munge returns, or whether FOO_SOME_FLAG is a int or pointer or whatever. We can't even know the number of args: for example, munge() might be a macro which expands to "b, strlen(b)". So in general, the XS parser can't know the signature of the C function. Unless there is some new C feature I don't know about which provides that info? A sort of __FUNCTION_SIGNATURE__(some_function_name)?? We leads me to wonder: is there a viable fallback position for an INTERFACE XSUB which also contains C_ARGS? Such as a pragma which turns off arg checking? But if so, couldn't we just use that always? Just out of curiosity, does any C expert one know how detailed the function pointer declaration has to be? For example, could we just declare all args as 'void *' or something like that? (Note: my C knowledge is basically K&R, albeit updated with the newfangled ANSI way of declaring a function's parameters. I don't understand all this fancy C99 and later stuff.)…-- This email is confidential, and now that you have read it you are legally obliged to shoot yourself. Or shoot a lawyer, if you prefer. If you have received this email in error, place it in its original wrapping and return for a full refund. By opening this email, you accept that Elvis lives.
Thinking some more: C_ARGS is going to be a problem.
That is a good point. Yeah that will be hairy.
Unless there is some new C feature I don't know about which provides that
info? A sort of FUNCTION_SIGNATURE(some_function_name)??C23 actually has a
typeofoperator, but we can't exactly require C23.Just out of curiosity, does any C expert one know how detailed the
function pointer declaration has to be? For example, could we just declare
all args as 'void *' or something like that?Absolutely not. In the original version of C all arguments were word sized so none of this mattered, but that has long stopped being the case.
Perhaps instead of doing this weird function-pointer-hidden-in-CV voodoo, we could generate a separate XSUB for each function listed in INTERFACE?
So basically, this:
int foo_interface(int a, int b) INTERFACE: fun1 fun2would be equivalent to this:
int fun1(int a, int b) int fun2(int a, int b)(and remove INTERFACE_MACRO)
3 remaining items
In any case, I'm assuming anything we do to fix this will have to done
post-5.42.0.Yeah, that seems wiser than rushing a solution to a problem that's caused by a change outside of our power.
Speaking with my PSC hat on, we consider this a release blocker… for 5.44. This really needs solved but we don’t foresee the solution to be simple enough to still get into 5.42 at this late stage in the release cycle.
Reacted by Sam JamesAs a workaround, can this problem be overcome by adding
-std=c17to ccflags when gcc-15 is used ?As a workaround, can this problem be overcome by adding -std=c17 to ccflags when gcc-15 is used ?
But should we do that, or should CommonMark do that?
But should we do that, or should CommonMark do that?
Or .... should the user attend to that ? I don't know.
I was wondering what advice we would offer to someone who wants to install CommonMark-0.310100 on a perl that has been built using gcc-15, and c23.
I've meddled around a bit and found that if ccflags already specifies something less than c23 (as is currently the usual case on Windows), then CommonMark builds fine.
Nothing remarkable about that.And if, on my gcc-15 build (on Windows), I remove
-std=c99from ccflags, then I hit the issue as reported by the OP.
To then overcome that problem, rather than restore ccflags to its original state, I can simply rebuild CommonMark as a manual build, starting with:perl Makefile.PL CC="gcc -std=c17"Nothing remarkable about that, either. (I presume I could alternatively tweak CCFLAGS at that command line, but IIRC that gets a bit messy in the cmd.exe shell.)
Is that "manual" build the type of approach we would recommend for the time being ?
Should the current blead test suite expose this issue (FAIL or TODO ?) when it is present ?
FAIK, it might already do that. So far, all of my perl builds using gcc-15 have specified-std=c99in ccflags, so I wouldn't be be experiencing such failures, anyway.I presently have gcc-15 on Windows 11 only.
- On Fri, Apr 25, 2025 at 10:11:08PM -0700, sisyphus wrote: I've meddled around a bit and found that if ccflags already specifies something less than c23 (as is currently the usual case on Windows), then CommonMark builds fine.So if standard builds on Windows set -std= to something which doesn't trigger this problem, why is this a problem? (I'm not denying that it's potentially a problem, I'm just trying to understand the scope of the problem.)…-- "I used to be with it, but then they changed what ‘it’ was, and now what I’m with isn’t it. And what’s ‘it’ seems weird and scary to me." -- Grandpa Simpson (It will happen to you too.)
So if standard builds on Windows set -std= to something which doesn't trigger this problem, why is this a problem?
I don't think it's helpful in the long term to be hiding such issues under the C99 blanket.
What other issues might we be masking ?
I've pretty much decided that my own builds of perl-5.42 will be built without that "C99" wind-back - just like perl-5.38 and earlier.
I've spent most of today building and testing blead (using gcc-15.1.0) on Windows such that the C level remains at C23, and haven't yet found any additional issues at all.
But I feel that all of that would be more appropriately discussed in a separate issue/PR.As for the "scope of the problem", it looks to me that if perl's underlying C level is at C23 && you want to call
XSFUNCTIONwith one or more arguments, then you'll come up against this issue.
At least, that's about as far as I've got. (FAIRK, there could be caveats.)- added a commit that references this issue
on Aug 24, 2025 - I now have a proposed fix in PR #23640. It basically extracts the types of the parameters and uses them in a cast before calling XSFUNCTION. In the presence of C_ARGS, if its just a simple list of reordered parameters names, it splits the C_ARGS string and looks up the types of each referenced parameter. For complex C_ARGS lines it gives up on any complex args and just uses 'void*' as the arg's type. I'm using the philosophy of "the perfect is the enemy of the good". There is some theoretical XS code this commit won't fix, but it is unlikely to actually be seen in the wild.…-- In England there is a special word which means the last sunshine of the summer. That word is "spring".
- added a commit that references this issue
on Aug 24, 2025 For complex C_ARGS lines it
gives up on any complex args and just uses 'void*' as the arg's type.I'm using the philosophy of "the perfect is the enemy of the good". There
is some theoretical XS code this commit won't fix, but it is unlikely to
actually be seen in the wild.I have absolutely written complex
C_ARGS, butvoid*might just be close enough that it will work because I think they all used pointer types.- added 2 commits that reference this issue
on Aug 30, 2025 Fixed by v5.43.2-85-gb81e58c28b
Reacted by Graham Knop
Module: XS
Description
Since upgrading from gcc 14 to 15, the perl-CommonMark package cannot be rebuild. This does not look like an error in the CommonMark module but one in the XS module from core.
Steps to Reproduce
Build the CommonMark module using gcc 15 and Perl 5.40.1
Expected behavior
The module should build successfully
Perl configuration