CFD Online Logo CFD Online URL
www.cfd-online.com
[Sponsors]
Home > Forums > Software User Forums > OpenFOAM > OpenFOAM Programming & Development

It has to include complete definition of a type (not just fwd declaration), isn't it?

Register Blogs Members List Search Today's Posts Mark Forums Read

Reply
 
LinkBack Thread Tools Search this Thread Display Modes
Old   August 12, 2016, 17:59
Default It has to include complete definition of a type (not just fwd declaration), isn't it?
  #1
Senior Member
 
Zeppo's Avatar
 
Sergei
Join Date: Dec 2009
Posts: 261
Rep Power: 21
Zeppo will become famous soon enough
While scanning the source code of OpenFoam 4.x I see this file files which lists sources to be build into finiteVolume library:
Code:
//--- src/finiteVolume/Make/files ---
...
finiteVolume/fvc/fvcFlux.C
...
LIB = $(FOAM_LIBBIN)/libfiniteVolume
Among others it lists fvcFlux.C file:
Code:
//--- src/finiteVolume/fvc/fvcFlux.C ---
#include "fvcFlux.H"
#include "surfaceInterpolate.H"
...
Foam::tmp<Foam::surfaceScalarField> Foam::fvc::flux
(
    const volVectorField& vvf
)
{
    return scheme<vector>
    (
        vvf.mesh(),
        "flux(" + vvf.name() + ')'
    )().dotInterpolate(vvf.mesh().Sf(), vvf);
}
...
As you can see here, to compile this file a compiler has to be given complete definition of volVectorField type. Otherwise it can't check if, for example, the call vvf.mesh() is valid or not. It has to see volVectorField definition including all volVectorField's member functions. Basically it can be done via inclusion of corresponding header file (.h-file). There're two .h-files included into fvcFlux.C: fvcFlux.H and surfaceInterpolate.H
Code:
//--- src/finiteVolume/fvc/fvcFlux.H ---
#include "volFieldsFwd.H"
#include "surfaceFieldsFwd.H"
...
Code:
//--- src/finiteVolume/interpolation/surfaceInterpolation/surfaceInterpolation/surfaceInterpolate.H
#include "tmp.H"
#include "volFieldsFwd.H"
#include "surfaceFieldsFwd.H"
#include "surfaceInterpolationScheme.H"
#include "one.H"
...
Both fvcFlux.h and surfaceInterpolate.H in turn include volFieldsFwd.H:
Code:
//--- src/finiteVolume/fields/volFields/volFieldsFwd.H
#include "fieldTypes.H"

class volMesh;

template<class Type>
class fvPatchField;

template<class Type, template<class> class PatchField, class GeoMesh>
class GeometricField;

typedef GeometricField<scalar, fvPatchField, volMesh> volScalarField;
typedef GeometricField<vector, fvPatchField, volMesh> volVectorField;
typedef GeometricField<sphericalTensor, fvPatchField, volMesh>
    volSphericalTensorField;
typedef GeometricField<symmTensor, fvPatchField, volMesh> volSymmTensorField;
typedef GeometricField<tensor, fvPatchField, volMesh> volTensorField;
...
volFieldsFwd.H contains only forward declaration (incomplete definition) of volScalarField (which is merely typedefed GeometricField<scalar, fvPatchField, volMesh>) and it is not enough for the compiler to compile fvcFlux.C. I looked through the other included files to find that none of them contains the definition of GeometricField<scalar, fvPatchField, volMesh> (which is located in src/OpenFOAM/fields/GeometricFields/GeometricField.GeometricField.H). Have I looked over something?
Zeppo is offline   Reply With Quote

Old   August 12, 2016, 18:34
Default
  #2
Super Moderator
 
Tobi's Avatar
 
Tobias Holzmann
Join Date: Oct 2010
Location: Bad Wörishofen
Posts: 2,711
Blog Entries: 6
Rep Power: 52
Tobi has a spectacular aura aboutTobi has a spectacular aura aboutTobi has a spectacular aura about
Send a message via ICQ to Tobi Send a message via Skype™ to Tobi
Hi Zeppo,

