C++ 11 undefined reference to `__atomic_store_16' [duplicate] - c++

This question already has an answer here:
is_lock_free not defined in std::atomic<T> in gcc 4.7.2?
(1 answer)
Closed 8 years ago.
The following code fails to link:
#include <atomic>
struct A
{
unsigned long a;
unsigned long b;
};
struct B
{
void set(A tmp)
{
_a.store(tmp);
}
std::atomic<A> _a;
};
int main()
{
B b;
b.set(A());
return 0;
}
With the following error:
/tmp/cc8gyaZM.o: In function `std::atomic<A>::store(A, std::memory_order)':
dryn.cpp: (.text._ZNSt6atomicI1AE5storeES0_St12memory_order[_ZNSt6atomicI1AE5storeES0_St12memory_order]+0x3e): undefined reference to `__atomic_store_16'
If I replace the unsigned long-s with anything that is up-to int in size, this compiles just fine. Using g++ 4.7.2 . Do you have any idea why is that?
Compiled with command:
g++ dryn.cpp --std=c++11

As answered by Zeta:
Atomic API isn't complete in GCC 4.7:
When lock free instructions are not available (either through hardware or OS support) atomic operations are left as function calls
to be resolved by a library. Due to time constraints and an API
which is not finalized, there is no libatomic supplied with GCC 4.7.
This is easily determined by encountering unsatisfied external symbols
beginning with __atomic_*.
Since there is no libatomic shipped with GCC 4.7 you need to use
another compiler which actually supports the features you want or
provide the missing features (sample implementation).

Related

What are the exact requirements for MyType to allow std::atomic<MyType>?

I would like to communicate some Informations between threads.
Atomics sound like the thing to use.
I had a look at this. And found that a simple struct like
struct MyType{
int val_a,val_b;
float vals_c[5];
};
should fullfill the assert:
static_assert(
std::is_trivially_copyable<MyType>::value &&
std::is_copy_constructible<MyType>::value &&
std::is_move_constructible<MyType>::value &&
std::is_copy_assignable<MyType>::value &&
std::is_move_assignable<MyType>::value,
"MyType is not suitable for std::atomic");
)
But a simple program as
//... MyType and static_assert
int main(int argc,char *argv[]){
MyType a;
std::atomic<MyType> b;
b = a;
a = b;
return 0;
}
fails to compile with:
undefined reference to `__atomic_store'
undefined reference to `__atomic_load'
I am using gcc version 5.4 on a 64-bit ubuntu 16.04.
Flags used are: -pipe -g -std=gnu++11 -Wall -W -fPIC
Is it that this is a total wrong use of std::atomic? What are the requirements to MyType? Or is just something missing from this setup?
As always, documentation is your friend:
The primary std::atomic template may be instantiated with any TriviallyCopyable type T satisfying both CopyConstructible and CopyAssignable. The program is ill-formed if any of following values is false:
std::is_trivially_copyable<T>::value
std::is_copy_constructible<T>::value
std::is_move_constructible<T>::value
std::is_copy_assignable<T>::value
std::is_move_assignable<T>::value
So, your assert is good.
Later it says:
On gcc and clang, some of the functionality described here requires linking against -latomic.
So, if the program still fails to build, you may need to link against libatomic.
If it still doesn't work, you probably have a compiler bug.

Compiler Error on std::sort function (GCC 4.4)

The code below sorting in Visual Studio successfully.
But, in Ubuntu GCC 4.4.7 compiler throws error. It seems it's not familiar with this type of syntax.
How shall I fix this line to make code working in GCC? (the compiler is remote. So I can't upgrade the GCC version either).
What I'm doing right here is:sorting Vector B elements regarding their fitness values
//B is a Vector of class Bird
//fitness is a double - member of Bird objects
vector<Bird> Clone = B;
sort(Clone.begin(), Clone.end(), [](Bird a, Bird b) { return a.fitness> b.fitness; });
//error: expected primary expresssion before '[' token
//error: expected primary expresssion before ']' token...
(Note: this 3 piece of lines compiling successful in MSVC but not in GCC)
my answer is
bool X_less(Bird a, Bird b) { return a.fitness > b.fitness; }
std::sort(Clone.begin(), Clone.end(), &X_less);
It seems to work. Is it a function or not? I don't know its technical name, but it seems to work. I am not much familiar with C++.
You will need to upgrade your C++ as 4.4 is too old to support Lambda. I have Gcc 4.8, but it still requires you enable c++11 that includes lambda functions, so
$ g++ -std=c++11 x.cc
compiles this fine
#include <algorithm>
#include <functional>
#include <vector>
using namespace std;
int main()
{
vector<int> Clone;
sort(Clone.begin(), Clone.end(), [](int a, int b) { return a> b; });
}
but still gives errors without -std=c++11 option

c++ strict-aliasing rules compile error with Qt and QLinkedList [duplicate]

This question already has answers here:
What is the strict aliasing rule?
(11 answers)
Closed 9 years ago.
In file included from /usr/local/Qt/linux-g++/include/QtCore/QLinkedList:2,
from /home/bamboo/Packages/Parser.h:17,
from /home/bamboo/Packages/Module.cpp:6:
/usr/local/Qt/linux-g++/include/QtCore/qlinkedlist.h: In member function 'void QLinkedList<T>::clear() [with T = int]':
/usr/local/Qt/linux-g++/include/QtCore/qlinkedlist.h:294: error: dereferencing pointer 'y' does break strict-aliasing rules
/usr/local/Qt/linux-g++/include/QtCore/qlinkedlist.h:293: note: initialized from here
/usr/local/Qt/linux-g++/include/QtCore/qlinkedlist.h:294: error: dereferencing pointer 'y' does break strict-aliasing rules
/usr/local/Qt/linux-g++/include/QtCore/qlinkedlist.h:293: note: initialized from here
where in big lines class Module contains a member template like: Parser<int> and the class parser is defined:
template <typename T> class Parser
{
// some stuff
QLinkedList<T> stuff;
};
and this piece of code compiles nicely with gcc (Ubuntu 4.4.3-4ubuntu5.1) 4.4.3 and nicely with g++ (Ubuntu/Linaro 4.7.2-2ubuntu1) 4.7.2 and fails with g++ (Debian 4.4.5-8) 4.4.5 ... and I have no idea why? Anyone has seen this error message and anyone know what this might mean?... and more importantly how to solve it?
Aliasing means that a pointer int *i points to the same address as double *d.
So if
int i = 5;
int *pi = &i:
double *d = pi;
here d is aliasing pi.
this is in c99 >illegal<
I don't know how exactly c++ treats it, but I can't imagine it is welcome.
If you want to test a code where it will be getting funny, try this code in different optimisation levels.
You will get differen results with gcc 4.2
uint32_t anint;
int main(int arg, char** argv)
{
foo ((uint64_t *)&anint);
return 0;
}
void foo (uint64_t *dblptr)
{
anint = 88;
*dblptr = 86;
dosmthng (anint);
}
void dosmthng (uint32_t val)
{
printf ("%d\r\n", val);
}
if you do -O2 or higher the output will be 88. because the compiler expects you to respect the strict-aliasing rule and expects *dblptr as never been used in this code, and jsut takes the line out.
If you any way see no way of working wihtout aliasing, you can give the compiler the param -fno-strict-aliasing. This forces GCC to do not any optimisation based on this expection.
But anyway in C it is not strict ISO C code if you do wrong type punning.
(So if it may ease you, a lot of C code on famous programms gets compiled with -fno-strict-aliasing)

Why are std::stoi and std::array not compiling with g++ c++11?

I've been learning C++ and using the Terminal for the last couple of months. My code was compiling and running fine using g++ and C++11, but in the last couple of days it started giving errors and I have had problems compiling since. The only programs I can compile and run depend on older C++ standards.
The errors I first got related to #include < array > in the header file. Not sure why this happened, but I got around it by using boost/array instead. Another error I can't solve is with std::stoi. Both array and stoi should be in the C++11 standard library. I made the following simple code to demonstrate what's going on:
//
// stoi_test.cpp
//
// Created by ecg
//
#include <iostream>
#include <string> // stoi should be in here
int main() {
std::string test = "12345";
int myint = std::stoi(test); // using stoi, specifying in standard library
std::cout << myint << '\n'; // printing the integer
return(0);
}
Try to compile using ecg$ g++ -o stoi_trial stoi_trial.cpp -std=c++11
array.cpp:13:22: error: no member named 'stoi' in namespace 'std'; did you mean
'atoi'?
int myint = std::stoi(test);
~~~~~^~~~
atoi
/usr/include/stdlib.h:149:6: note: 'atoi' declared here
int atoi(const char *);
^
array.cpp:13:27: error: no viable conversion from 'std::string' (aka
'basic_string') to 'const char *'
int myint = std::stoi(test);
^~~~
/usr/include/stdlib.h:149:23: note: passing argument to parameter here
int atoi(const char *);
^
2 errors generated.
I also get these errors at compilation when using gcc or clang++ and with -std=gnu++11 (I guess they all depend on the same file structure). I also get the same error whether I specify std:: in the code, or if I specify using namespace std;
I worry that these issues arose because of the September Command Line Tools update via Xcode or because I installed boost and this somehow messed up my C++11 libraries. Hopefully there is a simple solution.
My system:
Configured with: --prefix=/Applications/Xcode.app/Contents/Developer/usr --with-gxx-include-> dir=/usr/include/c++/4.2.1
Apple LLVM version 5.0 (clang-500.2.76) (based on LLVM 3.3svn)
Target: x86_64-apple-darwin12.5.0
Thread model: posix
Thanks for any insight you can offer.
clang has a weird stdlib, you need to add the following flag when you compile
-stdlib=libc++
your snippet works on my mac with
g++ -std=gnu++11 -stdlib=libc++ test.cpp -o test
This answer describes the problem

Difference between -Wconversion between gcc and g++ [duplicate]

This question already has answers here:
Closed 10 years ago.
Possible Duplicate:
Can I make GCC warn on passing too-wide types to functions?
Consider the following test program:
static void func(int a)
{
}
int main()
{
unsigned int b = 42;
func(b);
return 0;
}
Compiling it with gcc:
lol#mac:~/projects$ gcc -Wconversion testit.c
testit.c: In function âmainâ:
testit.c:11: warning: passing argument 1 of âfuncâ as signed due to prototype
lol#mac:~/projects$
But, in g++ there is no warning!:
lol#mac:~/projects$ g++ -Wconversion testit.c
lol#mac:~/projects$
What is the reason for this and is there any way to get the same warning when compiling C++ code?
From the documentation for -Wconversion:
Warnings about conversions between signed and unsigned integers are disabled by default in C++ unless -Wsign-conversion is explicitly enabled.
Seems that you'll need a sufficiently new version of GCC, too. I have version 4.0.1, and it doesn't recognize -Wsign-conversion.