Strange compilation error: compiler bug or my own? - c++

I have header-only library, and I'm getting the strangest compilation error. The problem in proceeding is that I'm not getting this error in a representative minimal example, and not on all compilers (on macOS everything compiles and runs like a charm). I am not sure if I should be worried about something in my code, or if it is an upstream bug. Regardless, I'm not sure how to work around this.
I'm getting the following compiler error:
In file included from /home/tdegeus/opt/include/eigen3/Eigen/SparseCore:59:0,
from /home/tdegeus/opt/include/eigen3/Eigen/Sparse:26,
from /home/tdegeus/opt/include/eigen3/Eigen/Eigen:2,
from /home/tdegeus/prog/src/GooseFEM/docs/examples/Statics/Periodic/LinearElasticity/main.cpp:1:
/home/tdegeus/opt/include/eigen3/Eigen/src/SparseCore/SparseSelfAdjointView.h: In function ‘void Eigen::internal::permute_symm_to_symm(const MatrixType&, Eigen::SparseMatrix<typename MatrixType::Scalar, DestOrder, typename MatrixType::StorageIndex>&, const typename MatrixType::StorageIndex*) [with int SrcMode = 1; int DstMode = 2; MatrixType = Eigen::SparseMatrix<double>; int DestOrder = 0]’:
/home/tdegeus/opt/include/eigen3/Eigen/src/SparseCore/SparseSelfAdjointView.h:517:6: internal compiler error: in predicate_mem_writes, at tree-if-conv.c:2252
void permute_symm_to_symm(const MatrixType& mat, SparseMatrix<typename MatrixType::Scalar,DstOrder,typename MatrixType::StorageIndex>& _dest, const typename MatrixType::StorageIndex* perm)
^~~~~~~~~~~~~~~~~~~~
0xb3530b predicate_mem_writes
/ssoft/spack/paien/spack.v2/var/spack/stage/gcc-7.3.0-drb5cfgzldhzbrs6lyzk7xdqqcixbxhb/gcc-7.3.0/gcc/tree-if-conv.c:2252
0xb3530b combine_blocks
/ssoft/spack/paien/spack.v2/var/spack/stage/gcc-7.3.0-drb5cfgzldhzbrs6lyzk7xdqqcixbxhb/gcc-7.3.0/gcc/tree-if-conv.c:2377
0xb359bb tree_if_conversion(loop*)
/ssoft/spack/paien/spack.v2/var/spack/stage/gcc-7.3.0-drb5cfgzldhzbrs6lyzk7xdqqcixbxhb/gcc-7.3.0/gcc/tree-if-conv.c:2883
0xb3663b execute
/ssoft/spack/paien/spack.v2/var/spack/stage/gcc-7.3.0-drb5cfgzldhzbrs6lyzk7xdqqcixbxhb/gcc-7.3.0/gcc/tree-if-conv.c:2961
Please submit a full bug report,
with preprocessed source if appropriate.
Please include the complete backtrace with any bug report.
See <https://gcc.gnu.org/bugs/> for instructions.
Which disappears if I comment this line (obviously breaking functionality):
m_solver.compute(m_ACuu);
Note that:
Eigen::SparseMatrix<double> m_ACuu;
Eigen::SimplicialLDLT<Eigen::SparseMatrix<double>> m_solver;
I tried a minimal example:
#include <iostream>
#include <iomanip>
#include <math.h>
#include <vector>
#include <Eigen/Dense>
#include <Eigen/Sparse>
#include <Eigen/SparseCholesky>
int main()
{
size_t N = 11;
// allocate system
Eigen::SparseMatrix<double> A(N,N);
Eigen::VectorXd f(N);
// set force
f *= 0.0;
f((N-1)/2) = 1.0;
// construct list of Triplets (row,col,data) that from the matrix "A"
std::vector<Eigen::Triplet<double>> Atr;
// - first equation
Atr.push_back(Eigen::Triplet<double>(0,0,+2.0));
Atr.push_back(Eigen::Triplet<double>(0,1,-1.0));
// - body
for ( size_t i=1; i<N-1; ++i ) {
Atr.push_back(Eigen::Triplet<double>(i,i-1,-1.0));
Atr.push_back(Eigen::Triplet<double>(i,i ,+2.0));
Atr.push_back(Eigen::Triplet<double>(i,i+1,-1.0));
}
// - last equation
Atr.push_back(Eigen::Triplet<double>(N-1,N-2,-1.0));
Atr.push_back(Eigen::Triplet<double>(N-1,N-1,+2.0));
// build matrix from Triplets
A.setFromTriplets(Atr.begin(),Atr.end());
// solve the linear system
// - define solver (according to type above)
Eigen::SimplicialLDLT<Eigen::SparseMatrix<double>> solver;
// - analyze the system, and factorize (one could solve different right-hand-sides)
// solver.analyzePattern(A);
solver.factorize(A);
// - solve "A * x = f"
Eigen::VectorXd u = solver.solve(f);
// print to screen
std::cout << A << std::endl;
std::cout << u << std::endl;
return 0;
}
Compiled on the same system with the same libraries and with similar options:
g++ -march=native -O3 test.cpp
But this compiles and runs like a charm!?
Note that I've tried several Eigen versions, including 3.3.90.
Edit
Also note that this problem occurs with
g++ --version
g++ (GCC) 7.3.0
But is gone for
g++ (GCC) 6.4.0

