This is the mail archive of the gsl-discuss@sources.redhat.com mailing list for the GSL project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

Re: Forward declaration is not possible


On Friday 13 December 2002 16:50, Brian Gough wrote:
> Peter Haase writes:
>  > Hi, using GSL to implement some random generators, I would like to
>  > make a forward declaration for 'gsl_rng' and 'gsl_rng_type'
>  > (Otherwise, I have to include the GSL header files in my header
>  > file and clients using my random generators must have these GSL
>  > header files available ). Unfortunatley a forward declaration is
>  > not possible since both 'gsl_rng' and 'gsl_rng_type' are not names
>  > of a struct but are defined by typedef as new types
>
> I'm not clear what you want to do on the client side, can you send an
> example to motivate it. Thanks.
>
> Brian

Hi Brian,
I'm writing a library*  that provides some functions that are useful for 
developing simulation programs. For that reason I programmed a class called 
RandomGenerator:

//in myrandom.h:
#include <gsl_rng.h>

class RandomGenerator
{
  public:
    // Class default constructor:
     RandomGenerator();

     //Returns a random variate with  a specified distribution:
     double get();

  private:
     gsl_rng*  ptrToGslRng;
};

A programmer that would like to use my RandomGenerator class in his program 
needs to include my header file (myrandom.h) and to include (implicit via the 
#include in myrandom.h statement)  the gsl header file. From an object 
oriented point of view, the pointer gsl_rng* is just an implemention detail 
that should be hide from the user of that class. So a better programming 
style is:

//in myrandom.h:
// !This isn't needed anymore: #include <gsl_rng.h>!

//Forward declaration:
struct gsl_rng;

class RandomGenerator
{
  public:
    // Class default constructor:
     RandomGenerator();

     //Returns a random variate with  a specified distribution:
     double get();

  private:
     gsl_rng*  ptrToGslRng;
};
 
Unfortunatley this forward declaration is not possible if gsl_rng is declared 
as follows:

typedef struct {
  char* name;
   /*... */
} gsl_rng;

but the forward declaration is possible if gsl_rng is declared as follows:

typedef struct gsl_rng {
  char* name;
  /*... */
} gsl_rng; 

Note, that code that is already existing can be used with that declaration as 
it was before! I'm not shure if it is strict ANSI C to use gsl_rng as a name 
for the struct and as the name of the new type introduced by the typedef 
statement. But at least in C++ it is standard conform (see C++ ARM s. 106): 
'A typedef may be used to redefine a name to refer to the type to which it 
already refers - even in the scope where the type was originally declared. 
For example: 
typedef struct s { /* */ } s;'

*(actually I'm not writing a library, but I think that is a more common case. 
So look to it as an abstract example)

Hope this makes it a bit more clearer, what I would like to do.

Thanks,
Peter


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]