Consider the following Minimal Complete:
#include <numeric>
int main() {
std::transform_reduce();
}
An attempt to compile it with GCC 7.2 results in error:
[bipll#home ~]$ g++ -std=c++17 omg.cpp
omg.cpp: In function ‘int main()’:
omg.cpp:4:7: error: ‘transform_reduce’ is not a member of ‘std’
std::transform_reduce();
^~~~~~~~~~~~~~~~
[bipll#home ~]$ g++ -v |& tail -1
gcc version 7.2.0 (GCC)
I have tried to find something related on https://gcc.gnu.org/projects/cxx-status.html but it mostly covers language features and I haven't seen anything on new STL definitions support (sometimes this can be trivially automated, like checking #if __has_include(<execution>), but <numeric> is an old include and I don't see any clean way to check whether it contains a particular definition). Aside from scriptedly parsing STL headers, are there any quick info sources on whether something described in current draft has already been implemented? and when something else will probably be?
The library (libstdc++) support is documented on a different page:
https://gcc.gnu.org/onlinedocs/libstdc++/manual/status.html#status.iso.201z
The "Parallelism TS" is still marked as "No", so it's not been implemented yet. It's also not implemented in Clang. You can test various compilers here:
https://gcc.godbolt.org
Related
I'm starting a project using C++, which I haven't used before outside of a handful of school projects - nowhere near the scope of what I'm tackling now.
My goal is to try my best to follow the C++ Core Guidelines as I work to avoid errors, improve performance, and most importantly: improve maintainability of my code.
I've been running into literally hundreds of issues ranging from my g++ / Clang++ versions not being right to standard libraries not being found to g++ using the wrong version of C++ for compilation to very basic functions not behaving as expected - and I haven't even started to look into autotools, so I expect many more headaches to follow.
This question is specific to one part of the C++ Core Guidelines, though. Interfaces 6: Prefer Expects() for expressing preconditions
I tried writing the following simple code:
#include <iostream>
using namespace std;
int square(int x) {
Expects(x > 0);
return x * x;
}
int main() {
cout << square(3) << endl;
return 0;
}
This threw an error in g++:
$> g++ -std=c++17 main.cpp
main.cpp: In function ‘int square(int)’:
main.cpp:7:2: error: ‘Expects’ was not declared in this scope
Expects(x > 0);
^~~~~~~
-> [1]
I tried using Clang, as well, but it has an entirely different (and unrelated) problem:
$> clang++ -x c++ main.cpp
main.cpp:1:10: fatal error: 'iostream' file not found
#include <iostream>
^~~~~~~~~~
1 error generated.
-> [1]
I haven't figured out how to fix that one yet, so I'm not bothering with it.
Expects is part of the GSL library. You have to use some GSL library implementation, which you can find on Github:
https://github.com/martinmoene/gsl-lite
https://github.com/Microsoft/GSL
These are the ones I have off the top of my head.
The CPP Guidelines likely allude to the "contracts" proposal which provides the same checks via attributes. It was scheduled for C++20, but later removed for lack of consensus on its scope. See p1823r0 and a standard committee member's Reddit thread on the rationale leading to the removal.
Apart from GSL, Excepts exists also in C++20 not in C++17 with a little different syntax
https://en.cppreference.com/w/cpp/language/attributes/contract
One can call sph_legendre from tr1 and compile it with gcc-5 or gcc-6
#include<tr1/cmath>
int main()
{
std::tr1::sph_legendre(1,1,0);
return 0;
}
Unfortunately, if I try to compile it with clang++ as:
clang++ -stdlib=libstdc++ legendre.cpp -o legendre
I get
error: no member named 'sph_legendre' in namespace 'std::tr1'
In the section 40.3, The C++PP (4th edition) states:
"There is a separate ISO standard for special mathematical functions [C++Math,2010]. An implementation may add these functions to cmath"
How can I compile these special functions with clang++?
As Richard already mentioned, clang does not support std::sph_legendre at the moment.
A possible workaround for you is to use the boost libraries (http://www.boost.org)
and include header: boost/math/tr1.hpp
In 29.5 Atomic types of the C++ Standard November 2014 working draft it states:
There is a generic class template atomic. The type of the template argument T shall be trivially copyable (3.9). [ Note: Type arguments that are not also statically initializable may be difficult to use. —end note ]
So - as far as I can tell - this:
#include <atomic>
struct Message {
unsigned long int a;
unsigned long int b;
};
std::atomic<Message> sharedState;
int main() {
Message tmp{1,2};
sharedState.store(tmp);
Message tmp2=sharedState.load();
}
should be perfectly valid standard c++14 (and also c++11) code. However, if I don't link libatomic manually, the command
g++ -std=c++14 <filename>
gives - at least on Fedora 22 (gcc 5.1) - the following linking error:
/tmp/ccdiWWQi.o: In function `std::atomic<Message>::store(Message, std::memory_order)':
main.cpp:(.text._ZNSt6atomicI7MessageE5storeES0_St12memory_order[_ZNSt6atomicI7MessageE5storeES0_St12memory_order]+0x3f): undefined reference to `__atomic_store_16'
/tmp/ccdiWWQi.o: In function `std::atomic<Message>::load(std::memory_order) const':
main.cpp:(.text._ZNKSt6atomicI7MessageE4loadESt12memory_order[_ZNKSt6atomicI7MessageE4loadESt12memory_order]+0x1c): undefined reference to `__atomic_load_16'
collect2: error: ld returned 1 exit status
If I write
g++ -std=c++14 -latomic <filename>
everything is fine.
I know that the standard doesn't say anything about compiler flags or libraries that have to be included, but so far I thought that any standard conformant, single file code can be compiled via the first command.
So why doesn't that apply to my example code? Is there a rational why -latomic is still necessary, or is it just something that hasn't been addressed by the compiler maintainers, yet?
Relevant reading on the GCC homepage on how and why GCC makes library calls in certain cases regarding <atomic> in the first place.
GCC and libstdc++ are only losely coupled. libatomic is the domain of the library, not the compiler -- and you can use GCC with a different library (which might provide the necessary definitions for <atomic> in its main proper, or under a different name), so GCC cannot just assume -latomic.
Also:
GCC 4.7 does not include a library implementation as the API has not been firmly established.
The same page claims that GCC 4.8 shall provide such a library implementation, but plans are the first victims of war. I'd guess the reason for -latomic still being necessary can be found in that vicinity.
Besides...
...so far I thought that any standard conformant, single file code can be compiled via the first command.
...-lm has been around for quite some time if you're using math functions.
I know that the standard doesn't say anything about compiler flags or libraries that have to be included
Right.
but so far I thought that any standard conformant, single file code can be compiled via the first command.
Well, no. As you just said, there is no particular reason to assume this. Consider also that GCC extensions are enabled by default.
That being said, it seems self-evident that the intention is to make -latomic a default part of the runtime when it's settled down a bit.
g++ is a wrapper for gcc which adds the correct C++ libraries. Clearly -latomic is missing from that list. Not a core compiler problem then, simply a minor bug in the wrapper.
In 29.5 Atomic types of the C++ Standard November 2014 working draft it states:
There is a generic class template atomic. The type of the template argument T shall be trivially copyable (3.9). [ Note: Type arguments that are not also statically initializable may be difficult to use. —end note ]
So - as far as I can tell - this:
#include <atomic>
struct Message {
unsigned long int a;
unsigned long int b;
};
std::atomic<Message> sharedState;
int main() {
Message tmp{1,2};
sharedState.store(tmp);
Message tmp2=sharedState.load();
}
should be perfectly valid standard c++14 (and also c++11) code. However, if I don't link libatomic manually, the command
g++ -std=c++14 <filename>
gives - at least on Fedora 22 (gcc 5.1) - the following linking error:
/tmp/ccdiWWQi.o: In function `std::atomic<Message>::store(Message, std::memory_order)':
main.cpp:(.text._ZNSt6atomicI7MessageE5storeES0_St12memory_order[_ZNSt6atomicI7MessageE5storeES0_St12memory_order]+0x3f): undefined reference to `__atomic_store_16'
/tmp/ccdiWWQi.o: In function `std::atomic<Message>::load(std::memory_order) const':
main.cpp:(.text._ZNKSt6atomicI7MessageE4loadESt12memory_order[_ZNKSt6atomicI7MessageE4loadESt12memory_order]+0x1c): undefined reference to `__atomic_load_16'
collect2: error: ld returned 1 exit status
If I write
g++ -std=c++14 -latomic <filename>
everything is fine.
I know that the standard doesn't say anything about compiler flags or libraries that have to be included, but so far I thought that any standard conformant, single file code can be compiled via the first command.
So why doesn't that apply to my example code? Is there a rational why -latomic is still necessary, or is it just something that hasn't been addressed by the compiler maintainers, yet?
Relevant reading on the GCC homepage on how and why GCC makes library calls in certain cases regarding <atomic> in the first place.
GCC and libstdc++ are only losely coupled. libatomic is the domain of the library, not the compiler -- and you can use GCC with a different library (which might provide the necessary definitions for <atomic> in its main proper, or under a different name), so GCC cannot just assume -latomic.
Also:
GCC 4.7 does not include a library implementation as the API has not been firmly established.
The same page claims that GCC 4.8 shall provide such a library implementation, but plans are the first victims of war. I'd guess the reason for -latomic still being necessary can be found in that vicinity.
Besides...
...so far I thought that any standard conformant, single file code can be compiled via the first command.
...-lm has been around for quite some time if you're using math functions.
I know that the standard doesn't say anything about compiler flags or libraries that have to be included
Right.
but so far I thought that any standard conformant, single file code can be compiled via the first command.
Well, no. As you just said, there is no particular reason to assume this. Consider also that GCC extensions are enabled by default.
That being said, it seems self-evident that the intention is to make -latomic a default part of the runtime when it's settled down a bit.
g++ is a wrapper for gcc which adds the correct C++ libraries. Clearly -latomic is missing from that list. Not a core compiler problem then, simply a minor bug in the wrapper.
In 29.5 Atomic types of the C++ Standard November 2014 working draft it states:
There is a generic class template atomic. The type of the template argument T shall be trivially copyable (3.9). [ Note: Type arguments that are not also statically initializable may be difficult to use. —end note ]
So - as far as I can tell - this:
#include <atomic>
struct Message {
unsigned long int a;
unsigned long int b;
};
std::atomic<Message> sharedState;
int main() {
Message tmp{1,2};
sharedState.store(tmp);
Message tmp2=sharedState.load();
}
should be perfectly valid standard c++14 (and also c++11) code. However, if I don't link libatomic manually, the command
g++ -std=c++14 <filename>
gives - at least on Fedora 22 (gcc 5.1) - the following linking error:
/tmp/ccdiWWQi.o: In function `std::atomic<Message>::store(Message, std::memory_order)':
main.cpp:(.text._ZNSt6atomicI7MessageE5storeES0_St12memory_order[_ZNSt6atomicI7MessageE5storeES0_St12memory_order]+0x3f): undefined reference to `__atomic_store_16'
/tmp/ccdiWWQi.o: In function `std::atomic<Message>::load(std::memory_order) const':
main.cpp:(.text._ZNKSt6atomicI7MessageE4loadESt12memory_order[_ZNKSt6atomicI7MessageE4loadESt12memory_order]+0x1c): undefined reference to `__atomic_load_16'
collect2: error: ld returned 1 exit status
If I write
g++ -std=c++14 -latomic <filename>
everything is fine.
I know that the standard doesn't say anything about compiler flags or libraries that have to be included, but so far I thought that any standard conformant, single file code can be compiled via the first command.
So why doesn't that apply to my example code? Is there a rational why -latomic is still necessary, or is it just something that hasn't been addressed by the compiler maintainers, yet?
Relevant reading on the GCC homepage on how and why GCC makes library calls in certain cases regarding <atomic> in the first place.
GCC and libstdc++ are only losely coupled. libatomic is the domain of the library, not the compiler -- and you can use GCC with a different library (which might provide the necessary definitions for <atomic> in its main proper, or under a different name), so GCC cannot just assume -latomic.
Also:
GCC 4.7 does not include a library implementation as the API has not been firmly established.
The same page claims that GCC 4.8 shall provide such a library implementation, but plans are the first victims of war. I'd guess the reason for -latomic still being necessary can be found in that vicinity.
Besides...
...so far I thought that any standard conformant, single file code can be compiled via the first command.
...-lm has been around for quite some time if you're using math functions.
I know that the standard doesn't say anything about compiler flags or libraries that have to be included
Right.
but so far I thought that any standard conformant, single file code can be compiled via the first command.
Well, no. As you just said, there is no particular reason to assume this. Consider also that GCC extensions are enabled by default.
That being said, it seems self-evident that the intention is to make -latomic a default part of the runtime when it's settled down a bit.
g++ is a wrapper for gcc which adds the correct C++ libraries. Clearly -latomic is missing from that list. Not a core compiler problem then, simply a minor bug in the wrapper.