A collection of stupid Errors
Warning: a set of stupid errors occur when compiling c++ and OpenFOAM.
c++
this pointer in inherited template class
I tried to write a simple snippet of inheriting template class, I wrote this simple code and it gave me such errors.
#include <iostream>
using namespace std;
template <class T>
class Base
{
public:
T m_data;
};
template <class T>
class child_template: public Base<T>
{
public:
void print_child()
{
cout << m_data << endl; // error: use of undeclared identifier 'm_data'; did you mean 'child_class::m_data'?
// cout << this->m_data << endl; // no error
}
};
int main()
{
child_template<int> child_obj;
child_obj.m_data = 20;
child_obj.print_child();
return 0;
}the error is such that:
template_cls_inherit.cpp:17:17: error: use of undeclared identifier 'm_data'; did you mean '__nl_cat_d::__data'?
cout << m_data << endl; // error: use of undeclared identifier 'm_data'; did you mean 'child_class::m_data'?
^~~~~~
__nl_cat_d::__data
/Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX.sdk/usr/include/nl_types.h:90:8: note: '__nl_cat_d::__data' declared here
void *__data;
^
template_cls_inherit.cpp:17:17: error: '__nl_cat_d::__data' is not a member of class 'child_template<int>'
cout << m_data << endl; // error: use of undeclared identifier 'm_data'; did you mean 'child_class::m_data'?
^~~~~~
template_cls_inherit.cpp:26:15: note: in instantiation of member function 'child_template<int>::print_child' requested here
child_obj.print_child();
^
2 errors generated.Error addressed by
I used this->m_data instead of m_data and the error gone
the use of this pointer is necessary here.
More of this pointer in template class inheriting
c++ - Why do I have to access template base class members through the this pointer? - Stack Overflow
put typename and before dependent names
I wrote this function template to print the vector and I got this ERROR. Here's my code:
// some vector features
#include <iostream>
using namespace std;
#include <vector>
template <class T>
void printVector(vector<T> v)
{
for (vector<T>::iterator it = v.begin(); it != v.end(); it++) // error: missing 'typename' prior to dependent type name 'vector<T>::iterator'
// for (vector<int>::iterator it = v.begin(); it != v.end(); it++) // works when gives the type 'int'
// for (auto it = v.begin(); it != v.end(); it++) // works in c++11
{
cout << *it << " ";
}
cout << endl;
}
int main()
{
// constructor
vector<int> v1(10); //size 10, all elements are 0
printVector<int> (v1);
}> g++ codeName.cpp
error: missing 'typename' prior to dependent type name 'vector<T>::iterator'
for(vector<T>::iterator it=v.begin(); it!=v.end(); it++)
^~~~~~~~~~~~~~~~~~~
typename
1 error generated.I know it can be solved by algorithm for_each, and the auto type in c++11. I just don't understand why I can't use T over here and how to address this error.
Error addressed by
substitute the error line with
for (typename vector<T>::iterator it = v.begin(); it != v.end(); it++)Add a typename before the 'vector<T>::iterator', just like the error message suggested.
More about typename
c++ - Where and why do I have to put the "template" and "typename" keywords? - Stack Overflow
Compile with c++11
When compile this code:
#include <iostream>
#include <vector>
#include <algorithm>
using namespace std;
bool cmp(int a, int b)
{
return a < b;
}
int main()
{
vector<int> myvec{3,2,5,6,4,3,6}; // vector initialisation, also in c++11
// vector myvec{3,2,5,6,4,3,6}; // alto deduction data type, available in c++17
vector<int> lbvec(myvec);
sort(myvec.begin(), myvec.end(), cmp); // before c++ 11
cout << "predicate function:" << endl;
for (int it : myvec) // range-based for loop, also is a C++11 extension [-Wc++11-extensions]
cout << it << ' ';
cout << endl;
sort(lbvec.begin(), lbvec.end(), [](int a, int b) -> bool { return a < b; }); // Lambda
cout << "lambda expression:" << endl;
for (int it : lbvec)
cout << it << ' ';
cout << endl;
}> clang++ 2_lambda_expression.cpp
2_lambda_expression.cpp:16:22: error: expected ';' at end of declaration
vector<int> myvec{3,2,5,6,4,3,6}; // vector initialisation, also in c++11
^
;
2_lambda_expression.cpp:22:17: warning: range-based for loop is a C++11 extension [-Wc++11-extensions]
for (int it : myvec) // range-based for loop, also is a C++11 extension [-Wc++11-extensions]
^
2_lambda_expression.cpp:26:38: error: expected expression
sort(lbvec.begin(), lbvec.end(), [](int a, int b) -> bool { return a < b; }); // Lambda
^
2_lambda_expression.cpp:28:17: warning: range-based for loop is a C++11 extension [-Wc++11-extensions]
for (int it : lbvec)
^
2 warnings and 2 errors generated.Error addressed by
lambda function is only supported in c++11.
compile with c++11 flag:
> clang++ --std=c++11 2_lambda_expression.cppMore about default standard c++ version
show g++/clang++ standard c++ version, type in the terminal:
> g++ -dM -E -x c++ /dev/null | grep __cplusplus
#define __cplusplus 201402L> clang++ -dM -E -x c++ /dev/null | grep __cplusplus
#define __cplusplus 199711Lpriority of * and .
When compile this code, use vector container with custom data structure:
#include <iostream>
using namespace std;
#include <vector>
#include <deque>
#include <typeinfo>
class Player
{
public:
string m_name;
int m_score;
public:
Player(){}
Player(string name, int score)
{
m_name = name;
m_score = score;
}
string getName()
{
return m_name;
}
int getScore()
{
return m_score;
}
};
template <class T>
void printVector(const T v)
{
for (typename T::const_iterator it = v.begin(); it != v.end(); it++)
{
// print name and score
cout << "name: " << *it.getName() << " score: " << *it.getScore() << endl; // error: no member named 'getName' in '__gnu_cxx::__normal_iterator<const Player *, std::vector<Player, std::allocator<Player> > >'
// // debug
// cout << "typeid(*it).name() = " << typeid(*it).name() << endl; // 6Player
// cout << "typeid(it).name() = " << typeid(it).name() << endl; // N9__gnu_cxx17__normal_iteratorIPK6PlayerSt6vectorIS1_SaIS1_EEEE
// cout << "name: " << (*it).getName() << " score: " << (*it).getScore() << endl; // no error
// cout << "name: " << it -> getName() << " score: " << it -> getScore() << endl; // no error
}
cout << endl;
}
int main()
{
// init players with name and score = 0
vector<Player> playerList;
string base_name = "player_";
for (int i=0; i<5; i++)
{
playerList.push_back(Player(base_name+(char)(65+i), i));
}
printVector(playerList);
}
The Error occurs as:
> clang++ test.cpp
test.cpp:40:33: error: no member named 'getName' in '__gnu_cxx::__normal_iterator<const Player *, std::vector<Player, std::allocator<Player> > >'
cout << "name: " << *it.getName() << " score: " << *it.getScore() << endl; // error: no member named 'getName' in 'std::__wrap_iter<Player *>'
~~ ^
test.cpp:60:5: note: in instantiation of function template specialization 'printVector<std::vector<Player, std::allocator<Player> > >' requested here
printVector(playerList);
^
1 error generated.Debug
Have a look at the type of *it and it, the output shows:
typeid(*it).name() = 6Player
typeid(it).name() = N9__gnu_cxx17__normal_iteratorIPK6PlayerSt6vectorIS1_SaIS1_EEEEThe type of the it matches that in the error message.
So the bug is because the priority of the * is lower than ..
Error addressed by
Need a pair of parenthesizes to wrap the *it, then use the ..
More
Alternatively, techniques such as ostream << overloading, -> operator and be used.
And the constant_iterator is necessary with a const parameter.
OpenFOAM
change the wmake compiler
Try to make use wmake and the c++ fatal error occurs:
> wmake
Making dependency list for source file onlyMainFunction.C
g++ -std=c++11 -m64 -pthread -DOPENFOAM=2006 -DWM_DP -DWM_LABEL_SIZE=64 -Wall -Wextra -Wold-style-cast -Wnon-virtual-dtor -Wno-unused-parameter -Wno-invalid-offsetof -Wno-attributes -Wno-unknown-pragmas -O3 -DNoRepository -ftemplate-depth-100 -iquote. -IlnInclude -I/CFD/linux/software/OpenFOAM/OpenFOAM-v2006/src/OpenFOAM/lnInclude -I/CFD/linux/software/OpenFOAM/OpenFOAM-v2006/src/OSspecific/POSIX/lnInclude -fPIC -c onlyMainFunction.C -o Make/linux64GccDPInt64Opt/onlyMainFunction.o
onlyMainFunction.C:1:10: fatal error: iostream: No such file or directory
1 | #include <iostream>
| ^~~~~~~~~~
compilation terminated.
make: *** [Make/linux64GccDPInt64Opt/onlyMainFunction.o] Error 1Debug by
Read the Error message and try compile with g++directory:
> g++ --std=c++11 onlyMainFunction.C
onlyMainFunction.C:1:10: fatal error: iostream: No such file or directory
1 | #include <iostream>
| ^~~~~~~~~~
compilation terminated.Same error occurs, try compile with clang++ instead:
> clang++ --std=c++11 onlyMainFunction.C -o $FOAM_USER_APPBIN/onlyMainFunction-clang_compliedsuccess, so the error is the Gcc compiler.
Error addressed by
change the wmake compiler toclang:
in tcsh shell:
> setenv WM_COMPILER Clang
> wmake
clang++ -std=c++11 -m64 -pthread -DOPENFOAM=2006 -DWM_DP -DWM_LABEL_SIZE=64 -Wall -Wextra -Wold-style-cast -Wnon-virtual-dtor -Wno-unused-parameter -Wno-invalid-offsetof -Wno-undefined-var-template -Wno-unknown-warning-option -O3 -DNoRepository -ftemplate-depth-100 -iquote. -IlnInclude -I/CFD/linux/software/OpenFOAM/OpenFOAM-v2006/src/OpenFOAM/lnInclude -I/CFD/linux/software/OpenFOAM/OpenFOAM-v2006/src/OSspecific/POSIX/lnInclude -fPIC -c onlyMainFunction.C -o Make/linux64GccDPInt64Opt/onlyMainFunction.o
clang++ -std=c++11 -m64 -pthread -DOPENFOAM=2006 -DWM_DP -DWM_LABEL_SIZE=64 -Wall -Wextra -Wold-style-cast -Wnon-virtual-dtor -Wno-unused-parameter -Wno-invalid-offsetof -Wno-undefined-var-template -Wno-unknown-warning-option -O3 -DNoRepository -ftemplate-depth-100 -iquote. -IlnInclude -I/CFD/linux/software/OpenFOAM/OpenFOAM-v2006/src/OpenFOAM/lnInclude -I/CFD/linux/software/OpenFOAM/OpenFOAM-v2006/src/OSspecific/POSIX/lnInclude -fPIC -Xlinker --add-needed Make/linux64GccDPInt64Opt/onlyMainFunction.o -L/CFD/linux/software/OpenFOAM/OpenFOAM-v2006/platforms/linux64GccDPInt64Opt/lib \
-lOpenFOAM -ldl \
-lm -o /data/epblsr/OpenFOAM/epblsr-v2006/platforms/linux64GccDPInt64Opt/bin/onlyMainFunction-wmake_compliedsuccess!
More about $WM_COMPILER
The$WM_COMPILER is set in $FOAM_ETC/cshrc and $FOAM_ETC/bashrc
The default setting is:
#------------------------------------------------------------------------------
# Configuration environment variables.
# Override with <prefs.csh> instead of editing here.
# [WM_COMPILER_TYPE] - Compiler location:
# = system | ThirdParty
setenv WM_COMPILER_TYPE system
# [WM_COMPILER] - Compiler:
# = Gcc | Clang | Icc | Cray | Amd | Arm | Pgi | Fujitsu |
# Gcc<digits> | Clang<digits>
setenv WM_COMPILER Gcc
# [WM_PRECISION_OPTION] - Floating-point precision:
# = DP | SP | SPDP
setenv WM_PRECISION_OPTION DP
# [WM_LABEL_SIZE] - Label size in bits:
# = 32 | 64
setenv WM_LABEL_SIZE 64
# [WM_COMPILE_OPTION] - Optimised(default), debug, profiling, other:
# = Opt | Debug | Prof
# Other is processor or packaging specific (eg, OptKNL)
setenv WM_COMPILE_OPTION Opt
# [WM_MPLIB] - MPI implementation:
# = SYSTEMOPENMPI | OPENMPI | SYSTEMMPI | MPI | MPICH | MPICH-GM |
# HPMPI | CRAY-MPICH | FJMPI | QSMPI | SGIMPI | INTELMPI | USERMPI
# Also possible to use INTELMPI-xyz etc and define your own wmake rule
setenv WM_MPLIB OPENMPI
#------------------------------------------------------------------------------
# (advanced / legacy)
# [WM_PROJECT] - This project is "OpenFOAM" - do not change
setenv WM_PROJECT OpenFOAMCase insensitive filenames
The onlyMainFunction.C can be complied successfully by g++ .
Try to make with wmake and ERROR arose:
> wmake
make: *** No rule to make target `Make/linux64GccDPInt64Opt/onlyMainFunction.c.dep', needed by `Make/linux64GccDPInt64Opt/onlyMainFunction.o'. Stop.Debug by
Have a look at the file structure:
> tree .
.
├── Make
│ ├── files
│ └── options
└── onlyMainFunction.C
1 directory, 3 files
nothing wrong.
look into the Make/files and the stupidity is found:
> cat Make/files
onlyMainFunction.c
EXE = $(FOAM_USER_APPBIN)/onlyMainFunction-wmake_complied
Error addressed by
change the onlyMainFunction.c with onlyMainFunction.C in the Make/file.
Define namespace Foam
When try to compile a default solver,
> foamNewApp DefaultApp
Creating application code directory DefaultApp
Creating Make subdirectory
> cd DefaultApp
> wmakeA long series of Errors occur, a summery of it shows:
OpenFOAM-v2006/src/OpenFOAM/lnInclude/primitiveFieldsFwd.H:51:15: error: ‘label’ was not declared in this scope
typedef Field<label> labelField;
^
OpenFOAM-v2006/src/OpenFOAM/lnInclude/primitiveFieldsFwd.H:51:20: error: template argument 1 is invalid
typedef Field<label> labelField;
^
OpenFOAM-v2006/src/OpenFOAM/lnInclude/primitiveFieldsFwd.H:51:32: error: invalid type in declaration before ‘;’ token
typedef Field<label> labelField;
^
OpenFOAM-v2006/src/OpenFOAM/lnInclude/primitiveFieldsFwd.H:52:15: error: ‘scalar’ was not declared in this scope
typedef Field<scalar> scalarField;
^
OpenFOAM-v2006/src/OpenFOAM/lnInclude/primitiveFieldsFwd.H:52:34: error: invalid type in declaration before ‘;’ token
typedef Field<scalar> scalarField;
^
OpenFOAM-v2006/src/OpenFOAM/lnInclude/primitiveFieldsFwd.H:53:15: error: ‘solveScalar’ was not declared in this scope
typedef Field<solveScalar> solveScalarField;
^
OpenFOAM-v2006/src/OpenFOAM/lnInclude/primitiveFieldsFwd.H:53:26: error: template argument 1 is invalid
typedef Field<solveScalar> solveScalarField;
^
OpenFOAM-v2006/src/OpenFOAM/lnInclude/primitiveFieldsFwd.H:53:44: error: invalid type in declaration before ‘;’ token
typedef Field<solveScalar> solveScalarField;
^
OpenFOAM-v2006/src/OpenFOAM/lnInclude/primitiveFieldsFwd.H:54:15: error: ‘vector’ was not declared in this scope
typedef Field<vector> vectorField;
^Have a look into the primitiveFieldsFwd.H file, the error are summarized as notations:
#ifndef primitiveFieldsFwd_H
#define primitiveFieldsFwd_H
#include "fieldTypes.H"
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
namespace
{
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
template<class Type> class Field;
typedef Field<bool> boolField;
typedef Field<label> labelField; // error: ‘label’ was not declared in this scope
typedef Field<scalar> scalarField; // error: ‘scalar’ was not declared in this scope
typedef Field<solveScalar> solveScalarField; // error: ‘solveScalar’ was not declared in this scope
typedef Field<vector> vectorField; // error: ‘vector’ was not declared in this scope
typedef Field<sphericalTensor> sphericalTensorField; // error: ‘sphericalTensor’ was not declared in this scope
typedef Field<symmTensor> symmTensorField; // error: ‘symmTensor’ was not declared in this scope
typedef Field<tensor> tensorField; // error: ‘tensor’ was not declared in this scope
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
} // End namespace Foam
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
#endif
// ************************************************************************* //
It is the source code going wrong
Debug by
compare the code with backup, using commands: vimdiff and diff -r
Error addressed by
The namespace is not defined in the code, it should be
namespace Foam
{
...
}More
Don't turn the autosave on in the VS code!
Again, the error message tells everything, when foo is not declared in this scope occurs, one should check the scope.
Typo in the filename
When trying to implement a solver SolidParticleInterFoam combining Lagrangian Particle Tracking with VoF InterFoam solver, I compile the solver successfully but encountered big obstacle with the test case.
I run the solver in the test case directory:
> blockMesh
> setFields
> solidParticleInterFoam
--> FOAM FATAL ERROR:
Size of origProcId field 0 does not match the number of particles 2
From void Foam::Cloud<ParticleType>::checkFieldIOobject(const Foam::Cloud<ParticleType>&, const Foam::IOField<DataType>&) const [with DataType = long int; ParticleType = Foam::solidParticle]
in file /data/CFD/linux/software/OpenFOAM/OpenFOAM-v2006/src/lagrangian/basic/lnInclude/CloudIO.C at line 215.
Debug by
Read the error message, it seems like the error is because it cannot read the procid file, because I set 2 particles to track and the size of the origProcId field and the number of particles should both be 2.
Have a look at the case structure:
> tree
.
├── 0
│ ├── alpha.water
│ ├── lagrangian
│ │ └── defaultCloud
│ │ ├── d
│ │ ├── orgId // it should be origId
│ │ ├── orgProcId // it should be origProcId
│ │ ├── positions
│ │ └── U
│ ├── p_rgh
│ ├── U
│ └── uniform
│ └── lagrangian
│ └── defaultCloud
│ └── cloudProperties
├── constant
│ ├── g
│ ├── particleProperties
│ ├── transportProperties
│ └── turbulenceProperties
└── system
├── blockMeshDict
├── controlDict
├── decomposeParDict
├── fvSchemes
├── fvSolution
├── sampling
└── setFieldsDict
8 directories, 20 files
And I did NOT spot the typo in the 0/lagrangian/defaultCloud/orgId and orgProcId!
I dig into the source code that went wrong, applied grep to search for the error flag, read the constructors of the solidParticleCloud Class class in the Doxygen, etc.
such as:
> grep -rn origProcId
lagrangian/basic/particle/particleTemplates.C:144: IOobject procIO(c.fieldIOobject("origProcId", IOobject::MUST_READ));
lagrangian/basic/particle/particleTemplates.C:148: IOField<label> origProcId(procIO, valid && haveFile);
lagrangian/basic/particle/particleTemplates.C:149: c.checkFieldIOobject(c, origProcId);
lagrangian/basic/particle/particleTemplates.C:161: p.origProc_ = origProcId[i];
lagrangian/basic/particle/particleTemplates.C:200: c.fieldIOobject("origProcId", IOobject::NO_READ),
lagrangian/basic/particle/particleTemplates.C:245: const auto& origProcId = cloud::lookupIOField<label>("origProc", obr);
lagrangian/basic/particle/particleTemplates.C:257: p.origProc_ = origProcId[i];
> find */ -iname "Cloud.*"
lagrangian/basic/lnInclude/Cloud.C
lagrangian/basic/lnInclude/Cloud.H
lagrangian/basic/Cloud/Cloud.C
lagrangian/basic/Cloud/Cloud.H
OpenFOAM/fields/cloud/cloud.H
OpenFOAM/fields/cloud/cloud.C
OpenFOAM/lnInclude/cloud.H
OpenFOAM/lnInclude/cloud.CError addressed by
Simply change the file names into the right ones...
Always check the file name carefully! It happens twice and it is really a wast of time!