Skip to content

Fix compiler error in CoreFoundation when building in C++ mode #5081

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

Merged
merged 1 commit into from
Sep 3, 2024

Conversation

egorzhdan
Copy link
Contributor

__CFAllocatorRespectsHintZeroWhenAllocating has two declarations in different headers: ForFoundationOnly.h and ForSwiftFoundationOnly.h. One of the declarations was under extern "C" block, the other one wasn't. Clang accepts this in C language mode, but it is a hard compiler error in C++ language mode due to a linkage mismatch.

This was blocking clients from using CoreFoundation in Swift projects that enable C++ interoperability.

This change makes sure that both declarations of __CFAllocatorRespectsHintZeroWhenAllocating are under extern "C" blocks.

@egorzhdan
Copy link
Contributor Author

@swift-ci please test

Boolean __CFAllocatorRespectsHintZeroWhenAllocating(CFAllocatorRef _Nullable allocator);
_CF_EXPORT_SCOPE_END
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Will making this CF_EXPORT like the others also fix the issue?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Good question! CF_EXPORT seems to expand into extern on Linux, not extern "C":

https://github.com/apple/swift-corelibs-foundation/blob/a9ffa779b1fdaa767c9c6ea28acfca32f7efe460/Sources/CoreFoundation/include/CFBase.h#L139

I'm wondering if this is an oversight, I can tweak the CF_EXPORT macro to expand into extern "C" in C++ language mode, and then use CF_EXPORT for this function.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

In truth no one is supposed to be using CoreFoundation except Foundation.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Usually our CF headers start with the macro the begin extern “C” but since this one is internal to Foundation it doesn’t have it.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think this header file is included by a public Foundation header, so it ends up being parsed when someone is including Foundation.

There are a few _CF_EXPORT_SCOPE_BEGIN/_CF_EXPORT_SCOPE_END blocks below in this file, so I thought that this is the preferred solution. But I'm happy to switch to CF_EXPORT if you think that's better.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

To avoid this turning into a tar pit of changes, let's just extend the begin/end to cover this 'group' of functions. Lines 60 - 75

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Sounds good, done.

`__CFAllocatorRespectsHintZeroWhenAllocating` has two declarations in different headers: `ForFoundationOnly.h` and `ForSwiftFoundationOnly.h`. One of the declarations was under `extern "C"` block, the other one wasn't. Clang accepts this in C language mode, but it is a hard compiler error in C++ language mode due to a linkage mismatch.

This was blocking clients from using CoreFoundation in Swift projects that enable C++ interoperability.

This change makes sure that both declarations of `__CFAllocatorRespectsHintZeroWhenAllocating` are under `extern "C"` blocks.
@egorzhdan
Copy link
Contributor Author

@swift-ci please test

@egorzhdan
Copy link
Contributor Author

@swift-ci please test Windows

@parkera parkera merged commit c820f72 into main Sep 3, 2024
2 of 3 checks passed
@parkera parkera deleted the egorzhdan/extern-c branch September 3, 2024 16:45
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants