I'm porting over some code from one project to another within my company and I encountered a generic "sets_intersect" function that won't compile:
template<typename _InputIter1, typename _InputIter2, typename _Compare>
bool sets_intersect(_InputIter1 __first1, _InputIter1 __last1,
_InputIter2 __first2, _InputIter2 __last2,
_Compare __comp)
{
// Standard library concept requirements
// These statements confuse automatic indentation tools.
// concept requirements
__glibcpp_function_requires(_InputIteratorConcept<_InputIter1>)
__glibcpp_function_requires(_InputIteratorConcept<_InputIter2>)
__glibcpp_function_requires(_SameTypeConcept<
typename iterator_traits<_InputIter1>::value_type,
typename iterator_traits<_InputIter2>::value_type>)
__glibcpp_function_requires(_OutputIteratorConcept<_OutputIter,
typename iterator_traits<_InputIter1>::value_type>)
__glibcpp_function_requires(_BinaryPredicateConcept<_Compare,
typename iterator_traits<_InputIter1>::value_type,
typename iterator_traits<_InputIter2>::value_type>)
while (__first1 != __last1 && __first2 != __last2)
if (__comp(*__first1, *__first2))
++__first1;
else if (__comp(*__first2, *__first1))
++__first2;
else {
return true;
}
return false;
}
I'm new to this concept of "concepts" (sorry for the pun), so I did some poking around in the c++ standard library and some googling and I can see that these __glibcpp_function_requires macros were changed to __glibcxx_function_requires. So that fixed my compiler error; however, since this is new to me, I'm curious about what this code is doing for me and I'm having trouble finding any documentation or decyphering the code in the library.
I'm assuming that the point of these macros is that when the compiler expands the templated function these will run some type checking at compile-time to see if the container being used is compatible with this algorithm. In other words, I'm assuming the first call is checking that _InputIter1 conforms to the _InputIteratorConcept. Am I just confused or am I on the right track? Also, why were the names of these macros changed in the c++ standard library?
"Concepts" were a proposed feature for the next version of C++, but they were (relatively) recently voted out of the standard so won't resurface for quote some time now.
They were designed to allow early checking of requirements for template parameters and, amongst other things, would have enabled much more succinct error messages when a type that didn't meet the required constrains was used to instantiate a template.
2nd Edit: (see comments from dribeas and Jerry Coffin) These g++ macros are an internal concept checking mechanism and are not directly related to the proposed new language feature of the same name. As they are internal to g++ you can (and perhaps should) safely remove them without any loss of functionality in your function template.
You are correct, the first call is checking that _InputIter1 implements "input iterator" concept.
These macros are internal GLIBC implementation details (starting with an underscore or a double underscore), therefore GLIBC implementers are allowed to change them at will. They are not supposed to be used by user's code.
Since "concepts" are no longer the part of C++0x draft, in order to have portable concept checking, you should use some third-party library, like Boost Concept Check Library.
There are two concept concepts (pun intended) around. The standard as it is being defined had a proposal for concepts as a standard language feature that would help in compilation and... there's quite a bit of literature around about C++0x concepts, discussions...
The other concept concept is the one you have just hit. The STL that is deployed with g++ implementations does have specific implementor checks that are also meant to aid in error detection. These are different to the previous concepts in that they are not a language feature and are not meant to be used by programmers, but rather they are used internally in the library. As the names are reserved (they begin with double underscore) the compiler/library implementor is free to add anything there as long as the behavior of the library does not differ from what the standard defines.
Going back to what you are doing: The code that you are trying to port to a newer compiler is a modified version of std::set_intersect as defined in the standard [lib.set.intersection] to return only whether they do intersect without having to parse the whole two ranges. I would either use the standard version and check that the output iterator was not modified, or if it is a performance issue, implement it without the concept checks, depending on non-standard hidden compiler defined symbols is asking for maintenance trouble when upgrading the compiler. But that you know already.
As Charles already pointed out, direct support for concepts as part of C++ 0x was removed from the language relatively recently, and they almost certainly won't even be reconsidered until the next round of standardization. Hopefully by then there will be greater agreement on what they should really be/do.
A fair number of libraries attempt to provide similar capabilities though. Boost Concept Check Library is probably the most obvious, and I believe most of the others are based on it, at least in concept (if you'll pardon the pun). As to why the g++ guys decided to change from '*cxx' to '*cpp', I can't even begin to guess -- other than that they seem to think breaking backward compatibility as often as possible is a good thing (though these are really only intended for internal use, so changing the name shouldn't break much but their own code).
This is also fairly similar to the basic idea of what Andrei Alexandrescu presented in §2.1 of Modern C++ Design. If you want some idea of how to write concept checking of your own, you might want to read that (as well as §2.7, where he applies similar techniques to testing for convertibility and inheritance). While the concepts being checked varied, those do a good job of explaining most of the basic techniques, so: You stand a decent chance of reading and understanding concept-checking templatesIf you ever decide to write some of your own, you have a starting point
Edit: It's probably worth noting that the standard libraries for most current C++ compilers include at least some sort of concept-checking templates. Obviously gnu does. So does Comeau. In fact, the only one I can think of that doesn't seem to include any such thing anymore is MS VC++ (which uses the Dinkumware library). They've concentrated primarily on some (rather expensive) run-time debugging instead. This is also somewhat useful, but in an entirely different direction, and the two aren't mutually exclusive at all.
Related
P0040R3 (adopted 2016-06, see also N4603) introduced some extended memory management algorithms like std::uninitialized_move_n into the draft, and finally it became parts of ISO C++17. Some of them had an extra overload with a ExecutionPolicy parameter for potential support of parallelism.
However, as of now (Aug 2018), I don't find any standard library implementation shipped with the implementations of these overloads. And the documentation of implementations I've checked does not clarify it well. Specifically, (currently) they are:
libstdc++ shows it does not support P0040R3 in trunk, but actually at least std::destroy_at and std::uninitialized_move_n without ExecutionPolicy are in GCC 8.2.
libc++ has "Complete" support of P0040R3 since 4.0, but the overloads with ExecutionPolicy are actually missing.
Microsoft VC++ has support of P0040R3 since VS 2017 15.3 with /std:c++17 or /std:c++latest, but the overloads with ExecutionPolicy are actually missing.
The only implementation with ExecutionPolicy overloads I know is in HPX, but this is not a full implementation of the standard library. If I want to use the features portably, I have to adapt to custom implementation likewise, rather than direct use of std names. But I still want to use std implementation in future as preference (unless they have known bugs). (The reason is that implementation-defined execution policies are tightly coupled with concrete implementations, so external implementations as well as their client code would likely have less opportunity to utilize various execution policies in general; although this is not necessarily true for client code which is not guaranteed portable in the sense of conforming to standard.) Thus, I want something available for conditional inclusion in my potable adaptive layer for implementations - to get the specified features with using std::... when they are provided by the standard library, and complement it with my implementations as the fallback of missing parts from the standard library implementation only when necessary.
As I have known, the SD-6 feature testing macros as well as P0941R2 shows __cpp_lib_raw_memory_algorithms is sufficient for the features in P0040R3. On the other hand, __cpp_lib_parallel_algorithm seems not related to <memory> at all. So there is no way to express the state like current libc++ and MSVC implementations - with std names from P0040R3 but lack of ExecutionPolicy overloads. And I'm not sure __has_include<execution> would ever work. The reality may be quirkier, e.g. P0336R1 is even not supported by libc++.
So, how to get it perfectly portable in my code when the features become (hopefully) available in some newer version of the standard library implementations, except inspecting the source of each version of them, or totally reinventing my wheels of the whole P0040R3?
Edited:
I know the intended use of feature testing macros and I think libstdc++ has done the right thing. However, there is room to improve. More specifically, my code of the portable layer would play the role of the implementation (like HPX), but more "lightweight" in the sense of not reinventing wheels when they are already provided by the standard library implementation:
namespace my
{
#if ???
//#if __cpp_lib_raw_memory_algorithms
using std::uninitialized_move_n;
// XXX: Is this sufficient???
#else
// ... wheels here ... not expected to be more efficient to std counterparts in general
#endif
}
so my client code can be:
my::uninitialized_move_n(???::par, iter, size, d_iter);
rather than (copied from Barry's answer):
#if __cpp_lib_raw_memory_algorithms
std::uninitialized_move_n(std::execution::par, iter, size, d_iter);
#else
// ???
#endif
Both pieces of the code can work, but obviously checking __cpp_lib_raw_memory_algorithms directly everywhere in client code is more costly.
Ideally I should have some complete up-to-date standard library implementation, but that is not always the case I can guarantee (particularly working with environments where the standard library is installed as parts of system libraries). I need the adaption to ease the clients' work anyway.
The fallback is obvious: avoiding the using std::uninitialized_move_n; path totally. I'm afraid this would be a pessimistic implementation so I want to avoid this approach when possible.
Second update:
Because "perfectly portable" sounds unclear, I have illustrated some code in the edit above. Although the question is not changed and still covered by the title, I will make it more concrete here.
The "perfectly portable" way I want in the question is restricted as, given the code like the edit above, filling up any parts marked in ???, without relying on any particular versions of language implementations (e.g., nothing like macro names depended on implementations should be used for the purpose).
See here and here for the code examples fail to meet the criteria. (Well, these versions are figured out via inspection of commit logs... certainly imperfect, and, still buggy in some cases.) Note this is not related to the overloads with ExecutionPolicy yet, because they are missing in the mentioned standard library implementations, and my next action is depending on the solution of this question. (But the future of the names in std should be clear.)
A perfect (enough) solution can be, for example, adding a new feature testing macro to make the overloads independent from __cpp_lib_raw_memory_algorithms so in future I can just add my implementation of the overloads with ExecutionPolicy when they are not detected by the stand-alone new feature testing macro, without messing up the condition of #if again. But certainly I can't guarantee this way would be feasible; it ultimately depends on the decision of the committee and vendors.
I'm not sure whether there can be other directions.
The initial version of P0941 contained a table which made it clear that P0040R3 has the corresponding feature-test macro __cpp_lib_raw_memory_algorithms. This implies that the correct, portable way to write code to conditionally use this feature is:
#if __cpp_lib_raw_memory_algorithms
std::uninitialized_move_n(std::execution::par, iter, size, d_iter);
#else
// ???
#endif
The imposed requirement is that if that macro is defined, then that function exists and does what the standard prescribes. But that macro not being defined does not really say anything. As you point out, there are parts of P0040R3 that are implemented in libstdc++ - parts, but not all, which is why the feature-test macro is not defined.
There is currently a concerted effort to implement the parallel algorithms in libstdc++.
As to what to do in the #else branch there, well... you're kind of on your own.
Type traits are cool and I've used them since they originated in boost a few years ago. However, when you look at their implementation (check out "How is_base_of works?" StackOverflow thread).
Why won't compiler help here? For example, if you want to check if some class is base of another, compiler already knows that, why can't it tell us? This would make things like concepts so much easier to implement and use. You could use language constructs right there.
I am not sure, but I am guessing that it would increase general performance. It is like asking compiler for help, instead of C++ language.
I suspect that the primary reason will sound something like "we need to maintain backwards compatibility" and I agree, but why won't the compiler be more active in generating generic templated code?
Actually... some do.
The thing is that if something can be implemented in pure C++ code, there is no reason, other than simplifying the code, to hard-wire them in the compiler. It is then a matter of trade-off, is the value brought by the code simplification worth the hard-wiring ?
This depends on several points:
correctness (some times software may only partially emulate the trait)
complexity of the code ~~ maintenance burden
performance
...
Once all those points have been weighted, then you can determine whether it's more advantageous to put things in the library or the compiler; and the more likely situation is that you will end up with a mixed strategy: a couple intrinsics in the compiler used as building blocks to provide the required interface in the library.
Note that the maintenance burden is much more significant in a compiler: any C++ developer sufficiently acquainted with the language can delve into a library implementation, whereas the compiler code is a black-box. Therefore, it'll be much easier to debug and patch the library than the compiler, so there is incentive not to put things in the compiler unless you have a very good reason to.
It's hard to give an objective answer here, but I suspect the following.
The code using language quirks to find out this stuff has often already been written (Boost, etc).
The compiler does not have to be changed to implement this if it can be done with language quirks (which saves a lot of time in writing, compiling, debugging and testing).
It's basically a "don't fix what isn't broken" mentality.
Compiler help for type traits has always been a design goal. TR1 formally introduced type traits, and included a section that described acceptable incorrect results in some cases to enable writing the type traits in straight C++. When those type traits were added to C++11 (with some name changes that don't affect their implementation) the allowance for incorrect results was removed, effectively requiring compiler help to implement some of them. And even for those that can be implemented in straight C++, compiler writers prefer intrinsics to complicated templates so that you don't have to put a drip pan under your computer to catch the slag as the overworked compiler causes the computer to melt down.
I am updating a code base that is 10 years old and used Metrowerks Code Warrior on Mac and Windows.
I am updating to OS X, XCode 3.2, Universal Binary.
I seem to be getting a lot of template related errors and not being a genius on templates (and forgetting to eat a healthy dose of frosted templates for breakfast), I find myself wondering about template portability issues.
IIRC, templates are/or can be compiler specific?
Does anyone have advice or a tutorial on templates that they recommend?
Yes and no -- most reasonable template code written for one current compiler will work fine on other current compilers. Compilers have progressed over time, so a lot of new code won't work on old compilers, and vice versa. The biggest culprit with old code on new compilers is needing "typename" in quite a few places that old compilers would accept the code without it.
The most common problem is with code something like this:
template <class T>
class XYZ {
T::y a;
};
Most older compilers would (incorrectly) interpret "T::y" as a type -- but in a template, it's actually impossible to be sure of that, because T might be any type. To make the code work with a modern (more accurate) compiler, you need to change that to: typename T::y a;, to let the compiler know that T::y is the name of a type.
Templates themselves have well-defined behavior, as defined in §14 in the standard.
What is implementation-dependent is the limits of template use. For example, from Annex B (which lists recommended limit minimums):
Template arguments in a template declaration [1024].
Recursively nested template instantiations [17].
If you're depending on behavior more than these, it may be implementation dependent. It should be noted a compiler does not have to provide these minimal limits to remain standards compliant.
If you post some actual code/errors, we can tell you why you're getting an error. Likely, you're old code used some compiler-specific extensions or otherwise was allowed to use explicitly forbidden behavior.
The ability of compilers has improved a lot in ten years.
I would question the standards compliance of the compiler and the STL from 10 years ago. I belive tha standard had only just been introduced ten years ago and it takes compilers a while to catch up with the standard.
In modern compilers I think you will find that template code is relatively portable across compilers and the standards comitee is very carefull about changes to the standard to make sure it does not break compatabilty (very often).
There wasn't a single compiler in 2000 which implemented all aspects of standard templates. I'd dare to say no one even realised what was possible with templates till Alexandrescu released his Modern C++ design in 2001.
That said, Metrowerks was one of the better ones. If it compiles on version 7 or later, it should be very feasible to get it working on a modern, more standard compliant, compiler rather fast.
If I remember correctly the biggest problem with Metrowerks compilers in the early days was that wherever typename appeared, what followed was simply interpreted as a type, no matter what followed it.
This meant you could do, and I've seen, completely non standard stuff with that, like forward declaring typedefs.
Another part of templates that took them pretty long to get right was everything w.r.t. template template parameters and default template arguments.
Post some specific errors if you can't get it to work, they'll probably all fall in one or two 'classes' of problems, and someone will quickly be able to help you.
As I already said, Metrowerks had a pretty good C++ compiler, especially their STL implementation, largely thanks to Howard Hinnant I think.
For instance why does most members in STL implementation have _M_ or _ or __ prefix?
Why there is so much boilerplate code ?
What features C++ is lacking that would allow make vector (for instance) implementation clear and more concise?
Implementations use names starting with an underscore followed by an uppercase letter or two underscores to avoid conflicts with user-defined macros. Such names are reserved in C++.
For example, one could define a macro called Type and then #include <vector>. If vector implementations used Type as a template parameter name, it would break.
However, one is not allowed to define macros called _Type (or __type, type__ etc.). Therefore, vector can safely use such names.
Lots of STL implementations also include checking for debug builds, such as verifying that two iterators are from the same container when comparing them, and watching for iterators going out of bounds. This involves fairly complex code to track the container and validity of every iterator created, but is invaluable for finding bugs. This code is also all interwoven with the standard release code with #ifdefs - even in the STL algorithms. So it's never going to be as clear as their most basic operation. Sites like this one show the most basic functionality of STL algorithms, stating their functionality is "equivalent to" the code they show. You won't see that in your header files though.
In addition to the good reasons robson and AshleysBrain have already given, one reason that C++ standard library implementations have such terse names and compact code is that virtually every C++ program (compilation unit, really) includes a large number of the standard library headers, and they are thus repeatedly recompiled (remember that they're largely inlined and template-based, whereas the C standard library headers only contain a handful of function declarations). A standard library written to "industry standard" style guidelines would take longer to compile and thus lead to the perception that a particular compiler was "slow". By minimizing whitespace and using short identifier names, the lexer and parser have less work to do, and the whole compilation process completes a little bit faster.
Another reason worth mentioning is that many standard library implementations (e.g. Dinkumware, Rogue Wave (old), etc.) can be used with several different compilers with widely different standards compliance and quirks. There's frequently a lot of macro hackery aimed at satisfying each supported platform.
Lately as part of my day job I've been learning IBM Rhapsody and using it to generate code in C++ from the UML.
Yesterday it struck me that it might be cool to think about adding state machine support to my C++ compiler, so I jotted a few notes here: http://ellcc.org/wiki/index.php/State_machines_and_Active_Classes
My motivations for doing this are:
It seems like a cool idea.
The compiler could do much better semantic checking (with better error checking) than the current Rhapsody/normal C++ compiler.
There are many optimization possibilities available when the compiler itself understands the state machine structure.
I may try to extend my grammar to except something like the proposal to see how well it works.
What is your opinion of the proposal? Does it seem readable? Does it seem worthwhile?
Edit:
Thanks for the answers recommending specific libraries to do state machines, but that wasn't my question. I've implemented many state machines using both libraries and code that I've written.
I was really looking for ideas, criticism, etc. about the design of a state machine extension to a C++-like language, not whether this change would be appropriate for addition to standard C++. Think of it as a domain specific extension, where my my domain is real-time control applications.
I've started implementation of the extension in my compiler as described here: http://ellcc.org/wiki/index.php/State%5Fmachines%5Fand%5FActive%5FClasses
So far the concept hasn't had to change much going from proposal to implementation but there have been a few changes in details and I'm refining my understanding of the semantics of the problem.
Time will tell whether the whole concept has any value, however. ;-)
With a few exceptions, C++ has traditionally been extended using class libraries, not new keywords. State machines can easily be implemented using such libraries, so I don't think your proposal has much of a chance.
One problem I see in your proposal is the use of 'goto' to go to another state. What happens if I want to use goto in my own code within a state transition?
Excellent work developing what you've done. Something like you've done probably is possible, but I'm doubtful it would ever get into the C++. Most changes that make it into the language itself are included only to allow people to write more useful and powerful libraries.
There's a library here that provides support for state machines. I haven't tried it, but it might interest you, and you may be able to combine your ideas with a library like this to allow other people to make use of it.
http://www.boost.org/doc/libs/1_34_1/libs/statechart/doc/index.html
Or, you could develop your own extension as you suggest, and it would at least be useful for you. Microsoft implement some extension keywords, so there is no reason why you couldn't create your own extended version of C++.
Keep the new ideas coming.
You should take a look at how another smart developer added State machine support to a C-like language: UnrealScript Language Reference. See the section named "States".
UnrealScript supports states at the
language level. In UnrealScript, each
actor in the world is always in one
and only one state. Its state reflects
the action it wants to perform. For
example, moving brushes have several
states like "StandOpenTimed" and
"BumpOpenTimed". Pawns have several
states such as "Dying", "Attacking",
and "Wandering". In UnrealScript, you
can write functions and code which
exist in a particular state. These
functions are only called when the
actor is in that state
It's an interesting idea, but I think you'd actually have better luck creating your own domain-specific language for state machines than officially extending C++. C++ is designed as a very general-purpose programming language. I think Boost has proven that C++ is flexible enough that most features can be implemented nicely using libraries. It also evolves very slowly, to the extent that standard C++ still doesn't even have built-in threading support as of 2009, (it is planned in 0x). So it's unlikely the committee would consider this addition for some time.
Your solution does not look like it has any advantages to a template- or preprocessor-macro-based solution.
I am also not sure, how you can provide better semantic checking. And I doubt that you can apply many useful code optimizations.
However, to allow better optimizations and semantic checking, you should also replace "goto" with a new keyword (e.g. __change__ newState), and disallow goto for state changes! Allow goto for local jumps as usual.
Then the compiler can extract a list of possible transitions.
Read your proposal, have the following comments:
There's actually no keyword to declare and define an actual state machine! Do you assume a single global state machine (and thus a single global state)? How does that relate to __active__ ?
The closest comparable construct in C++ is actually the enum. Why not extend it?
There seems to be some connection between defined events and states, but I fail to see how it's implemented.
Why are threads and timers needed at all? Some use cases of state machines may benefit from them, but a good proposal should keep these seperate. Most importantly this should allow the use of standard C++0x threads.
Personally, I would extend the enum syntax:
enum Foo {
red, blue, green; /* Standard C++ so far - defines states. State list ends with a ; not a , */
Foo() { *this = red; } // Reuse ctor syntax, instead of __initial__
~Foo() { } // reuse dtor syntax, instead of __onexit__
void Bar() {/**/} // Defines an event, no return value. Doesn't need keyword __event__
};
It follows naturally that you can now declare your events in a header, and define them in a .cpp file. I don't even need to suggest the syntax here, any C++ programmer can guess that at this point. Add a bit of inheritance syntax for combined states:
enum DrawingObject : public Shape, public Color { /** } // allows (red && circle)
and you're pretty much at the point where your proposal is, without any new keywords, all by reusing an already familiar syntax.