Building Transactional Memory C++ Code in g++ - c++

The cppreference website has a (work in progress) page describing transactional memory c++ code. This is the first example on the page
#include <iostream>
#include <vector>
#include <thread>
int f()
{
static int i = 0;
synchronized { // begin synchronized block
std::cout << i << " -> ";
++i; // each call to f() obtains a unique value of i
std::cout << i << '\n';
return i; // end synchronized block
}
}
int main()
{
std::vector<std::thread> v(10);
for(auto& t: v)
t = std::thread([]{ for(int n = 0; n < 10; ++n) f(); });
for(auto& t: v)
t.join();
}
Toward the bottom of that page, there is an indication that this builds on gcc (// GCC assembly with the attribute:).
I can't get this to build on g++ 5.3.1:
$ g++ --std=c++11 -fgnu-tm -lpthread trx.cpp
trx.cpp: In function ‘int f()’:
trx.cpp:7:5: error: ‘synchronized’ was not declared in this scope
synchronized { // begin synchronized block
^
$ g++ --help | grep transaction
$ g++ --version
g++ (Ubuntu 5.3.1-14ubuntu2.1) 5.3.1 20160413
gcc documentation does have a page on transactional memory, but the primitives are different (e.g., the atomic block is __transaction_atomic). The page on cppreference.com conversely appears to be related to N3919, and uses the primitives from there.
How can this code be built with g++?

The transactional_memory link you mention first says:
Compiler support
This technical specification is supported by GCC as of version 6.1 (requires -fgnu-tm to enable).
So you need GCC 6 (and probably also -std=c++1z in addition to -fgnu-tm ....)

Related

Why GCC does not report uninitialized variable?

#include <ios>
#include <iostream>
#include <map>
using namespace std;
int main() {
ios_base::sync_with_stdio(false);
map<int, int> v;
int i;
int t;
while (cin >> i) {
v[i] = t++;
}
auto mi = i;
auto mt = t;
for (const auto p : v) {
if (p.second < mt) {
mi = p.first;
mt = p.second;
}
}
cout << mi << '\n';
return 0;
}
The abovementioned program makes heavy use of an uninitialized variable t, but GCC does not report it with -Wall or -Wuninitialized. Why is it so?
It is worth noting that Clang catches it:
main.cpp:13:12: warning: variable 't' is uninitialized when used here [-Wuninitialized]
v[i] = t++;
^
Used g++ (GCC) 7.2.1 20170915 (Red Hat 7.2.1-2).
Used clang version 4.0.1 (tags/RELEASE_401/final).
As you can see in https://godbolt.org/g/kmYMC1 GCC 7.2 does not report it even when it should. I will create a ticket in GCC's issue tracker.
g++'s warning flag is not called -Wuninitialized: it is called -Wmaybe-uninitialized.
Also, as Jonathan Wakely noted in his answer, g++ is able to detect usage of uninitialized variables only when optimizations are enabled.
Enabling both -Wmaybe-initalized and optimizations produces the expected warning: https://godbolt.org/g/3CZ6kT
Note that -Wmaybe-initalized is enabled by default with both -Wall and -Wextra.
GCC can only detect uninitialized variables when optimization is enabled, because the logic for tracking the values of variables is part of the optimization machinery.
If you compile with -O -Wall you get a warning:
<source>: In function 'int main()':
12 : <source>:12:13: warning: 't' may be used uninitialized in this function [-Wmaybe-uninitialized]
v[i] = t++;
~^~
Compiler exited with result code 0
https://godbolt.org/g/327bsi

Why does GCC optimization not work with valarrays?

This is a simple c++ program using valarrays:
#include <iostream>
#include <valarray>
int main() {
using ratios_t = std::valarray<float>;
ratios_t a{0.5, 1, 2};
const auto& res ( ratios_t::value_type(256) / a );
for(const auto& r : ratios_t{res})
std::cout << r << " " << std::endl;
return 0;
}
If I compile and run it like this:
g++ -O0 main.cpp && ./a.out
The output is as expected:
512 256 128
However, if I compile and run it like this:
g++ -O3 main.cpp && ./a.out
The output is:
0 0 0
Same happens if I use -O1 optimization parameter.
GCC version is (latest in Archlinux):
$ g++ --version
g++ (GCC) 6.1.1 20160707
However, if I try with clang, both
clang++ -std=gnu++14 -O0 main.cpp && ./a.out
and
clang++ -std=gnu++14 -O3 main.cpp && ./a.out
produce the same correct result:
512 256 128
Clang version is:
$ clang++ --version
clang version 3.8.0 (tags/RELEASE_380/final)
I've also tried with GCC 4.9.2 on Debian, where executable produces the correct result.
Is this a possible bug in GCC or am I doing something wrong? Can anyone reproduce this?
EDIT: I managed to reproduce the issue also on Homebrew version of GCC 6 on Mac OS.
valarray and auto do not mix well.
This creates a temporary object, then applies operator/ to it:
const auto& res ( ratios_t::value_type(256) / a );
The libstdc++ valarray uses expression templates so that operator/ returns a lightweight object that refers to the original arguments and evaluates them lazily. You use const auto& which causes the expression template to be bound to the reference, but doesn't extend the lifetime of the temporary that the expression template refers to, so when the evaluation happens the temporary has gone out of scope, and its memory has been reused.
It will work fine if you do:
ratios_t res = ratios_t::value_type(256) / a;
Update: as of today, GCC trunk will give the expected result for this example. I've modified our valarray expression templates to be a bit less error-prone, so that it's harder (but still not impossible) to create dangling references. The new implementation should be included in GCC 9 next year.
It's the result of careless implementation of operator/ (const T& val, const std::valarray<T>& rhs) (and most probably other operators over valarrays) using lazy evaluation:
#include <iostream>
#include <valarray>
int main() {
using ratios_t = std::valarray<float>;
ratios_t a{0.5, 1, 2};
float x = 256;
const auto& res ( x / a );
// x = 512; // <-- uncommenting this line affects the output
for(const auto& r : ratios_t{res})
std::cout << r << " ";
return 0;
}
With the "x = 512" line commented out, the output is
512 256 128
Uncomment that line and the output changes to
1024 512 256
Since in your example the left-hand side argument of the division operator is a temporary, the result is undefined.
UPDATE
As Jonathan Wakely correctly pointed out, the lazy-evaluation based implementation becomes a problem in this example due to the usage of auto.

Is this (auto && elem : v) syntax simple C++? what compiler should I use to have it compile?

I used to code in C++ 12 years ago, but left it for other simpler languages due to my job.
I'd like to renew my knowledge and tried to compile the solution proposed here, just to try this new way to iterate on vectors. But ran into a compile error:
expected initializer before ‘:’ token
I didn't know it was possible to avoid explicit declaration of iterators like that in C++ with the use of this (auto && elem : v). What version of C++ is it?
b.cpp
#include <iostream>
#include <vector>
#include <utility>
#include <algorithm>
#include <string>
#include <set>
int main()
{
std::vector<std::pair<std::string, std::string>> v
{ {"handgun", "bullets"},
{"turret", "bullets"}};
std::cout << "Initially: " << std::endl << std::endl;
for (auto && elem : v)
std::cout << elem.first << " " << elem.second << std::endl;
return 0;
}
Compilation
$ cc b.cpp -std=c++0x -o myprog
Errors
b.cpp: In function ‘int main()’:
b.cpp:15: error: expected initializer before ‘:’ token
...
C++ Compilers I use: g++
$ g++ --version
gives
g++ (GCC) 4.4.7 20120313 (Red Hat 4.4.7-3)
Copyright (C) 2010 Free Software Foundation, Inc.
Your compiler is too old. Ranged-based for loops weren't added until 4.6.
Also, ignore the comments. cc is usually symlinked to gcc. From the manual:
GCC recognizes files with these names and compiles them as C++
programs even if you call the compiler the same way as for compiling C
programs (usually with the name gcc).
Following pupper's advice, I adapted my code to the below:
#include <iostream>
#include <vector>
int main()
{
std::vector<std::pair<std::string, std::string>> v
{ {"handgun", "bullets"},
{"turret", "bullets"}};
std::cout << "started: " << std::endl;
std::vector<std::pair<std::string, std::string>>::iterator Current_Iterator = v.begin();
while(Current_Iterator != v.end())
{
std::cout << Current_Iterator->first << " " << Current_Iterator->second << std::endl;
Current_Iterator++;
}
return 0;
}
It still doesn't compile with the gcc on my system, giving
b.cpp:(.text+0x134): undefined reference to ``std::cout'
...
But it works with g++:
$ g++ b.cpp -std=c++0x -o myprog && ./myprog
started:
handgun bullets
turret bullets

Enable multithreading Eclipse C++

I have been trying to get a program working in Eclipse C++. One of the functions uses multithreading from std. Here is the function in the code:
void PrimeCheck::checkFull(long long int number)
{
std::thread t1(&PrimeCheck::checkFirstHalf, this, number);
std::thread t2(&PrimeCheck::checkSecondHalf, this, number);
t1.join();
t2.join();
}
When searching for a solution, I came across many solutions, all of which stating to either add a -pthread flag or a -std=c++11 in addition to changing the dialect to C++11. All of which I have done. This is what the compile command looks like in eclipse so you can see exactly which modifications I have already added:
Building file: ../src/Prime Checker.cpp
Invoking: GCC C++ Compiler
g++ -std=c++0x -D__GXX_EXPERIMENTAL_CXX0X__ -O2 -g -Wall -c -fmessage-length=0 -std=c++11 -pthread -Wl,--whole-archive -lpthread -Wl,--no-whole-archive -MMD -MP -MF"src/Prime Checker.d" -MT"src/Prime\ Checker.d" -o "src/Prime Checker.o" "../src/Prime Checker.cpp"
Finished building: ../src/Prime Checker.cpp
And this is the linker command as it appears in eclipse:
Invoking: GCC C++ Linker
g++ -Wl,--no-as-needed -pthread -shared -o [A bunch of .o files]
The code compiles correctly, and eclipse content assist recognizes thread as a member of std. Yet, when I run the program I still this error:
terminate called after throwing an instance of 'std::system_error'
what(): Enable multithreading to use std::thread: Operation not permitted
To test this, I wrote a simple program outside of Eclipse which looked like this:
#include <thread>
#include <iostream>
using namespace std;
void func1(int x){
for(int i=0; i<x; i++){
cout << " " << 1 + i;
}
}
void func2(){
for(int j=0; j<5; j++){
cout << "Standard message! ";
}
}
int main(){
int input;
cout << "Give me a number:" << endl;
cin >> input;
thread t1(func1, input);
thread t2(func2);
t1.join();
t2.join();
return 0;
}
And compiled it in the terminal with this:
g++ ThreadTest.cpp -o Program.o -std=c++11 -pthread
And the program ran without error. I think this means that there's something wrong with Eclipse, but I'm not sure.
As a note, I'm doing this on Ubuntu 14.04 with gcc version 4.8.4. Also, I know that similar questions have been asked, but as far as I can tell, I've implemented those solutions with little success.
Help would be appreciated. Thanks!
Solved. Using Eclipse IDE for C/C++ Developers v4.7.3a in Ubuntu 14.04.
1/2. Problem description
Just trying to run this sample code:
mutex.cpp:
// mutex example
#include <iostream> // std::cout
#include <thread> // std::thread
#include <mutex> // std::mutex
std::mutex mtx; // mutex for critical section
void print_block (int n, char c) {
// critical section (exclusive access to std::cout signaled by locking mtx):
mtx.lock();
for (int i=0; i<n; ++i) { std::cout << c; }
std::cout << '\n';
mtx.unlock();
}
int main ()
{
std::thread th1 (print_block,50,'*');
std::thread th2 (print_block,50,'$');
th1.join();
th2.join();
return 0;
}
From: http://www.cplusplus.com/reference/mutex/mutex/
It builds and runs just fine on the command line with the following command, but will not run in Eclipse!
Command-line command that builds and runs in a terminal just fine:
g++ -Wall -std=c++11 -save-temps=obj mutex.cpp -o ./bin/mutex -pthread && ./bin/mutex
Eclipse error when I try to run it in Eclipse:
terminate called after throwing an instance of 'std::system_error'
what(): Enable multithreading to use std::thread: Operation not permitted
2/2. The solution to make it build and run in Eclipse is as follows:
A. Enable pthread for compiler:
Project --> Properties --> C/C++ Build --> Settings --> GCC C++ Compiler --> Miscellaneious --> type in -std=c++11 to the "Other flags" box, and check the box for "Support for pthread (-pthread)". See yellow highlighting here:
B. Enable pthread for Linker:
Then, withOUT closing this window, also set this setting for the Linker:
in center pane: GCC C++ Linker --> General --> check the box for "Support for pthread (-pthread)", as shown here:
Click "Apply and Close". It will now build and run.

Vectors of vectors string issue

i'm in a situation with a declaration of vector<vector<string>>. On windows it's ok i can declare this in a struct like vector<vector<string>>v={{"me","you"}} but on a linux machine..only errors so i must declare it after the struct initialization but how because mystruct.vec[0]={"me","you"} gives me a segmentation fault. Any sugestions please?
This program on gcc 4.7.2 works just fine:
#include <vector>
#include <string>
#include <utility>
#include <iostream>
using ::std::vector;
using ::std::string;
using ::std::move;
vector<vector<string>> foo()
{
vector<vector<string>>v={{"me","you"}};
return move(v);
}
int main()
{
using ::std::cout;
cout << "{\n";
for (auto &i: foo()) {
cout << " {\n";
for (auto &o: i) {
cout << " \"" << o << "\",\n";
}
cout << " },\n";
}
cout << "}\n";
return 0;
}
It produces this output:
$ /tmp/a.out
{
{
"me",
"you",
},
}
I think your problem is either an old compiler or that you have some other problem in some other place in your code.
I used this command line to compile:
$ g++ -std=gnu++0x -march=native -mtune=native -Ofast -Wall -Wextra vvstr.cpp
And my g++ gives this as a version:
$ g++ --version
g++ (GCC) 4.7.2 20121109 (Red Hat 4.7.2-8)
Copyright (C) 2012 Free Software Foundation, Inc.
This is free software; see the source for copying conditions. There is NO
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
This page tells you which version of gcc has which C++ feature:
http://gcc.gnu.org/projects/cxx0x.html
If you are using GCC, them you need a version that supports this C++11 initialization feature, and then you need to tell the compiler to compile in C++11 mode by passing it the -std=c++0x flag (or =std=c++11 for the 4.7 series). See this demo, compiled with GCC 4.7.2:
#include <vector>
#include <string>
int main()
{
std::vector<std::vector<std::string>> v = {{"me","you"}};
}