Related

Error with Lambda Expression C++ in VS Code

I'm trying to sort an array m of class measure using a lambda expression as follows:
#include <iostream>
#include <vector>
#include <string>
#include <algorithm>
#include <math.h>
using namespace std;
struct measure{
int day;
int cow;
int change;
};
int main()
{
int N;
cin >> N;
measure m[N];
for (int i = 0; i < N; i++){
measure m_i;
cin >> m_i.day >> m_i.cow >> m_i.change;
m[i] = m_i;
}
sort(m, m + N, [](measure a, measure b) {return a.day < b.day;});
}
However, an error occurs when trying to build the task in VS Code (using C++17):
error: expected expression
sort(m, m + N, [](measure a, measure b) {return a.day < b.day;});
^
1 error generated.
Build finished with error(s).
I've tested this code on other compilers with no difficulties. Why is this error happening on VS Code?
Okay, so it does not look like you are compiling with c++17. I can reproduce this error if I roll back the gcc version to 4.x and leave the standard up to the compiler. Here is how it would look on an older compiler. Here is how it would run properly on a newer compiler. Most likely that you are using something like c++98 or c++03.
Note - I have taken the liberty of modifying your code to make it more C++. Also, please stop with using namespace std.
A simple fix is to just make sure that you are using the right version of the compiler basis the features you need. Lambdas in C++ were introduced in C++11, so clearly you are using a compiler that is at a much lower version.
VS Code does not have a compiler built-in. It uses the system compiler you have installed. You can configure things to use the system compiler and pass the flag --std=c++17 to the compiler command line.
Both gcc and clang++ support this command line flag.

How to compile generator and coroutine using c++2a on Mac