nice post (clear and with all information). Here, you need only the forward declaration nothing more. Why? It is easy, we are building libraries and for that the compiler just need to know the class but not the definition of classes (just needed if you make an instance and hence you need to allocate memory).
__________________
Keep foaming,
Tobias Holzmann
Tobi is offline   Reply With Quote

Old   August 13, 2016, 11:49
Default
  #3
Senior Member
 
Zeppo's Avatar
 
Sergei
Join Date: Dec 2009
Posts: 261
Rep Power: 21
Zeppo will become famous soon enough
Tobias, I don't think your answer is correct. Look at fvcFlux.C ance again:
Code:
//--- src/finiteVolume/fvc/fvcFlux.C ---
#include "fvcFlux.H"
#include "surfaceInterpolate.H"
...
Foam::tmp<Foam::surfaceScalarField> Foam::fvc::flux
(
    const volVectorField& vvf
)
{
    return scheme<vector>
    (
        vvf.mesh(),
        "flux(" + vvf.name() + ')'
    )().dotInterpolate(vvf.mesh().Sf(), vvf);
}
...
At the point where vvf.mesh() is invoked the compiler must know the complete definition of the vvf's type for many reasons:
1. To ensure that the very method volVectorField::mesh() do exist. If not (or it is private/protected), it searches for mesh() in volVectorField's base classes.
2. If function mesh() is found, the compiler must know it's return type so that it can ensure that the return type matches (possible with additional conversion) the type of the input parameter for function scheme<vector>:
Code:
//--- src/finiteVolume/interpolation/surfaceInterpolation/surfaceInterpolation/surfaceInterpolate.H
...
//- Return weighting factors for scheme given from Istream
template<class Type>
static tmp<surfaceInterpolationScheme<Type>> scheme
(
    const fvMesh& mesh,
    Istream& schemeData
);
...
And when a compiler compiles the source file into the object file the compiler doesn't really care much what the object file will be used for later on. It is the linker's job to build library or executable from the object files.
So the question is still open: how the compiler can "see" the definition of GeometricField<scalar, fvPatchField, volMesh>? I can't.
Zeppo is offline   Reply With Quote

Old   August 13, 2016, 13:11
Default
  #4
Super Moderator
 
Tobi's Avatar
 
Tobias Holzmann
Join Date: Oct 2010
Location: Bad Wörishofen
Posts: 2,711
Blog Entries: 6
Rep Power: 52
Tobi has a spectacular aura aboutTobi has a spectacular aura aboutTobi has a spectacular aura about
Send a message via ICQ to Tobi Send a message via Skype™ to Tobi
Maybe your are correct if you say that I am wrong... I have not time to check it in such detail. But here is the way it should be. First of all. The method volVectorField::mesh does not exist because the volVectorField is just a typedef from the GeometricField and even this has no function called mesh(). You have to dig deeper because the ::mesh() function you are referring to is inherit by the DimensionedField class.

The problem you mentioned, that the compiler need to know everything is correct (here I was wrong). But luckily it knows everything. The first stuff that the compiler gets to know is the pre-compiled library called libOpenFOAM.so (Make/options).

The volFields are included in line 231 in the Make/files file (src/finiteVolume) and here the compiler gets all information about the field (how they are build and which function is inherit by the classes).

The compilation of you file fvcFlux.C comes in line 395. So the compiler knows the fields.
__________________
Keep foaming,
Tobias Holzmann
Tobi is offline   Reply With Quote

Old   August 13, 2016, 14:01
Default
  #5
Senior Member
 
Zeppo's Avatar
 
Sergei
Join Date: Dec 2009
Posts: 261
Rep Power: 21
Zeppo will become famous soon enough
Believe me or not, Tobias, volVectorField::mesh() is literally the same as GeometricField<scalar, fvPatchField, volMesh>::mesh(). If volVectorField::mesh() does not exist, GeometricField<scalar, fvPatchField, volMesh>::mesh() does not exist either.

