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.cpp

More 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 199711L

priority 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_EEEE

The 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 1

Debug 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_complied

success, 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_complied

success!

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 OpenFOAM

Case 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
> wmake

A 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.C

Error 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!


A collection of stupid Errors
https://daydreamatnight.github.io/2022/08/15/A-collection-of-stupid-Errors/
Author
Ryan LI
Posted on
August 15, 2022
Licensed under