Incorrect overload resolution in for_each_n? [duplicate] - c++

I have small piece of code for std::for_each_n loop. I tried running it on inbuilt Coliru compiler GCC C++17 using following command :
g++ -std=c++1z -O2 -Wall -pedantic -pthread main.cpp && ./a.out
But compiler give an error that " 'for_each_n' is not a member of 'std' ".
My code is bellow which is copied from cppreference.
#include <algorithm>
#include <iostream>
#include <vector>
int main()
{
std::vector<int> ns{1, 2, 3, 4, 5};
for (auto n: ns) std::cout << n << ", ";
std::cout << '\n';
std::for_each_n(ns.begin(), 3, [](auto& n){ n *= 2; });
for (auto n: ns) std::cout << n << ", ";
std::cout << '\n';
}
So, Why I'm getting an error?

There is nothing wrong with your code. The issue is that libstdc++ does not support std::for_each_n until GCC 8 and Clang 8. If we look at the header that defines std::for_each_n, we see it does not exist.
However, if you have access to libc++, their header from the official mirror does implement std::for_each_n.
(Update: the current version of the GCC repository now also does include for_each_n)

Related

Is this gcc and clang optimizer bug with minmax and structured binding?

This program, built with -std=c++20 flag:
#include <iostream>
using namespace std;
int main() {
auto [n, m] = minmax(3, 4);
cout << n << " " << m << endl;
}
produces expected result 3 4 when no optimization flags -Ox are used. With optimization flags it outputs 0 0. I tried it with multiple gcc versions with -O1, -O2 and -O3 flags.
Clang 13 works fine, but clang 10 and 11 outputs 0 4198864 with optimization level -O2 and higher. Icc works fine. What is happening here?
The code is here: https://godbolt.org/z/Wd4ex8bej
The overload of std::minmax taking two arguments returns a pair of references to the arguments. The lifetime of the arguments however end at the end of the full expression since they are temporaries.
Therefore the output line is reading dangling references, causing your program to have undefined behavior.
Instead you can use std::tie to receive by-value:
#include <iostream>
#include <tuple>
#include <algorithm>
int main() {
int n, m;
std::tie(n,m) = std::minmax(3, 4);
std::cout << n << " " << m << std::endl;
}
Or you can use the std::initializer_list overload of std::minmax, which returns a pair of values:
#include <iostream>
#include <algorithm>
int main() {
auto [n, m] = std::minmax({3, 4});
std::cout << n << " " << m << std::endl;
}

Apple Clang gives error when using bracket initialization, while g++ and ordinary Clang works

This code example from learncpp.com doesn't work on Apple Clang 13.0.0 while working on both ordinary Clang and g++ from Homebrew.
Code
#include <iostream>
int getValueFromUser()
{
std::cout << "Enter an integer: ";
int input{};
std::cin >> input;
return input;
}
void printDouble(int value)
{
std::cout << value << " doubled is: " << value * 2 << '\n';
}
int main()
{
printDouble(getValueFromUser());
return 0;
}
Error
main.cpp:6:11: error: expected ';' at end of declaration
int input{};
^
;
1 error generated.
Does Apple Clang have no support for initializations by brackets? I'm really puzzled right now.
Yeah, seems like Apple Clang's default standard is super old. When I added -std=c++20 as a flag it compiled.

'for_each_n' is not a member of 'std' in C++17

I have small piece of code for std::for_each_n loop. I tried running it on inbuilt Coliru compiler GCC C++17 using following command :
g++ -std=c++1z -O2 -Wall -pedantic -pthread main.cpp && ./a.out
But compiler give an error that " 'for_each_n' is not a member of 'std' ".
My code is bellow which is copied from cppreference.
#include <algorithm>
#include <iostream>
#include <vector>
int main()
{
std::vector<int> ns{1, 2, 3, 4, 5};
for (auto n: ns) std::cout << n << ", ";
std::cout << '\n';
std::for_each_n(ns.begin(), 3, [](auto& n){ n *= 2; });
for (auto n: ns) std::cout << n << ", ";
std::cout << '\n';
}
So, Why I'm getting an error?
There is nothing wrong with your code. The issue is that libstdc++ does not support std::for_each_n until GCC 8 and Clang 8. If we look at the header that defines std::for_each_n, we see it does not exist.
However, if you have access to libc++, their header from the official mirror does implement std::for_each_n.
(Update: the current version of the GCC repository now also does include for_each_n)

Clang performance drop for specific C++ random number generation