While a compiler does its job compiling a source file it doesn't care about any object code (object files (.o), static libraries (.a), shared libraries (.so)). Compiler goes in loop though all files listed in Make/files compiling each file independently. To be more specific, it is not a source file, it is a compilation unit to be compiled which is what the compiler see when the content of all #includes have been inserted into the source file by a preprocessor. fvcFlux.C and volFields.C are in different compilation units and don't see each other. Source files can ever be compiled in parallel independently.

When all files have been compiled into object files, the linker teakes over building either a library or executable.
Zeppo is offline   Reply With Quote

Old   August 13, 2016, 15:12
Default
  #6
Super Moderator
 
Tobi's Avatar
 
Tobias Holzmann
Join Date: Oct 2010
Location: Bad Wörishofen
Posts: 2,711
Blog Entries: 6
Rep Power: 52
Tobi has a spectacular aura aboutTobi has a spectacular aura aboutTobi has a spectacular aura about
Send a message via ICQ to Tobi Send a message via Skype™ to Tobi
Hello Sergei,

I am sorry for the non-helpful answers.

  1. You 're right, the things that I wrote above are not correct. The line in which we start the compiling of fvcFlux.C is not really important because each file is compiled as an own library » .o «
  2. The compiler has to know the class definition of the volVectorField
  3. Of course the volVectorField can call mesh(), based on the derivatives. I just wanted to make clear that the mesh() function is defined in the DimensionedField.H file/class.
But now, I have (hopefully) figured out the answer to your question. If we delete the whole library
Code:
src
cd finiteVolume
wclean
and remove all entries in the Make/files file except of fvcFlux.C, we see what happens. After excecuting wmake libso we get:
Code:
shorty@finiteVolume: wmake libso 
/home/shorty/OpenFOAM/OpenFOAM-4.x/src/finiteVolume
wmakeLnInclude: linking include files to ./lnInclude
Making dependency list for source file finiteVolume/fvc/fvcFlux.C
g++ -std=c++0x -m64 -Dlinux64 -DWM_ARCH_OPTION=64 -DWM_DP -DWM_LABEL_SIZE=32 -Wall -Wextra -Wold-style-cast -Wnon-virtual-dtor -Wno-unused-parameter -Wno-invalid-offsetof -O3  -DNoRepository -ftemplate-depth-100 -I/home/shorty/OpenFOAM/OpenFOAM-4.x/src/triSurface/lnInclude -I/home/shorty/OpenFOAM/OpenFOAM-4.x/src/meshTools/lnInclude  -IlnInclude -I. -I/home/shorty/OpenFOAM/OpenFOAM-4.x/src/OpenFOAM/lnInclude -I/home/shorty/OpenFOAM/OpenFOAM-4.x/src/OSspecific/POSIX/lnInclude   -fPIC -c finiteVolume/fvc/fvcFlux.C -o /home/shorty/OpenFOAM/OpenFOAM-4.x/platforms/linux64GccDPInt32Opt/src/finiteVolume/finiteVolume/fvc/fvcFlux.o
g++ -std=c++0x -m64 -Dlinux64 -DWM_ARCH_OPTION=64 -DWM_DP -DWM_LABEL_SIZE=32 -Wall -Wextra -Wold-style-cast -Wnon-virtual-dtor -Wno-unused-parameter -Wno-invalid-offsetof -O3  -DNoRepository -ftemplate-depth-100 -I/home/shorty/OpenFOAM/OpenFOAM-4.x/src/triSurface/lnInclude -I/home/shorty/OpenFOAM/OpenFOAM-4.x/src/meshTools/lnInclude  -IlnInclude -I. -I/home/shorty/OpenFOAM/OpenFOAM-4.x/src/OpenFOAM/lnInclude -I/home/shorty/OpenFOAM/OpenFOAM-4.x/src/OSspecific/POSIX/lnInclude   -fPIC -shared -Xlinker --add-needed -Xlinker --no-as-needed /home/shorty/OpenFOAM/OpenFOAM-4.x/platforms/linux64GccDPInt32Opt/src/finiteVolume/finiteVolume/fvc/fvcFlux.o -L/home/shorty/OpenFOAM/OpenFOAM-4.x/platforms/linux64GccDPInt32Opt/lib \
    -lOpenFOAM -ltriSurface -lmeshTools  -o /home/shorty/OpenFOAM/OpenFOAM-4.x/platforms/linux64GccDPInt32Opt/lib/libfiniteVolume.so
