How to make g++ compile a chrono output? - c++

I would like to print a chrono time point in the console, and I've found the following stackoverflow question:
How do you print a C++11 time_point?
One of the answers (How do you print a C++11 time_point?) states that in C++20 (which is now out for more than a year) one can just put the time point into an output command. Unfortunately, I can't compile the code on my machine. I have used the following command for the compilation:
g++ -std=c++20 chrono5.cpp -o test
I use this command because I read that C++ 20 is required for the direct output to work.
The file "chrono5.cpp" contains the exact same code as the (edit to the) answer to which the link above points, which was literally written by Howard Hinnant, the creator of the chrono library. What am I doing wrong?
The error message is exceedingly long, whence I probably should not include it in its entirety, but here is its beginning:
chrono5.cpp:7:15: error: no match for ‘operator<<’ (operand types are ‘std::ostream’ {aka ‘std::basic_ostream<char>’} and ‘std::chrono::_V2::system_clock::time_point’ {aka ‘std::chrono::time_point<std::chrono::_V2::system_clock, std::chrono::duration<long int, std::ratio<1, 1000000000> > >’})
7 | std::cout << std::chrono::system_clock::now() << " UTC\n";
| ~~~~~~~~~ ^~ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
| | |
| | std::chrono::_V2::system_clock::time_point {aka std::chrono::time_point<std::chrono::_V2::system_clock, std::chrono::duration<long int, std::ratio<1, 1000000000> > >}
| std::ostream {aka std::basic_ostream<char>}
Does my compiler have the support for this feature at all? Thank you very much in advance!

The operator<< overload necessary to make this work was introduced in C++20 with the proposal P0355, which however also contains a much larger extension of the <chrono> library. It introduces concepts of calendars and time zones which the <chrono> library didn't have before. These are necessary to e.g. print a time point as calendar date and day time as operator<< now does.
literally written by Howard Hinnant, the creator of the chrono library
He designed the library and wrote a reference implementation, but every C++ implementation still has to implement the library specification for itself.
Does my compiler have the support for this feature at all? Thank you very much in advance!
It is not about compiler support, but standard library support. Part of GCC is libstdc++ which contains the standard library implementation. On libstdc++'s implementation status page the paper I mentioned earlier is still listed as not implemented in any released version. But as #Brian notes in a comment under the question, current GCC trunk does support at least the operator<< overload you need here.
For an overview of multiple standard library implementations you can see https://en.cppreference.com/w/cpp/compiler_support#C.2B.2B20_library_features, which currently lists libstdc++'s implementation of the paper as partial since GCC 11 and targeted as complete for the next major release GCC 13.
LLVM's libc++ is also listed as partial (since LLVM/Clang 7) and only MSVC's implementation is listed as currently complete in a released version (since 16.10).

Related

Why did newer compilers start accepting this template function call?

