Error while compiling with clang/clang++ [-Werror,-Wrange-loop-constrcut] - c++

I'm trying to build a c++ project. While doing so with g++ the project compiles fine. However if I try to compile with clang I get the error:
ec_read_plan.h:135:19: error: loop variable 'op' creates a copy from type 'const std::pair<ChunkPartType, ReadPlan::ReadOperation>' [-Werror,-Wrange-loop-construct]
for (const auto op : read_operationss_{
ec_read_plan.h:135:8: note: use reference type 'const std:pair<ChunkPartType, ReadPlan::ReadOperation> &' to prevent copying
for (const auto op : read_operations) {
Code is below, I have put a comment next on the line that is giving the error:
protected:
void recoverParts(uint8_t *buffer,
const std::bitset<Goal::Slice::kMaxPartsCount> &available_parts) const {
typedef ReedSolomon<slice_traits::ec::kMaxDataCount, slice_traits::ec::kMaxParityCount> RS;
int k = slice_traits::ec::getNumberOfDataParts(slice_type);
int m = slice_traits::ec::getNumberOfParityParts(slice_type);
int max_parts = k + m;
RS::ConstFragmentMap data_parts{{0}};
RS::FragmentMap result_parts{{0}};
RS::ErasedMap erased;
RS rs(k, m);
int available_count = 0;
for (int i = 0; i < max_parts; ++i) {
if (!available_parts[i] || available_count >= k) {
erased.set(i);
} else {
available_count++;
}
}
for (const auto op : read_operations) { //ERROR appears to be here
data_parts[op.first.getSlicePart()] = buffer + op.second.buffer_offset;
}
for (int i = 0; i < (int)requested_parts.size(); ++i) {
if (!available_parts[requested_parts[i].part]) {
result_parts[requested_parts[i].part] = buffer + i * buffer_part_size;
}
}
rs.recover(data_parts, erased, result_parts, buffer_part_size);
}
Why am I getting such an error with Clang and how can I fix this? Thank you.
For anyone who may want to reproduce the error, the source code is here: https://github.com/lizardfs/lizardfs. Afterwards do:
export CC=/usr/bin/clang
export CC=/usr/bin/clang++
cd lizardfs
mkdir build
cd build
cmake .. -DCMAKE_BUILD_TYPE=Release -DCMAKE_INSTALL_PREFIX=/opt/lizardfs
make

It turns out the error has to do with the clang and clang++ versions. As mentioned gcc had no problems compiling. By default my machine uses clang/clang++ version 10. I tried using version 11 but also had the same problem. I therefore installed version 9 of clang/clang++ and tried compiling again and it worked.
If you happen to have the same problems make sure to run the following commands or have them in the ~/.bashrc file and run source ~/.bashrc after installing version 9 of clang/clang++
export CC=/usr/bin/clang-9
export CC=/usr/bin/clang++-9

Related

julia Cxx package different behavior when in module

I'm using Julia 1.1.1, and version 0.3.2 of Cxx. I'm finding that I'm getting an error when I call icxx"" from within a module I've defined, but not when I'm calling it in the REPL. In the REPL I have:
using Cxx
function xformVectors()
cxx"""
#include <iostream>
#include <vector>
class Summer {
public:
Summer() {}
std::vector<int> compute_sum(const std::vector<std::vector<int>> &input) {
std::vector<int> result(input.size(), 0);
for (std::size_t i = 0; i != input.size(); ++i) {
for (std::size_t j = 0; j != input[i].size(); ++j) {
result[i] += input[i][j];
}
}
return result;
}
};
"""
as = [rand(1:10,5), rand(1:10,6)]
x = convert(cxxt"std::vector< std::vector< int > >", as)
summer = #cxxnew Summer()
cxx_v = icxx"$summer->compute_sum($x);"
for v in cxx_v
println(collect(v))
end
end
If I then call xformVectors(), it writes out a couple of integers and exits (the expected behavior). If I use Pkg.generate() to wrap this code in a module, and then call xformVectors(), I get a fatal error:
ERROR: BoundsError: attempt to access 36-element Array{Tuple{AbstractString,Symbol,Int64,Int64,Bool},1} at index [37]
Stacktrace:
[1] getindex(::Array{Tuple{AbstractString,Symbol,Int64,Int64,Bool},1}, ::Int64) at ./array.jl:729
[2] #s37#70 at /home/jov9025/.julia/packages/Cxx/vxYtJ/src/cxxstr.jl:705 [inlined]
[3] #s37#70(::Any, ::Any, ::Any, ::Any) at ./none:0
[4] (::Core.GeneratedFunctionStub)(::Any, ::Vararg{Any,N} where N) at ./boot.jl:522
[5] xformVectors() at /home/jov9025/sandbox/julia/Vector2Vector.jl/src/Vector2Vector.jl:30
[6] top-level scope at none:0
If, in the REPL, I include the source file (include("src/Vector2Vector.jl") and then call Vector2Vector.xformVectors(), it runs without complaint.
Any idea what's going on?
The line in my code where the error originated was:
cxx_v = icxx"$summer->compute_sum($x);"
I still don't understand what the problem was with icxx"", but I don't actually need to use it in this sample (or in my real code). I can just use the #cxx macro, and voila, no crash:
cxx_v = #cxx compute_sum(x)
So, I may have been asking the wrong question (although I think it's an interesting one).
Revisiting this in January 2020: with version 0.3.3 of Cxx, the code executes fine with the original icxx"" line in the REPL.

Undefined reference when building R package using Rcpp with an external C++ library

I'm trying to create a R package for my own use, that is using Rcpp and whose C++ code include the Levmar library. I'm working on Windows.
The C++ code works fine when I build it using CMake for example and run it with Visual Studio. But when I put this code in my R package and try to build it, I get the following error :
levmar_example_r.o:levmar_example_r.cpp:(.text+0x281): undefined reference to `dlevmar_der'
(dlevmar_der is declared in levmar.h which is included in my R package, see below)
I have already read quite a lot of SO posts on how to build a R package with external libraries like this or this but it didn't help me to solve my problem.
The structure of my package :
bin/
|- levmar.lib
inst/
|- include/
|- levmar.h
man/
R/
src/
|- Makevars
|- Makevars.win
|- levmar_example_r.cpp
|- RcppExports.cpp
src-i386/
DESCRIPTION
NAMESPACE
Content of Makevars/Makevars.win
PKG_LIBS = -L../bin -llevmar
PKG_CPPFLAGS = -I../inst/include
The C++ code (levmar_example_r.cpp)
#include <iostream>
#include <levmar.h>
#include <math.h>
#include <Rcpp.h>
void fun(double *p, double *x, int m, int n, void *data_){
double a = p[0];
double b = p[1];
double *data = (double *) data_;
for(int i = 0; i < n; i++){
x[i] = log(a*data[i]+b);
}
}
void jacFun(double *p, double *jac, int m, int n, void *data_){
double a = p[0];
double b = p[1];
double *data = (double *) data_;
int k, l;
for(l=k=0; l < n; l++){
jac[k++] = data[l]/(a*data[l]+b);
jac[k++] = 1/(a*data[l]+b);
}
}
// [[Rcpp::export]]
void test_levmar(){
int m = 2; // # of parameters
int n = 40; // # of observations
double a = 1.0;
double b = 2.0;
double data[] = {0.119047619047619, 0.238095238095238, 0.357142857142857, 0.476190476190476, 0.595238095238095, 0.714285714285714, 1.07142857142857, 1.42857142857143,
0.119047619047619 ,0.238095238095238, 0.357142857142857, 0.476190476190476, 0.595238095238095, 0.714285714285714 ,1.07142857142857, 1.42857142857143 ,
0.119047619047619, 0.238095238095238, 0.357142857142857, 0.476190476190476, 0.595238095238095, 0.714285714285714, 1.07142857142857, 1.42857142857143,
0.119047619047619, 0.238095238095238, 0.357142857142857, 0.476190476190476 ,0.595238095238095, 0.714285714285714, 1.07142857142857, 1.42857142857143,
0.119047619047619, 0.238095238095238 ,0.357142857142857, 0.476190476190476, 0.595238095238095, 0.714285714285714, 1.07142857142857, 1.42857142857143};
double popti[2];
popti[0] = a; popti[1] = b;
double x[40];
fun(popti, x, m, n, (void *) data);
// algorithm parameters
double opts[LM_OPTS_SZ], info[LM_INFO_SZ];
opts[0]=LM_INIT_MU;
// stopping thresholds for
opts[1]=1E-10; // ||J^T e||_inf
opts[2]=1E-10; // ||Dp||_2
opts[3]=1E-10; // ||e||_2
opts[4]= LM_DIFF_DELTA; // finite difference if used
double p[2];
p[0] = 3.0; p[1] = 1.0;
dlevmar_der(fun,jacFun,p,x,m,n,100,opts,info,NULL,NULL,(void *) data);
std::cout << "Optimum found:" << std::scientific << std::setprecision(8)<< "\t"<< p[0]<< "\t" << p[1]<< std::endl;
}
I have also tried to put all headers of the levmar library in the inst/include folder and all the .c files in a src/levmar folder and consequently remove
PKG_LIBS = -L../bin -llevmar
in Makevars/Makevars.win and add
-I src/levmar
to the PKG_CPPFLAGS but it didn't work out either.
Do you have any idea on what I should do ?
Don't hesitate to ask for precisions if I wasn't clear enough
SODD got the better of me. I have build a very rough package that compiles the levmar code and creates an initial R package from it: https://github.com/rstub/levmaR. Important points:
Source files in sub-directories of src are not automatically compiled. One has to add them somehow, e.g.
CXX_STD = CXX11
PKG_LIBS=-L. -llevmar $(LAPACK_LIBS) $(BLAS_LIBS) $(FLIBS)
PKG_CPPFLAGS=-I./levmar/ -DSTRICT_R_HEADERS
all: $(SHLIB)
$(SHLIB): liblevmar.a
LIBOBJS = levmar/lm.o levmar/Axb.o levmar/misc.o levmar/lmlec.o levmar/lmbc.o \
levmar/lmblec.o levmar/lmbleic.o
liblevmar.a: $(LIBOBJS)
$(AR) rcs liblevmar.a $(LIBOBJS)
By default levmar tries to build single- and double-precision functions and tries to use LAPACK. Default builds of R only include double-precision LAPACK and BLAS. I disabled the single precision build.
The levmar library is actually pure C. So my suspicion that your problems where caused by the different C++ ABIs between VC and gcc is probably not correct. Most likely there is some other incompatibility between VC and gcc concerning the layout of static libraries.
Right now the only available function is your test_levmar(). Tested on Linux and Windows (via Appveyor and rhub).

Internal compile error c++ cilk plus

[Fixed]- Explanation given in comments
[Updated with error screenshot]
I am getting a compilation error when compiled using gcc/5.4.0. Following is the error reported:
internal compiler error: in lower_stmt, at gimple-low.c:397
cilk_spawn m_sparsify_graph_helper__(mdl, n_pa, n_ch, score2beat);
Following is the code snippet that causes error:
void m_sparsify_graph_helper__(MDL mdl, set_type pa, set_type ch, std::vector<double> score2beat) {
//cilk::reducer<cilk::op_list_append<RNode_>> rlist;
//"rlist" - defined in the class as a private variable
if (ch == 0) { return; }
set_type n_ch = ch;
// Some more code -- which I am very sure is not causing error
int lsb = n_ - 1;
for (; lsb >= 0; --lsb) { if (in_set(pa, lsb)) { break; } }
if (lsb == n_ - 1) { return; }
set_type n_pa = set_add(pa, lsb + 1);
int n_pa_sz = set_size(n_pa);
if (n_pa_sz >= n_) { return; }
BitCombination comb(n_pa, n_pa_sz, n_);
for (;;) {
n_pa = comb.data();
// If cilk_spawn keyword removed it compiles fine.
cilk_spawn m_sparsify_graph_helper__(mdl, n_pa, n_ch, score2beat);
if (!comb.next() || in_set(n_pa, n_ - 1)) { break; }
}
}// m_sparsify_graph_helper__
I assume it's a compiler error but I would like to know what is the way to circumvent this error and get the code executed warning and error free.
Error screenshot:
It seems the reported errors was ironed out in the GCC 6.X release.
FYI, if you are facing similar issue try to reproduce the error on the latest release of GCC just to confirm whether it was earlier reported and rectified or not.

c++ find command no longer works

This is some old code not written by me. It compiles with GCC 3.4.6, but now we are checking the build with GCC 4.4.7 and the build fails.
I hope this code is enough to go on:
list<Chapter*> * tocP; //Chapter is a class
tocP = NULL;
if (_searchChapter)
{
_chapter = _manager->GetCurrentChapter(); // _chapter is a Chapter*
}
else
{
tocP = _manager->GetTableOfContents();
if (tocP != NULL && tocP->size() > 0)
_chapter = tocP->front();
}
...
list<Chapter*>::iterator chp;
if (tocP != NULL && tocP->size() > 0)
for (chp=find(tocP->begin(),tocP->end(),_chapter); chp != tocP->end(); ++chp) // this code fails
{
//code to process chapter
}
error message is:
../src/HelpSearchC.C: In member function 'int HelpSearchC_i::DoSearch()':
../src/HelpSearchC.C:685: error: no matching function for call to 'find(std::_List_iterator<Chapter*>,
std::_List_iterator<Chapter*>, Chapter*&)'
You have to add #include <algorithm> on top of the file. The function find is defined within this header.

Can return keyword be omitted in a return statement?

I recently come across the below piece of code in this Apache Axis tutorial example.
int main()
{
int status = AXIS2_SUCCESS;
axutil_env_t *env = NULL;
axutil_allocator_t *allocator = NULL;
env = create_environment();
status = build_and_serialize_om(env);
(status == AXIS2_FAILURE)
{
printf(" build AXIOM failed");
}
axutil_env_free(env);
0;
}
What i don't understand is the 0; at the end.
Is that return statement without the return keyword?
I tried the below piece of code to test this in Visual Studio.
int main()
{
0; // in the second run, replaced 0 with 28
}
Both programmes ran without any problems. But echo %ERRORLEVEL% at
windows command line returned 0 for both.
But the below piece of code
int add()
{
0;
}
causes
Error 1 error C4716: 'add' : must return a value
I understand that return value 0 is implicitly added for the main().
I don't have a problem including the return keyword at all, but I am
porting the Axis2/C Library to a C++ project. And there are many instances
where I encountered 0;
Why is the above syntax causing this undefined behavior?
In C++ return can be omitted only in main() , in functions that return void, and in constructors and destructors. In the former case main() returns automatically 0. In your case the statement 0; is a syntactically correct statement, evaluated as a no-op, so the compiler is basically ignoring it.
Where did you find that code? It seems like it's corrupted, perhaps due to formatting for showing it on a web page or something...?
The original code (from https://github.com/bnoordhuis/axis2-c/blob/master/axiom/test/util/axiom_util_test.c) is:
int main()
{
int status = AXIS2_SUCCESS;
axutil_env_t *env = NULL;
status = build_and_serialize_om(env);
if(status == AXIS2_FAILURE)
{
printf(" build AXIOM failed");
}
axutil_env_free(env);
return 0;
}