-
Notifications
You must be signed in to change notification settings - Fork 68
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
Decide on standard wording for APIs that are available only when compiler is C++20 or later #667
Comments
If the spec says Option 1, then to me that implies that the implementation is checking just for C++20 and if Option 2, then the implementation is checking the specific feature macro. Ideally we don't select Option 1 and then have implementation actually implement Option 2. I don't know if we could have a case where |
Thanks for writing this up and opening the issue. There's just two things I want to add. First, I'm not tied to the specific wording I proposed, and there are potentially ways to simplify it if we don't like the complexity, e.g.,
Second, requiring only a specific header also constrains implementations (i.e., using more C++20 features than the ones in the list would be invalid). We're not happy with our current way of pre-adopting features, and so I'm trying to explore this as a potential replacement. This would effectively allow SYCL to start introducing features as soon as they're broadly adopted and stable, similar to what we were trying to achieve with things like |
For example I could not use
Do you have a concrete example? |
Right, that's the sort of thing I'm imagining. If the SYCL specification (or a specific SYCL implementation) says that it requires C++20, then the implementation should be able to use any C++20 feature it wants because it's the user's responsibility to ensure they are using a compatible compiler. But if we just want to make a feature like
I think @gmlueck brought this up recently, but I don't remember where. But if I understood correctly, the issue is with the way that we describe pre-adoption of future ISO C++ features in 3.9.2. Alignment with future versions of C++:
The intent of this wording was that in a future version of SYCL, we would be able to say something to the effect of "When a SYCL program is compiled in C++20 mode, The alternative I'm proposing here is that instead of the SYCL specification pre-adopting features, we would effectively be permitting SYCL implementations to expose features early. A specific implementation could choose to make |
This is not how the C++ feature-test macros work today in either clang of gcc. For example, I think these feature-test macros exist so that a compiler can claim to be C++20 even before it implements all of the C++20 features. The macros do not provide a way for a C++17 compiler to expose features that are added in a newer version of the language. This reinforces my opinion that we should use the simpler wording in the spec:
This is a true statement. The compiler does need to be C++20 in order for it to provide |
I agree that this is not how most of the feature-test macros work, but I think this is an implementation decision. clang does provide an option to enable We are already in a position with clang today where we could say "Required C++ Features:
The rationale document for the feature-test macros (see here) argues the opposite, suggesting that implementations don't typically claim support for C++20 until they've implemented everything:
I'm sorry for arguing semantics here, but I don't think that's true. I don't think the conditions for a "compiler to be C++20" are well-defined. I think it's true that a compiler which claims to conform to the C++20 standard will provide What criteria should we use to determine if a compiler is C++20? |
Are there any other precedents of this other than I think this is the crux of the issue. If compilers did generally add options like this to enable newer C++ features when compiling in older C++ modes, I would be in favor of the wording you propose. I'm not aware that this is the case, though. Is |
I haven't done an exhaustive search, but there appear to be other examples. It looks like it's much more common in gcc, which provides
I'm not a member of the compiler community, so I can't speak for them. My opinions here are based on what I've seen being done with feature-test macros in large C++ projects (e.g., Kokkos) and what I've seen in compiler documentation. @tahonermann, do you have an opinion here? I noticed you worked on the |
Use of the There is only one specification of C++. While implementors might have to be concerned with use of non-conforming compilation modes, I don't think the SYCL specification needs to be or should be. My recommendation is that the SYCL specification specify minimum C++ version requirements as needed for interfaces it specifies. Implementors can then make those interfaces available in earlier C++ compilation modes based on feature test macros if so desired. If it is desirable to encourage implementors to do so, then a non-normative note included with such interfaces could be added that details which feature test macros would indicate the minimum feature support required. Stated otherwise, the following from @Pennycook's previous comment reflects the direction I recommend:
|
I hadn't considered the conformance aspect of this. Given SYCL has a conformance test, what I proposed could lead to some really nasty corner cases, where SYCL says that a program should be valid, a conforming C++ implementation says it isn't, but a non-conforming C++ implementation says it is. Oof. You and @gmlueck have convinced me that stating things in terms of C++ version is a better idea. In terms of specific wording, I'll propose a slight tweak to Greg's wording:
...because this saves us writing "or later" every time this paragraph appears. For code in a synopsis block, I propose: void foo() noexcept; // C++20 ...because guarding with the Then we could modify Section 3.9.1 to say something like:
...including a non-normative note as Tom suggested. |
I used this as an opportunity to finish a PR I had started which broadens the base C++ version in the SYCL spec. I tried to incorporate your proposal: #680. |
We decided in a previous F2F meeting that the SYCL-Next specification will allow the host compiler to be C++17 or later. We have also discussed adding some APIs to the specification that will be available only if the compiler has a certain version. For example, we might add an API that uses
std::span
and document that the API is available only when the compiler is C++20 or later. We need to decide what the specification wording will be in cases like this. The choice of wording also affects the way a vendor must implement these APIs.To illustrate the options, let's consider a mythical API:
Option 1 is to document the API like this:
Option 2 is to document the API in terms of the C++ feature-test macros like:
@Pennycook proposed option 2, so I think he prefers this option. I agree that this option allows an application to make use of these APIs even if the compiler is not fully conformant to C++20. (In the case above, it is only necessary that the compiler supports
std::span
in order for the application to use thefrob
API.)Despite that, I think I have a preference for option 1. I like that the wording is simpler. Imagine a case where an API uses two or more C++ features that have different feature-test macros, and the wording could get even more complex than the example above. I think that most application developers will just want to know which version of C++ supports each SYCL API, rather than the finer-level granularity of the feature-test macros.
I also think there's a consistency concern. Would we add Required C++ features clauses even to APIs that use
std::byte
, for example? This is a C++17 feature, but it also has a feature-tests macro (__cpp_lib_byte
). In the existing SYCL spec, we seem to have taken the position that the underlying compiler must support all C++17 features. If SYCL-Next allows C++20, it seems like it would be most consistent to adopt the same all-or-nothing wording in the spec.This does not mean that an implementation also needs to adopt an all-or-nothing approach. An implementation could still choose to make these APIs available based on the C++ feature-test macros if it wanted. This would still be conformant with the specification even if we went with option 1. Thus, making these APIs available with a partially-conformant C++ compiler could be a quality-of-implementation thing rather than a mandated-by-specification thing.
Finally, we should consider how this wording will seem years from now when C++20 is more established and fully supported by all compilers. I think the option 2 wording will seem overly complicated at that time.
The text was updated successfully, but these errors were encountered: