macros

Hello everyone.
I am writing a finite element code and I want my code works for both 2d and 3d applications. I am writing the code using OOP method and I have several classes and headers. I am trying something like

1
2
3
4
5
6
7
8
#define 2Dimension
#ifdef 2Dimension
define dim 2
define nElmNodes 3
#else
define dim 3
define nElmnodes 4
#endif 


I don't know whether should I make .h file for this and include in every class which uses dim as a variable or put it in main file. I would be really grateful if you help me with this.


this is in header file,
1
2
3
4
5
6
7
8
9
10
11
12
13
#ifndef _DIMENSION_H_
#define _DIMENSION_H_

#define Dimension
#ifdef 2Dimension
#define dim 2
#define nElmNodes 3
#else
#define dim 3
#define nElmNodes 4
#endif 

#endif  

Last edited on
Creating a header file for the dimensions is fine.

Since you mention OOP, I assume this is for C++.
Therefore I would recommend the use of constexpr instead of #define.

1
2
3
4
5
6
7
8
9
10
11
12
13
#ifndef _DIMENSION_H_
#define _DIMENSION_H_

#define Dimension
#ifdef 2Dimension
constexpr int dim {2};
constexpr int nElmNodes {3};
#else
constexpr int dim {3};
constexpr int nElmNodes {4};
#endif 

#endif   

Last edited on
be careful. you may be painting yourself into a corner this way -- some programs will need to mix 2d and 3d and this construct prevents it.
@AbstractionAnon Thanks you so much and yes, this is a cpp code, in my case I need to mix 2d and 3d. As @jonnin said using constexpr prevents this, so what would be the possible solution for this?
Last edited on
I'm not sure what jonnin is referring to. You'll need him to elaborate if it's not the following.

Prior to C++17, constexpr could not be used in #if's.
However, that is no longer the case. C++17 allows constexpr in #if's.
just make the 2d / 3d flag be a class member that you set on construction. Then each variable instance can be whatever it needs to be. You can even make interface type wrappers that inherit this thing and their default ctor can configure it to be 2d or 3d so you have friendly names like thing2d() and thing3d() ... not required, but a fancy approach.

AA, I am saying that with #defines he locks one compile into 2d or 3d mode, unless he does even more weirdness and undefines/redefines them on the fly everywhere which would be a horrible way to have to use the tool.
Last edited on
> I need to mix 2d and 3d. As @jonnin said using constexpr prevents this,
> so what would be the possible solution for this?

If the number of dimensions is known at compile time, perhaps something like this:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
template < std::size_t N = 3 > struct dimension ;

template <> struct dimension<2> 
{
    static constexpr std::size_t dim = 2 ;
    static constexpr std::size_t num_nodes = 3 ;
    // etc...
};

template <> struct dimension<3> 
{
    static constexpr std::size_t dim = 3 ;
    static constexpr std::size_t num_nodes = 4 ;
    // etc...
};
Thank you all for your answers
Topic archived. No new replies allowed.