Using C++11's random module, I encountered an odd performance drop when using std::mt19937 (32 and 64bit versions) in combination with a uniform_real_distribution (float or double, doesn't matter). Compared to a g++ compile, it's more than an order of magnitude slower!
The culprit isn't just the mt generator, as it's fast with a uniform_int_distribution. And it isn't a general flaw in the uniform_real_distribution since that's fast with other generators like default_random_engine. Just that specific combination is oddly slow.
I'm not very familiar with the intrinsics, but the Mersenne Twister algorithm is more or less strictly defined, so a difference in implementation couldn't account for this difference I guess? measure Program is following, but here are my results for clang 3.4 and gcc 4.8.1 on a 64bit linux machine:
gcc 4.8.1
runtime_int_default: 185.6
runtime_int_mt: 179.198
runtime_int_mt_64: 175.195
runtime_float_default: 45.375
runtime_float_mt: 58.144
runtime_float_mt_64: 94.188
clang 3.4
runtime_int_default: 215.096
runtime_int_mt: 201.064
runtime_int_mt_64: 199.836
runtime_float_default: 55.143
runtime_float_mt: 744.072 <--- this and
runtime_float_mt_64: 783.293 <- this is slow
Program to generate this and try out yourself:
#include <iostream>
#include <vector>
#include <chrono>
#include <random>
template< typename T_rng, typename T_dist>
double time_rngs(T_rng& rng, T_dist& dist, int n){
std::vector< typename T_dist::result_type > vec(n, 0);
auto t1 = std::chrono::high_resolution_clock::now();
for (int i = 0; i < n; ++i)
vec[i] = dist(rng);
auto t2 = std::chrono::high_resolution_clock::now();
auto runtime = std::chrono::duration_cast<std::chrono::microseconds>(t2-t1).count()/1000.0;
auto sum = vec[0]; //access to avoid compiler skipping
return runtime;
}
int main(){
const int n = 10000000;
unsigned seed = std::chrono::system_clock::now().time_since_epoch().count();
std::default_random_engine rng_default(seed);
std::mt19937 rng_mt (seed);
std::mt19937_64 rng_mt_64 (seed);
std::uniform_int_distribution<int> dist_int(0,1000);
std::uniform_real_distribution<float> dist_float(0.0, 1.0);
// print max values
std::cout << "rng_default_random.max(): " << rng_default.max() << std::endl;
std::cout << "rng_mt.max(): " << rng_mt.max() << std::endl;
std::cout << "rng_mt_64.max(): " << rng_mt_64.max() << std::endl << std::endl;
std::cout << "runtime_int_default: " << time_rngs(rng_default, dist_int, n) << std::endl;
std::cout << "runtime_int_mt: " << time_rngs(rng_mt_64, dist_int, n) << std::endl;
std::cout << "runtime_int_mt_64: " << time_rngs(rng_mt_64, dist_int, n) << std::endl;
std::cout << "runtime_float_default: " << time_rngs(rng_default, dist_float, n) << std::endl;
std::cout << "runtime_float_mt: " << time_rngs(rng_mt, dist_float, n) << std::endl;
std::cout << "runtime_float_mt_64: " << time_rngs(rng_mt_64, dist_float, n) << std::endl;
}
compile via clang++ -O3 -std=c++11 random.cpp or g++ respectively. Any ideas?
edit: Finally, Matthieu M. had a great idea: The culprit is inlining, or rather a lack thereof. Increasing the clang inlining limit eliminated the performance penalty. That actually solved a number of performance oddities I encountered. Thanks, I learned something new.
As already stated in the comments, the problem is caused by the fact that gcc inlines more aggressive than clang. If we make clang inline very aggressively, the effect disappears:
Compiling your code with g++ -O3 yields
runtime_int_default: 3000.32
runtime_int_mt: 3112.11
runtime_int_mt_64: 3069.48
runtime_float_default: 859.14
runtime_float_mt: 1027.05
runtime_float_mt_64: 1777.48
while clang++ -O3 -mllvm -inline-threshold=10000 yields
runtime_int_default: 3623.89
runtime_int_mt: 751.484
runtime_int_mt_64: 751.132
runtime_float_default: 1072.53
runtime_float_mt: 968.967
runtime_float_mt_64: 1781.34
Apparently, clang now out-inlines gcc in the int_mt cases, but all of the other runtimes are now in the same order of magnitude. I used gcc 4.8.3 and clang 3.4 on Fedora 20 64 bit.

How to print positive numbers with a prefix + in C++

Is there any way to print the integer along with its sign in c++...i.e. by default if the number is negative we would get a - sign printed. In the same way can we get + before the positive numbers.
int x=-1;
cout<<"x="<<x;
gives output x=-1
but,..
int x=+1;
cout<<"x="<<x;
gives output as x=1 but how do i get it printed as x=+1
I know we can take cases by using if-else for x>0 and x<0;..but without using the if-else is there any direct way of printing in c++
Use std::showpos:
int x = 1;
std::cout << "x=" << std::showpos << x;
C++20 std::format option +
According to https://en.cppreference.com/w/cpp/utility/format/formatter#Standard_format_specification the following should hold:
#include <format>
// "1,+1,1, 1"
std::cout << std::format("{0:},{0:+},{0:-},{0: }", 1);
// "-1,-1,-1,-1"
std::cout << std::format("{0:},{0:+},{0:-},{0: }", -1);
The existing fmt library implements it for before it gets official support: https://github.com/fmtlib/fmt Install on Ubuntu 22.04:
sudo apt install libfmt-dev
Modify source to replace:
<format> with <fmt/core.h>
std::format to fmt::format
main.cpp
#include <iostream>
#include <fmt/core.h>
int main() {
std::cout << fmt::format("{0:},{0:+},{0:-},{0: }\n", 1);
std::cout << fmt::format("{0:},{0:+},{0:-},{0: }\n", -1);
}
and compile and run with:
g++ -std=c++11 -o main.out main.cpp -lfmt
./main.out
Output:
1,+1,1, 1
-1,-1,-1,-1
More information at: std::string formatting like sprintf
How about:
cout<<"x="<<(x>0)?"+":""<<x;
it's a bit clumsy, but fits the bill