Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

"template with C linkage" error when including "pycore_interp.h" from C++ file #122584

Closed
sklam opened this issue Aug 1, 2024 · 3 comments
Closed
Assignees
Labels
type-bug An unexpected behavior, bug, or error

Comments

@sklam
Copy link

sklam commented Aug 1, 2024

Bug report

Bug description:

Tested on official docker image python3.13.0b4-bullseye. pycore_interp.h causes compiler error when included from C++ file. No problem when included from C file.

mypackage/_good.c:

#include "Python.h"

#define Py_BUILD_CORE 1
#include "internal/pycore_interp.h"

mypackage/_bad.cpp (same content as above):

#include "Python.h"

#define Py_BUILD_CORE 1
#include "internal/pycore_interp.h"

setup.py:

from setuptools import Extension, find_packages, setup

def get_ext_modules():
    ext_good = Extension(name="mypackage.a",
                               sources=['mypackage/_good.c'])

    ext_bad = Extension(name="mypackage.b",
                               sources=['mypackage/_bad.cpp'])

    return [ext_good, ext_bad]

metadata = dict(
    name='debugthis',
    packages=find_packages(include=["mypackage"])
)

metadata['ext_modules'] = get_ext_modules()

setup(**metadata)

Running python setup.py build produces error:

running build
running build_py
copying mypackage/__init__.py -> build/lib.linux-x86_64-cpython-313/mypackage
running build_ext
building 'mypackage.a' extension
creating build/temp.linux-x86_64-cpython-313
creating build/temp.linux-x86_64-cpython-313/mypackage
gcc -pthread -fno-strict-overflow -Wsign-compare -DNDEBUG -g -O3 -Wall -fPIC -I/usr/local/include/python3.13 -c mypackage/_good.c -o build/temp.linux-x86_64-cpython-313/mypackage/_good.o
gcc -pthread -shared build/temp.linux-x86_64-cpython-313/mypackage/_good.o -L/usr/local/lib -o build/lib.linux-x86_64-cpython-313/mypackage/a.cpython-313-x86_64-linux-gnu.so
building 'mypackage.b' extension
gcc -pthread -fno-strict-overflow -Wsign-compare -DNDEBUG -g -O3 -Wall -fPIC -I/usr/local/include/python3.13 -c mypackage/_bad.cpp -o build/temp.linux-x86_64-cpython-313/mypackage/_bad.o
In file included from /usr/local/include/python3.13/internal/mimalloc/mimalloc.h:429,
                 from /usr/local/include/python3.13/internal/pycore_mimalloc.h:39,
                 from /usr/local/include/python3.13/internal/pycore_interp.h:31,
                 from mypackage/_bad.cpp:4:
/usr/include/c++/10/type_traits:56:3: error: template with C linkage
   56 |   template<typename _Tp, _Tp __v>
      |   ^~~~~~~~
In file included from mypackage/_bad.cpp:4:
/usr/local/include/python3.13/internal/pycore_interp.h:4:1: note: ‘extern "C"’ linkage started here
    4 | extern "C" {
      | ^~~~~~~~~~
...

CPython versions tested on:

3.13

Operating systems tested on:

Linux

Linked PRs

@sklam sklam added the type-bug An unexpected behavior, bug, or error label Aug 1, 2024
@mdboom
Copy link
Contributor

mdboom commented Aug 1, 2024

It looks like mimalloc.h is designed to be importable from either a C++ or C context, so it shouldn't be imported from inside an extern "C" { } block.

This fixes the issue, but there might be other cases of this, and it's not clear how to enforce that we don't fall in this trap again.

diff --git a/Include/internal/pycore_interp.h b/Include/internal/pycore_interp.h
index 45d85b2bace..f1dacc3eb3a 100644
--- a/Include/internal/pycore_interp.h
+++ b/Include/internal/pycore_interp.h
@@ -1,5 +1,8 @@
 #ifndef Py_INTERNAL_INTERP_H
 #define Py_INTERNAL_INTERP_H
+
+#include "pycore_mimalloc.h"      // struct _mimalloc_interp_state
+
 #ifdef __cplusplus
 extern "C" {
 #endif
@@ -28,7 +31,6 @@ extern "C" {
 #include "pycore_import.h"        // struct _import_state
 #include "pycore_instruments.h"   // _PY_MONITORING_EVENTS
 #include "pycore_list.h"          // struct _Py_list_state
-#include "pycore_mimalloc.h"      // struct _mimalloc_interp_state
 #include "pycore_object_state.h"  // struct _py_object_state
 #include "pycore_optimizer.h"     // _PyOptimizerObject
 #include "pycore_obmalloc.h"      // struct _obmalloc_state

@mdboom mdboom self-assigned this Aug 1, 2024
mdboom added a commit to mdboom/cpython that referenced this issue Aug 1, 2024
miss-islington pushed a commit to miss-islington/cpython that referenced this issue Aug 15, 2024
hauntsaninja pushed a commit that referenced this issue Aug 16, 2024
#123035)

gh-122584: Import mimalloc headers in a C++ context (GH-122587)
(cherry picked from commit 1dad23e)

Co-authored-by: Michael Droettboom <[email protected]>
blhsing pushed a commit to blhsing/cpython that referenced this issue Aug 22, 2024
@sklam
Copy link
Author

sklam commented Oct 24, 2024

I can confirm that the original problem is resolved.

@sklam sklam closed this as completed Oct 24, 2024
@vstinner
Copy link
Member

I'm now curious. Why do you need to access the internal C API, pycore_interp.h? What's your use case?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
type-bug An unexpected behavior, bug, or error
Projects
None yet
Development

No branches or pull requests

3 participants