The following small C++ program involving a call to the template function std::atomic_fetch_add() fails to compile in godbolt for x86-64 clang versions less than 9.0 and gcc versions less than 9.1,
in both cases using the --std=c++11 option.
#include <iostream>
#include <atomic>
std::atomic<char> ch ('#');
int main ()
{
std::atomic_fetch_add (&ch, 5);
std::cout << ch << std::endl;
}
In those early compiler versions (it might be more related to the C++ libraries provided by the compilers, I'm not sure), the std::atomic_fetch_add (&ch, 5); call fails to match any template specialization for the atomic fetch function, since the type of ch is char, and the type of 5 is int:
: In function 'int main()':
:8:34: error: no matching function for call to 'atomic_fetch_add(std::atomic*, int)'
std::atomic_fetch_add (&ch, 5);
...
However, later versions of the compiler (& libraries?) successfully compile this usage.
What changed to make this start compiling?
If it is a standard library change, what technique is used to allow this?
Does the C++ standard (& what version?) require that this usage should work.
I'm pretty much a C++ beginner, but I gather that this is related to implicit conversions not being performed as part of figuring out the appropriate template specialization to use. (I may not be using precise language.)
I know that I can modify the call to work by rewriting it as either
std::atomic_fetch_add<char> (&ch, 5);
or
std::atomic_fetch_add (&ch, (char)5);
However, I'm interested in getting a version of the <atomic> library to support the usage without the explicit instantiation and without the cast. (The compiler is clang 15.0.0, --std=c++11. The library is a proprietary version of the Dinkum libraries.)
I need to understand how to support the calling of template functions like
std::atomic_fetch_char (&ch, 5) where the argument types do not exactly match those in the template declaration. I would, for example, like to understand how this is supported in the linux /usr/include/c++/11/ standard library.
The nearest I've come up with myself is to add non-template overloads of various instantiations of std::atomic_fetch_add() & similar functions, but I don't see that being done in the Linux/GNU C++ libraries and I suspect there is a cleaner way. I want to understand it.
Originally std::atomic_fetch_add required the second parameter to have the same type as the value_type of the atomic object as both parameters participated in type deduction.
This was removed with defect report P0558R1 so that deduction only happens on the atomic object and the second parameter is just converted to the differece_type of the atomic object.
You get the error because older versions didn't get patched with this defect report but newer versions did.

Compiling with Intel Threading Building Blocks: error operands to ?:

Currently, I try to compile OpenVDB, which depends on Threading Building Blocks. I get the following error:
In file included from /usr/include/tbb/enumerable_thread_specific.h:32:0,
from ../openvdb/tools/Morphology.h:59,
from ../openvdb/tools/MultiResGrid.h:64,
from cmd/openvdb_lod/main.cc:32:
/usr/include/tbb/concurrent_vector.h: In member function ‘tbb::concurrent_vector<T, A>::iterator tbb::concurrent_vector<T, A>::grow_by(tbb::concurrent_vector<T, A>::size_type)’:
/usr/include/tbb/concurrent_vector.h:667:38: error: operands to ?: have different types ‘tbb::internal::concurrent_vector_base_v3::size_type {aka long unsigned int}’ and ‘tbb::atomic<long unsigned int>’
return iterator(*this, delta ? internal_grow_by( delta, sizeof(T), &initialize_array, NULL ) : my_early_size);
~~~~~~^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
/usr/include/tbb/concurrent_vector.h:667:38: note: and each type can be converted to the other
/usr/include/tbb/concurrent_vector.h: In member function ‘tbb::concurrent_vector<T, A>::iterator tbb::concurrent_vector<T, A>::grow_by(tbb::concurrent_vector<T, A>::size_type, tbb::concurrent_vector<T, A>::const_reference)’:
/usr/include/tbb/concurrent_vector.h:680:38: error: operands to ?: have different types ‘tbb::internal::concurrent_vector_base_v3::size_type {aka long unsigned int}’ and ‘tbb::atomic<long unsigned int>’
return iterator(*this, delta ? internal_grow_by( delta, sizeof(T), &initialize_array_by, static_cast<const void*>(&t) ) : my_early_size);
~~~~~~^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
/usr/include/tbb/concurrent_vector.h:680:38: note: and each type can be converted to the other
make: *** [vdb_lod] Error 1
In short, as second and third argument, the ?: operator gets one base type and the same base type wrapped in tbb::atomic, with the compiler not knowing which type to use as return value.
Needless to say, I have no intentions of changing that source code. Since they are established products, it's safe to say that I do something wrong at compiling.
The TBB library file seems to be build with rather old versions of GCC, that is 4.7. I originally thought that the problem might be that I used GCC 7.2.0, therefore I tried out different versions, like GCC 4.8.5, but the error persists.
I haven't tried out 4.7 in particular since I work in a company where I don't have admin rights, and I try to avoid a local installation of GCC. Especially since I don't know if GCC is even the issue here.
Does anyone know a fix to that?
Edit: https://software.intel.com/en-us/forums/intel-threading-building-blocks/topic/417161 seems to be about the same problem, and an employee from Intel noted it for change in there. However, that post was from 2013 and since people used TBB in-between, there must be something I do different in general.
It looks like that an outdated TBB version is used.
See the similar question on the TBB forum.

Is operator void*() conversion still part of C++ library?

Consider this program:
#include <iostream>
int main()
{
delete std::cout;
}
AFAIK the conversion function operator void* () const has been removed from C++11. So, this program should fail in compilation on a C++11 compiler. Ya, its true that both g++ 4.8.1 & 4.9.2 gives diagnosis (in the form of warning that deleting void* is undefined & that's also the good thing). But shouldn't this program fail in compilation because removal of that conversion function due to which all stream object could be implicitly converted to void* in C++98 & C++03?. Is this bug? It seems bit surprising that they still not have implemented this change.
I've tried this program in g++ 4.9.2(that supports C++14) but it gives warning not compiler error. Ideone compiler gives me an error as expected. (See live demo here)
It has nothing to do with the compiler, its a library issue. libstdc++ has lots of incompatibilities with C++11, of which this is just one. They are making breaking changes in 5 and up though iirc.
In short, it's neither a bug nor a compiler issue.
This is a bug in the standard library (if you view it as an implementation of the C++11/14 standard library rather than C++98/03).
It's sort of a compiler issue as well though. Specifically, removing the conversion to void * depends on adding a conversion directly to bool--but that, in turn, depends on adding "contextual conversion" to the compiler.
gcc 4.8 did implement a form of contextual conversion, but not the form that was accepted into the standard. Although the specific changes to contextual conversion wouldn't directly impact this use of contextual conversion, it does point to the fact that the definition of contextual conversion was still being tweaked as these compilers were being written.
The sequence in which things (at least normally) happen is that first the specification is solidified. Then the compiler implements it. Then the standard library puts it to use.
In this case the specification was still changing fairly shortly before the compiler was released. Therefore, the standard library didn't (and practically speaking, couldn't) use it.
By the time of 4.9, the specification was solid, and the compiler implemented the final version of contextual conversion, but it hadn't been around long enough to be put to use in the standard library yet.

STL's power in C++

I've found STL's power in the numeric header that computes power(TYPE T, Integer a) in O(log(a)), but when I've written that and compiled it with g++ it gave me compile error and says error: ‘power’ was not declared in this scope. Why it happens? I know writing the power function that computes in O(log(N)) is easy buy I want to know if there is a ready function in C++'s standard libraries. Isn't any feature added in C++11 standard?
That function was in SGI's original STL, but isn't in the standard library.
In the GNU library, it's available as an extension, __gnu_cxx::power in <ext/numeric>.
From the page you link:
This function is an SGI extension; it is not part of the C++ standard.
While the SGI-documentation is often helpful, be aware that it contains several deviations from the standard.
No there's no std::power or similar algorithms in C++11.
In the <cmath> header there are several overloads for the standard numeric types. Is there a particular reason you need a templated version?

'powf' is not a member of 'std'

I have an error while compiling a library using XCode:
'powf' is not a member of 'std'
The <cmath> is included.
Can someone explain to me what is going wrong?
Up until C++11, powf was just a Microsoft-ism. It did not appear in the ISO standard at all so is unlikely to be in XCode unless they were to adapt Microsoft's bizarre practices, something I would think unlikely.
pow, on the other hand, has been part of the C++ library for longer by virtue of the fact that it's in earlier iterations of the C library that is incorporated into C++ pre-11. Use that instead.
Since C++11, powf does appear in the ISO standard and is part of the std namespace.
Nevertheless, there are non-compliant implementations e.g., gcc libstdc++. More resources in this excerpt taken from a discussion in cppreference talk page:
Answers posted above were correct before C++11, since C++98/03 hadn't referred C99 library yet. According to the current standard, powf is declared in namespace std when is included (explicitly mentioned since C++17, implicitly mentioned in C++11/14, see also N4659, N4140 and N3337). For std::powf, gcc libstdc++ is not compliant while clang libc++ is. --Fruderica (talk) 03:49, 19 February 2019 (PST)
See also this, more recent, SO answer: https://stackoverflow.com/a/54735351 --Cubbi (talk) 08:10, 19 February 2019 (PST)
Use just pow - powf isn't standard.
It is named std::pow and overloaded for float and double.