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

[SR-7860] Compiler should help a bit if trying to call Variadic C Functions #50395

Open
swift-ci opened this issue Jun 4, 2018 · 0 comments
Open

Comments

@swift-ci
Copy link
Collaborator

swift-ci commented Jun 4, 2018

Previous ID SR-7860
Radar None
Original Reporter felix91gr (JIRA User)
Type Improvement
Additional Detail from JIRA
Votes 0
Component/s Compiler
Labels Improvement, ClangImporter, DiagnosticsQoI
Assignee None
Priority Medium

md5: 518da834cb4930a77a17007f41330284

Issue Description:

So currently when one tries to call a variadic C function, this is what the compiler says:

Compile Swift Module 'csd_proof' (2 sources)
/home/felix/Documents/Programming/tracelog_things/csd_proof/Sources/csd_proof/main.swift:20:1: error: 'sd_journal_print_with_location' is unavailable: Variadic function is unavailable
sd_journal_print_with_location(LOG_CRIT, "CODE_FILE=\(#file)", "CODE_LINE=\(#line)", #function, "Hello system log!");
^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
CSDJournal.sd_journal_print_with_location:2:13: note: 'sd_journal_print_with_location' has been explicitly marked unavailable here
public func sd_journal_print_with_location(_ priority: Int32, _ file: UnsafePointer<Int8>!, _ line: UnsafePointer<Int8>!, _ func: UnsafePointer<Int8>!, _ format: UnsafePointer<Int8>!, _ varargs: Any...) -> Int32

Based on this comment by Jordan, and this comment by me, the compiler should help the user a little bit more in these situations, since Swift does support alternatives. I'm talking of starting with something like this:

Compile Swift Module 'csd_proof' (2 sources)
/home/felix/Documents/Programming/tracelog_things/csd_proof/Sources/csd_proof/main.swift:20:1: error: 'sd_journal_print_with_location' is unavailable:
Variadic C functions are marked unavailable by the Swift compiler, since they are not type-safe and not composable.

Swift supports alternatives to directly calling variadic functions, in the form of `va_lists` of parameters. Therefore we should also be pointing out the user to that utility, either by linking to the Documentation or by showing them an example. Either way:

Compile Swift Module 'csd_proof' (2 sources)
/home/felix/Documents/Programming/tracelog_things/csd_proof/Sources/csd_proof/main.swift:20:1: error: 'sd_journal_print_with_location' is unavailable:
Variadic C functions are marked unavailable by the Swift compiler, since they are not type-safe and not composable.
-------------------------------------------------------------------------------
If you need to call variadic C functions, here's what you can do:
a) Use the alternative non-variadic form of that function. Most C libraries that allow for variadic functions like `fprintf` have functions like `vfprintf` that receive a `va_list` parameter. Swift supports creating `va_list` items and passing them onto imported non-variadic C functions. See https://github.com/apple/swift/blob/master/stdlib/public/core/VarArgs.swift for the implementation of this on the StdLib.
b) Create a Swift SPM wrapper that calls into the variadic function from C. See IBM's https://github.com/IBM-Swift/CCurl for an example of such a wrapper.
Option (a) should be easier to maintain, but if you can't find the non-variadic alternative in the imported library, option (b) is always available.

Alternatively to the last sentence of (a), we could point them to a repo that uses this functionality, or to the official documentation (if it exists).

Finally, and this would be just gravy on top, the compiler could look up into the header of the imported variadic function and look up for matches like send ~> sendv, fprintf ~> vfprintf and show them to the user as a direct alternative of the function they are trying to call. Then, instead of the above snippet, it could instead print this:

Compile Swift Module 'csd_proof' (2 sources)
/home/felix/Documents/Programming/tracelog_things/csd_proof/Sources/csd_proof/main.swift:20:1: error: 'sd_journal_print_with_location' is unavailable:
Variadic C functions are marked unavailable by the Swift compiler, since they are not type-safe and not composable.
-------------------------------------------------------------------------------
Rather than calling 'sd_journal_print_with_location', you can use 'sd_journal_printv_with_location' instead. It receives a `va_list`, which is supported by Swift. See <<Docs>> on how to use it.

Where can this be done? I could do it if someone is willing to guide me a little 🙂

@swift-ci swift-ci transferred this issue from apple/swift-issues Apr 25, 2022
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

1 participant