'/home/shorty/OpenFOAM/OpenFOAM-4.x/platforms/linux64GccDPInt32Opt/lib/libfiniteVolume.so' is up to date.
I highlighted the important part. Here, wmake links all needed header files into the lnInclude folder that is also included during the compilation (UserGuide):
Code:
3.2.2.1    Including headers

   
The compiler searches for the included header files in the following order, specified with the -I option in wmake: 
  1. the $WM_PROJECT_DIR/src/OpenFOAM/lnInclude directory;
  2. a local lnInclude directory, i.e. newApp/lnInclude;
  3. the local directory, i.e. newApp;
  4. platform dependent paths set in files in the $WM_PROJECT_DIR/wmake/rules/$WM_ARCH/ directory, e.g. /usr/X11/include and $(MPICH_ARCH_PATH)/include;
  5. other directories specified explicitly in the Make/options file with the -I option.
  • The typedef of volVectorField is in the lnInclude/volFieldsFwd.H (but we have again a forwarded class definition).
  • After I read your thread again, I think you are at the same point at the moment
  • The fact that we also include the folder src/OpenFOAM/lnInclude should be the anwer. Here we find the GeometricField, DimensionedField header and source files and hence the definition of volVectorField is available.

Two things that I learned
  • In the topics where I am not so convinced, I should first check it in more detail before I post an answer
  • I also forgot that wmake include the OpenFoam/lnInclude folder

I hope that this is now the answer to your question and I am sorry for the first two useless answers.


To sum up:

You were right in all points and the missing definition comes from the header files that are included automatically by wmake (src/OpenFoam/lnInclude)
__________________
Keep foaming,
Tobias Holzmann

Last edited by Tobi; October 14, 2017 at 08:03.
Tobi is offline   Reply With Quote

Old   August 13, 2016, 17:43
Default
  #7
Senior Member
 
Zeppo's Avatar
 
Sergei
Join Date: Dec 2009
Posts: 261
Rep Power: 21
Zeppo will become famous soon enough
Quote:
Originally Posted by Tobi View Post
I highlighted the important part. Here, wmake links all needed header files into the lnInclude folder that is also included during the compilation (UserGuide):
Code:
3.2.2.1    Including headers
The compiler searches for the included header files in the following order, specified with the -I option in wmake: 
  1. the $WM_PROJECT_DIR/src/OpenFOAM/lnInclude directory;
  2. a local lnInclude directory, i.e. newApp/lnInclude;
  3. the local directory, i.e. newApp;
  4. platform dependent paths set in files in the $WM_PROJECT_DIR/wmake/rules/$WM_ARCH/ directory, e.g. /usr/X11/include and $(MPICH_ARCH_PATH)/include;
  5. other directories specified explicitly in the Make/options file with the -I option.
These are the paths (folders in a file system) where a preprocessor (which is run by a compiler in the beginnig of compilation) searches for the files which were declared with #include directive in a source file (fvcFlux.C in my case):
Code:
//--- src/finiteVolume/fvc/fvcFlux.C ---
#include "fvcFlux.H"
#include "surfaceInterpolate.H"
...
Foam::tmp<Foam::surfaceScalarField> Foam::fvc::flux
(
    const volVectorField& vvf
)
{
    return scheme<vector>
    (
        vvf.mesh(),
        "flux(" + vvf.name() + ')'
    )().dotInterpolate(vvf.mesh().Sf(), vvf);
}
...
The preprocessor sees these directives
Code:
#include "fvcFlux.H"
#include "surfaceInterpolate.H"
and tries to find files fvcFlux.H and surfaceInterpolate.H in the directories mentioned above in your list. If the files are found their content is put into the source file (actually into the compilation unit formed in RAM) and compiled into the object file.
Quote:
Originally Posted by Tobi View Post
Two things that I learned
  • In the topics where I am not so convinced, I should first check it in more detail before I post an answer
