I'm having trouble using the C99 complex data type with FFTW and C++14.
// fftw14.cc
#include <complex.h>
#include <fftw3.h>
int main() {
fftw_complex* in;
in = (fftw_complex*) fftw_malloc(sizeof(fftw_complex) * 100);
in[0] = 1337.42;
return 0;
}
There is no problem when I compile it with g++ fftw14.cc -lfftw3 -lm. However, using C++14 (g++ -std=c++14 fftw14.cc -lfftw3 -lm), fftw_complex gets double[2] and hence the implicit typecast fails.
fftw14.cc: In function ‘int main()’:
fftw14.cc:11:8: error: incompatible types in assignment of ‘double’ to ‘fftw_complex {aka double [2]}’
in[0] = 1337.42;
^
Why is that? I know I could mess around with the std::complex<double> type, but I would like to avoid that.
Related
A simple program throws a weird warning , the program tries to use vector of intel intrinsics. i am using g++ 7.2 , there is a bug in gcc which is resolved to be fixed but the warning still persists, i am not sure what are the implications to ignore the warning as intel intrinsics need strictly aligned data.
avx.cpp: In function ‘int main()’:
avx.cpp:7:27: warning: ignoring attributes on template argument ‘__m256i* {aka __vector(4) long long int*}’ [-Wignored-attributes]
std::vector< __m256i* > v;
^
#include <vector>
#include <immintrin.h>
#include <iostream>
int main()
{
std::vector< __m256i* > v;
return 0;
}
I'm trying to compile the examples found here:
http://www.netlib.org/lapack/lapacke.html#_examples
Specifically, I'm trying to get the "Calling CGEQRF and the CBLAS" example to work. The code is like so:
#include <stdio.h>
#include <stdlib.h>
#include <lapacke.h>
#include <cblas.h>
int main (int argc, const char * argv[])
{
lapack_complex_float *a,*tau,*r,one,zero;
lapack_int info,m,n,lda;
int i,j;
float err=0.0;
m = 10; n = 5; lda = m;
one = lapack_make_complex_float(1.0,0.0);
zero= lapack_make_complex_float(0.0,0.0);
a = calloc(m*n,sizeof(lapack_complex_float));
r = calloc(n*n,sizeof(lapack_complex_float));
tau = calloc(m,sizeof(lapack_complex_float));
for(j=0;j<n;j++)
for(i=0;i<m;i++)
a[i+j*m] = lapack_make_complex_float(i+1,j+1);
info = LAPACKE_cgeqrf(LAPACK_COL_MAJOR,m,n,a,lda,tau);
info = LAPACKE_cungqr(LAPACK_COL_MAJOR,m,n,n,a,lda,tau);
for(j=0;j<n;j++)
for(i=0;i<n;i++)
r[i+j*n]=(i==j)?-one:zero;
cblas_cgemm(CblasColMajor,CblasConjTrans,CblasNoTrans,
n,n,m,&one,a,lda,a,lda,&one,r,n );
for(i=0;i<n;i++)
for(j=0;j<n;j++)
err=MAX(err,cabs(r[i+j*n]));
printf("error=%e\n",err);
free(tau);
free(r);
free(a);
return(info);
}
If I save the file as a .cpp (perhaps this is my first mistake?) and compile using
g++ lapacketest.cpp -llapack
I get the following compile errors:
3_20_2.cpp:14:7: error: assigning to '_Complex float *' from incompatible type 'void *'
a = calloc(m*n,sizeof(lapack_complex_float));
^ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
3_20_2.cpp:15:7: error: assigning to '_Complex float *' from incompatible type 'void *'
r = calloc(n*n,sizeof(lapack_complex_float));
^ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
3_20_2.cpp:16:9: error: assigning to '_Complex float *' from incompatible type 'void *'
tau = calloc(m,sizeof(lapack_complex_float));
^ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
3_20_2.cpp:29:25: error: use of undeclared identifier 'cabs'
err=MAX(err,cabs(r[i+j*n]));
I tried changing to .c and compiling with gcc, but I got other strange errors. Any thoughts? I'm slowly trying transition from Matlab to c++ for scientific computing and so far it's just been a giant headache.
It looks like calloc(m*n,sizeof(lapack_complex_float)); is not returning a pointer to an object of type lapack_complex_float.
I could compile it but you have to change the line
#include <lapacke.h>
to
#include <lapacke_utils.h>
You find at http://www.netlib.org/lapack/explore-html/da/d8e/lapacke__utils_8h_source.html. After you download it and put in the same directory of your program or use the tags -L -I to locate the library on your system during the compilation.
To compile use:
gcc CGEQRF_CUNGQR.c -llapacke -lblas -lm
When I compile the code below with g++ 4.8.1 (64bit) in this way:
$ g++ -Wconversion -o main main.cpp
I get this result:
main.cpp: In function ‘int main()’:
main.cpp:12:20: warning: conversion to ‘int’ from ‘long unsigned int’ may alter its value [-Wconversion]
int i = sizeof(x)/sizeof(x[0]);
^
My expectation would be that the compiler should be able to evaluate the expression at compile time. If you make a similar program in plain c, gcc works like a charm.
Should this be considered a bug in g++ (e.g. clang++ does not have this problem)?
if you change the problematic line to something like:
char c = 0x10000000/0x1000000;
then the compiler does not complain. This suggest that some constant evaluation is done before warning generation.
main.cpp:
#include <iostream>
struct foo {
int a;
int b;
};
foo x[50];
int main()
{
int i = sizeof(x)/sizeof(x[0]);
std::cout << i << std::endl;
return 0;
}
int i = sizeof(x)/sizeof(x[0]);
//int <-- std::size_t <-- std::size_t / std::size_t
The type of the expression sizeof(x)/sizeof(x[0]) is std::size_t which on your machine is unsigned long int. So conversion from this type to int is data-loss, if the source is bigger in size than the target.
Though, I agree that in your case, there would not be actual data-loss if the compiler actually computes the value, but I guess it applies -Wconversion before the actual computation.
sizeof() returns you std::size_t not int! So cast it or declare i as std::size_t.
std::size_t i = sizeof(x)/sizeof(x[0]);
To get precision and scale of a number i am using this simple program. But while converting number into string it is giving compilation error.
g++ precision.cpp
precision.cpp: In function ‘int main()’:
precision.cpp:6: error: ‘to_string’ was not declared in this scope
When I compile with the -std=c++0x switch I get
g++ precision.cpp -std=c++0x
precision.cpp: In function ‘int main()’:
precision.cpp:6: error: call of overloaded ‘to_string(int)’ is ambiguous
/usr/lib/gcc/i686-redhat-linux/4.4.4/../../../../include/c++/4.4.4/bits/basic_string.h:2604: note: candidates are: std::string std::to_string(long long int)
/usr/lib/gcc/i686-redhat-linux/4.4.4/../../../../include/c++/4.4.4/bits/basic_string.h:2610: note: std::string std::to_string(long long unsigned int)
/usr/lib/gcc/i686-redhat-linux/4.4.4/../../../../include/c++/4.4.4/bits/basic_string.h:2616: note: std::string std::to_string(long double)
The source code looks like this:
#include <iostream>
#include <string>
using namespace std;
int main()
{
string value = to_string(static_cast<int>(1234));
int precision = value.length();
int scale = value.length()-value.find('.')-1;
cout << precision << " " << scale;
return 0;
}
What is causing this error?
The first error is because std::to_string is a C++11 feature, and GCC by default compiles in C++03 mode.
The second error, when you are using the correct flag, is probably because the support for C++11 in GCC 4.4 (which you seem to be using) is quite minimal. As you can see by the error messages, the compiler shows you the alternatives it have.
By the way, you don't need to cast integer literals to int, they are of type int by default. You might want to cast it to long double though, as that's one of the valid overloads and you seems to want to find the decimal point (the code will not work as expected if there is no decimal point in the string, like when converting an integer).
I recommend to use boost::lexical_cast instead.
I'm new to c++, and I've started a project for my internship where I have use to the Snap library from stanford (http://snap.stanford.edu/). So I have downloaded the library and I am now trying to create my own little programm using it. Sadly i can't seem to be able to compile it :(
Here are the sources :
Makefile :
CXXFLAGS += -std=c++98 -Wall
LDFLAGS += -lrt
Snap.o :
g++ -c $(CXXFLAGS) ../snap/snap/Snap.cpp -I../snap/glib -I../snap/snap -pg
simulation.o : simulation.cpp simulation.h
g++ -g -c $(CXXFLAGS) simulation.cpp
test.o : test.cpp
g++ -g -c $(CXXFLAGS) test.cpp
test : test.o Snap.o simulation.o
g++ -g $(LDFLAGS) test.o Snap.o simulation.o -I../snap/glib -I../snap/snap -lm -o test
simulation.h
#ifndef SIMULATION
#define SIMULATION
#include <vector>
#include "../snap/snap/Snap.h"
class Simulation{
public:
Simulation():score(-1),nNodes(-1),nEdges(-1), dMax(-1){};
Simulation(int nN, int nE, int d);
Simulation(int d, PUNGraph g);
void setDMax(int d){ dMax = d; }
double getScore(){ return score; }
int getNNodes(){ return nNodes; }
int getNEdges(){ return nEdges; }
int getDMax(){ return dMax; }
PUNGraph getGraph(){ return graph; }
std::vector<int> getAlignment(){ return alignment; }
double computeEnergy();
private:
double score;
int nNodes;
int nEdges;
int dMax;
PUNGraph graph;
std::vector<int> alignment;
};
#endif
simulation.cpp
#include "simulation.h"
#include <stdlib.h>
#include <stdio.h>
#include <vector>
#include <algorithm>
#include "../snap/snap/Snap.h"
Simulation::Simulation(int nN, int nE, int d){
nNodes = nNodes;
nEdges = nEdges;
dMax = dMax;
graph = TSnap::GenRdnGnm<PUNGraph>(nNodes,nEdges);
for(int i=1; i<=nNodes; i++){
alignment.push_back(i);
}
random_shuffle(alignment.begin(),alignment.begin()+nNodes);
computeEnergy();
}
Simulation::Simulation(int d, PUNGraph g){
nNodes = graph->GetNodes();
nEdges = graph->GetEdges();
dMax = d;
graph = g;
for(int i=1; i<=nNodes; i++){
alignment.push_back(i);
}
random_shuffle(alignment.begin(),alignment.begin()+nNodes);
computeEnergy();
}
double computeEnergy(){
return 0.0;
}
test.cpp
#include<stdlib.h>
#include<stdio.h>
#include<vector>
#include<algorithm>
#include "simulation.h"
#include "../snap/snap/Snap.h"
int main(int argc, char** argv){
Simulation sim(5000,30000,30);
}
I don't think my compilation problems come from Snap itself and it might very well be only from my poor knowledge of c++ and how the includes an so on are working.
Here is what I get after running make :
g++ -g -c -std=c++98 -Wall simulation.cpp
In file included from /usr/include/c++/4.5/bits/stl_algo.h:61:0,
from /usr/include/c++/4.5/algorithm:63,
from simulation.cpp:5:
/usr/include/c++/4.5/bits/algorithmfwd.h:347:41: error: macro "max" passed 3 arguments, but takes just 2
/usr/include/c++/4.5/bits/algorithmfwd.h:358:41: error: macro "min" passed 3 arguments, but takes just 2
/usr/include/c++/4.5/bits/algorithmfwd.h:343:5: error: expected unqualified-id before ‘const’
/usr/include/c++/4.5/bits/algorithmfwd.h:343:5: error: expected ‘)’ before ‘const’
/usr/include/c++/4.5/bits/algorithmfwd.h:343:5: error: expected ‘)’ before ‘const’
/usr/include/c++/4.5/bits/algorithmfwd.h:343:5: error: expected initializer before ‘const’
/usr/include/c++/4.5/bits/algorithmfwd.h:347:5: error: template declaration of ‘const _Tp& std::max’
/usr/include/c++/4.5/bits/algorithmfwd.h:354:5: error: expected unqualified-id before ‘const’
/usr/include/c++/4.5/bits/algorithmfwd.h:354:5: error: expected ‘)’ before ‘const’
/usr/include/c++/4.5/bits/algorithmfwd.h:354:5: error: expected ‘)’ before ‘const’
/usr/include/c++/4.5/bits/algorithmfwd.h:354:5: error: expected initializer before ‘const’
/usr/include/c++/4.5/bits/algorithmfwd.h:358:5: error: template declaration of ‘const _Tp& std::min’
In file included from /usr/include/c++/4.5/algorithm:63:0,
from simulation.cpp:5:
/usr/include/c++/4.5/bits/stl_algo.h: In function ‘void std::__merge_sort_loop(_RandomAccessIterator1, _RandomAccessIterator1, _RandomAccessIterator2, _Distance)’:
/usr/include/c++/4.5/bits/stl_algo.h:3172:26: error: expected unqualified-id before ‘(’ token
/usr/include/c++/4.5/bits/stl_algo.h: In function ‘void std::__merge_sort_loop(_RandomAccessIterator1, _RandomAccessIterator1, _RandomAccessIterator2, _Distance, _Compare)’:
/usr/include/c++/4.5/bits/stl_algo.h:3202:26: error: expected unqualified-id before ‘(’ token
simulation.cpp: In constructor ‘Simulation::Simulation(int, int, int)’:
simulation.cpp:11:13: error: ‘GenRdnGnm’ is not a member of ‘TSnap’
simulation.cpp:11:38: error: expected primary-expression before ‘>’ token
simulation.cpp:11:47: warning: left-hand operand of comma has no effect
I'd be very glad if some one could help resolve my problems (and if you feel like giving some c++/programming wisdom in the process i'd be even happier :) )
Ortholle
The Snap library headers contain the unfortunate macro definitions:
#define min(a,b) ((a)<(b)?(a):(b))
#define max(a,b) ((a)>(b)?(a):(b))
This will cause problems with code that uses (or defines) std::min and std::max.
You can get around this by making sure to include STL headers before Snap, or possibly by adding
#undef min
#undef max
after including the Snap.h header.
Another problem with your code: What's with all those extraneous #includes? Example: Your test.cpp #includes a whole bunch of stuff it doesn't need. All that test.cpp needs is (or should need) simulation.h. simulation.cpp has a similar problem with far too many #includes.
Don't #include something in a file that isn't used in that file.
(Aside: that random_shuffle in simulation.cpp should be std::random_shuffle).
None of these fixes are going to help with the base problem, which is that the Snap library 'conveniently' defines max and min as macros. You don't need these, so undef them.