I am setting up my MacBook for C++20 and having problem to compile the code. I have installed latest Xcode, llvm and gcc. Here is the code that I am trying to compile
#include <chrono>
#include <experimental/coroutine>
#include <future>
#include <iostream>
using namespace std;
generator<int> getInts(int first, int last) {
for (auto i = first; i <= last; ++i) {
co_yield i;
}
}
int main() {
for (auto i : getInts(5, 10)) {
std::cout << i << " ";
}
}
however I am getting following error:
$ g++ gen.cpp -std=c++2a
In file included from gen.cpp:2:
/Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/include/c++/v1/experimental/coroutine:66:5: warning:
<experimental/coroutine> cannot be used with this compiler [-W#warnings]
# warning <experimental/coroutine> cannot be used with this compiler
^
appreciate any insight how to resolve this compile issue.
The Coroutines TS has not been voted into C++20 (indeed, there have been three separate votes, with approval not achieving consensus in all of them), so even if GCC implemented it (which it doesn't), it wouldn't be activated by the -std=c++2a switch.
Now, Clang does implement the Coroutines TS, which you have to turn on with -fcoroutines-ts. And apparently, you have to be using libc++.

include LAPACK on c++ code

I am trying to execute following simple c++ code in Qt environment on my mac. What I want with this code is to use libraries of LAPACK for simple mathematical operations. I just considered "dot product " function to test this case and got
"Symbols not found for architecture x86_64" and
"linker command failed with exit code 1 (use -v to see invocation) errors.
By the way, I am quite sure that i am repeating file or header file names that might cause these same errors.
Anyone knows how to overcome this ? Thanks in advance.
#include <iostream>
#include <vector>
#include <Accelerate/Accelerate.h>
extern "C"
{
double ddot_ (const int*, const double*, const int*, const double*, const int*);
}
int main()
{
std::vector<double> values(2, 1.);
int N = 2;
int one = 1;
double norm = ddot_(&N, &values[0], &one, &values[0], &one);
std::cout << "Hello world " <<norm << std::endl;
return 0;
}
The function ddot_() is part of the Blas library. It is not a part of the Lapack library. Hence, the program using ddot_() should be linked to the Blas library. For instance, the c++ program you posted can be compiled by:
g++ main.cpp -o main -lblas
provided #include <Accelerate/Accelerate.h> is commented.

Most basic parallelization with C++11 theads fail

I try to use C++11 theading library using g++ 4.7.
First I have a question: is it expected for a next release to not be required to link by hand the pthread library ?
So my program is :
#include <iostream>
#include <vector>
#include <thread>
void f(int i) {
std::cout<<"Hello world from : "<<i<<std::endl;
}
int main() {
const int n = 4;
std::vector<std::thread> t;
for (int i = 0; i < n; ++i) {
t.push_back(std::thread(f, i));
}
for (int i = 0; i < n; ++i) {
t[i].join();
}
return 0;
}
I compile with:
g++-4.7 -Wall -Wextra -Winline -std=c++0x -pthread -O3 helloworld.cpp -o helloworld
And it returns:
Hello world from : Hello world from : Hello world from : 32
2
pure virtual method called
terminate called without an active exception
Erreur de segmentation (core dumped)
What is the problem and how to solve it ?
UPDATE:
Now using mutex:
#include <iostream>
#include <vector>
#include <thread>
#include <mutex>
static std::mutex m;
void f(int i) {
m.lock();
std::cout<<"Hello world from : "<<i<<std::endl;
m.unlock();
}
int main() {
const int n = 4;
std::vector<std::thread> t;
for (int i = 0; i < n; ++i) {
t.push_back(std::thread(f, i));
}
for (int i = 0; i < n; ++i) {
t[i].join();
}
return 0;
}
It returns :
pure virtual method called
Hello world from : 2
terminate called without an active exception
Abandon (core dumped)
UPDATE 2:
Hum... It works with my default GCC (g++4.6) but it fails with the version of gcc I compiled by hand (g++4.7.1). Was there an option I forgot to compile g++ 4.7.1 ?
General edit:
In order to prevent use of cout by multiple threads simultaneously, that will result in character interleaving, proceed as follows:
1) declare before the declaration of f():
static std::mutex m;
2) then, guard the "cout" line between:
m.lock();
std::cout<<"Hello world from : "<<i<<std::endl;
m.unlock();
Apparently, linking against the -lpthread library is a must, for some unclear reasons. At least on my machine, not linking against -lpthread results in a core dump. Adding -lpthread results in proper functionality of the program.
The possibility of character interleaving if locking is not used when accessing cout from different threads is expressed here:
https://stackoverflow.com/a/6374525/1284631
more exactly: "[ Note: Users must still synchronize concurrent use of these objects and streams by multiple threads if they wish to avoid interleaved characters. — end note ]"
OTOH, the race condition is guaranteed to be avoided, at least in the C++11 standard (beware, the gcc/g++ implementation of this standard is still at experimental level).
Note that the Microsoft implementation (see: http://msdn.microsoft.com/en-us/library/c9ceah3b.aspx credit to #SChepurin) is stricter than the standard (apparently, it guarantees character interleaving is avoided), but this might not be the case for the gcc/g++ implementation.
This is the command line that I use to compile (both updated and original code versions, everything works well on my PC):
g++ threadtest.cpp -std=gnu++11 -lpthread -O3
OTOH, without the -lpthread, it compiles but I have a core dump (gcc 4.7.2 on Linux 64).
I understand that you are using two different versions of the gcc/g++ compiler on the same machine. Just be sure that you use them properly (not mixing different library versions).

unordered_map error in GCC

When was the unordered_map concept built into g++?
Because the following code throws an error.
#include<iostream>
#include<unordered_map>
#include<stdio.h>
using namespace std;
std::unordered_map<std::int,int> mirror;
mirror['A'] = 'A';
mirror['B'] = '#';
mirror['E'] = 3;
int main(void)
{
std::cout<<mirror['A'];
std::cout<<mirror['B'];
std::cout<<mirror['C'];
return 0;
}
I am compiling the code as follows:
g++ -c hashexample.cpp
g++ -o result hashExample.o
./result
The error I got is this:
inavalid types int[char[ for aaray subscript
What is the fix for this?
The problem is your assignment. You cannot assign values to your map in this place. C++ is not a script language.
This program works fine on my machine with gcc4.6:
#include<iostream>
#include<unordered_map>
std::unordered_map<int,int> mirror;
int main() {
mirror['A'] = 'A';
mirror['B'] = '#';
mirror['E'] = 3;
std::cout<<mirror['A'];
std::cout<<mirror['B'];
std::cout<<mirror['C'];
}
First, as mkaes points out, you cannot put assignments outside functions, so you have to put it in any, for example main.
As for unordered_map, for recent versions of gcc, if you don't want to go into C++11, you can use the TR1 version of unordered_map:
#include <tr1/unordered_map>
and the type std::tr1::unordered_map. You know, C++11 supersedes all this, but you will (at least in GCC) get this working.