I hope that this is now the answer to your question and I am sorry for the first two useless answers
Anyway, thank you for making attempts to help.
I don't have my OpenFoam environment at hand. Please, can you show what you have in fvcFlux.dep file when you have compiled fvcFlux.C. According to the UserGuide this file (fvcFlux.dep) contains a list of files which fvcFlux.C depends on. Here the cite from UserGuide:
Quote:
On execution, wmake builds a dependency list file with a .dep file extension, e.g. newApp.C.dep in our example, in a $WM_OPTIONS sub-directory of the Make directory, e.g. Make/linuxGccDPInt64Opt.
Zeppo is offline   Reply With Quote

Old   August 13, 2016, 18:23
Default
  #8
Super Moderator
 
Tobi's Avatar
 
Tobias Holzmann
Join Date: Oct 2010
Location: Bad Wörishofen
Posts: 2,711
Blog Entries: 6
Rep Power: 52
Tobi has a spectacular aura aboutTobi has a spectacular aura aboutTobi has a spectacular aura about
Send a message via ICQ to Tobi Send a message via Skype™ to Tobi
I was lying on my couch when I got the point. Based on the include files of the fvcFlux.H, there is no file that includes the header of the GeometricField.H file. Finally I got your question. Hmmm... there is also no fvcFlux.dep file.

  • I am not sure but at the end of the fvcFlux.H we include the fvcFluxTemplates.C that includes the fvMesh.H which includes the DimensionedField.H. Finally there are a lot of more headers that are included then. http://cpp.openfoam.org/v4/a05839.html
  • I found it after I compared it with 2.3.1 (here it was different)
I think this was the missing part. Based on the implementation, doxygen does not show the included fvcFluxTemplates.C file for the fvcFlux.H (file » fvc/fvcFlux.H «)



Code:
#ifdef NoRepository
    #include "fvcFluxTemplates.C"
#endif
__________________
Keep foaming,
Tobias Holzmann
Tobi is offline   Reply With Quote

Old   August 13, 2016, 20:10
Default
  #9
Senior Member
 
Zeppo's Avatar
 
Sergei
Join Date: Dec 2009
Posts: 261
Rep Power: 21
Zeppo will become famous soon enough
As UserGuide says, fvcFlux.dep should be in your Make/linux64GccDPInt32Opt/

Even if DimensionedField.H was included into fvcFlux.C (through fvcFluxTemplates.C) it wouldn't help much as the compiler still doesn't know that GeometricField is inherited from DimensionedField so the compiler can't allow invocation of any DimensionedField's methods from an object of GeometricField type. Agree?

I am still at the position where I started from: there seems to be no trace of GeometricField.h in fvcFlux.C file.
Zeppo is offline   Reply With Quote

Old   August 13, 2016, 20:37
Default
  #10
Super Moderator
 
Tobi's Avatar
 
Tobias Holzmann
Join Date: Oct 2010
Location: Bad Wörishofen
Posts: 2,711
Blog Entries: 6
Rep Power: 52
Tobi has a spectacular aura aboutTobi has a spectacular aura aboutTobi has a spectacular aura about
Send a message via ICQ to Tobi Send a message via Skype™ to Tobi
Quote:
Originally Posted by Zeppo View Post
Even if DimensionedField.H was included into fvcFlux.C (through fvcFluxTemplates.C) it wouldn't help much as the compiler still doesn't know that GeometricField is inherited from DimensionedField so the compiler can't allow invocation of any DimensionedField's methods from an object of GeometricField type. Agree?
Yes I agree.
__________________
Keep foaming,
Tobias Holzmann
Tobi is offline   Reply With Quote

Old   August 14, 2016, 06:49
Default
  #11
Super Moderator
 
Tobi's Avatar
 
Tobias Holzmann
Join Date: Oct 2010
Location: Bad Wörishofen
Posts: 2,711
Blog Entries: 6
Rep Power: 52
Tobi has a spectacular aura aboutTobi has a spectacular aura aboutTobi has a spectacular aura about
Send a message via ICQ to Tobi Send a message via Skype™ to Tobi
Dear Zappo,

I checked the *dep file now and indeed there is the GeometricField.H included:

Code:
$(OBJECTS_DIR)/finiteVolume/fvc/fvcFlux.C.dep: \
finiteVolume/fvc/fvcFlux.C \
finiteVolume/fvc/fvcFlux.H \
lnInclude/volFieldsFwd.H \
$(WM_PROJECT_DIR)/src/OpenFOAM/lnInclude/fieldTypes.H \
$(WM_PROJECT_DIR)/src/OpenFOAM/lnInclude/label.H \
$(WM_PROJECT_DIR)/src/OpenFOAM/lnInclude/int.H \
$(WM_PROJECT_DIR)/src/OpenFOAM/lnInclude/int32.H \
...
$(WM_PROJECT_DIR)/src/OpenFOAM/lnInclude/GeometricField.H \
$(WM_PROJECT_DIR)/src/OpenFOAM/lnInclude/dimensionedTypes.H \
$(WM_PROJECT_DIR)/src/OpenFOAM/lnInclude/dimensionedVector.H \
$(WM_PROJECT_DIR)/src/OpenFOAM/lnInclude/dimensionedSphericalTensor.H \
$(WM_PROJECT_DIR)/src/OpenFOAM/lnInclude/dimensionedSymmTensor.H \
...
$(WM_PROJECT_DIR)/src/OpenFOAM/lnInclude/GeometricField.C \
$(WM_PROJECT_DIR)/src/OpenFOAM/lnInclude/GeometricBoundaryField.C \
$(WM_PROJECT_DIR)/src/OpenFOAM/lnInclude/emptyPolyPatch.H \
...
In some file it has to be included.
__________________
Keep foaming,
Tobias Holzmann
Tobi is offline   Reply With Quote

Old   August 14, 2016, 10:32
Default
  #12
Senior Member
 
Zeppo's Avatar
 
Sergei
Join Date: Dec 2009
Posts: 261
Rep Power: 21
Zeppo will become famous soon enough
Now, it would be a good thing to have someone explain how that $(WM_PROJECT_DIR)/src/OpenFOAM/lnInclude/GeometricField.H got into fvcFlux.C's dependency list. Tobias, any ideas?
Zeppo is offline   Reply With Quote

Old   August 16, 2016, 15:01
Default
  #13
Super Moderator
 
Tobi's Avatar
 
Tobias Holzmann
Join Date: Oct 2010
Location: Bad Wörishofen
Posts: 2,711
Blog Entries: 6
Rep Power: 52
Tobi has a spectacular aura aboutTobi has a spectacular aura aboutTobi has a spectacular aura about
Send a message via ICQ to Tobi Send a message via Skype™ to Tobi
Hello Zappo,

I was searching one hour yesterday to figure out where the place is, that includes the header of GemoetricField.H. Unfortunately I could not find the file. Now I am also very interested how this works. If you figure it out, I would be glad to hear the answer. Maybe wyldckat could know it?
__________________
Keep foaming,
Tobias Holzmann
Tobi is offline   Reply With Quote

Reply

Tags
compiler, complete definition, forward declaration, include

Thread Tools Search this Thread
Search this Thread:

Advanced Search
Display Modes

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off
Trackbacks are Off
Pingbacks are On
Refbacks are On


Similar Threads
Thread Thread Starter Forum Replies Last Post
compilation problem with "fvPatch::lookupPatchField" Ya_Squall2010 OpenFOAM Programming & Development 9 November 15, 2021 23:01
Modified pimpleFoam solver to MRFPimpleFoam solver hiuluom OpenFOAM Programming & Development 12 June 14, 2015 22:22
LES supersonic free jet martyn88 OpenFOAM 22 April 17, 2015 07:00
T Junction Stability ignacio OpenFOAM Running, Solving & CFD 5 May 2, 2013 11:44
Problems in compiling paraview in Suse 10.3 platform chiven OpenFOAM Installation 3 December 1, 2009 08:21


All times are GMT -4. The time now is 07:57.