No subject


Tue Apr 3 04:57:33 UTC 2007


names even before the template is used (expanded in
some other part of the code).

And because while parsing the template the compiler
doesnt know "T", it also cant expand the base class
(SixStore) and therefore wouldnt know about the
"store" member variable.

Explicitly saying that it is a member variable
(this->store, or SixStore<T>::store) must turn off the
checking -- I´m betting that if you use something like
"this->xxx" it will only yield an error during the
first template instantiation.

But I dont have a C++ compiler (g++) here to check for
that :(, so I´m just guessing.

If you find out, pls let us know :)

good luck,

jan





   --- Dr Mark H Phillips <mark at austrics.com.au>
escreveu:
  > Hi,
  >
  > The recent versions of g++ (in contrast to 3.3.*
  > versions) will no
  > longer compile:
  >
  >   #include <iostream>
  >
  >   template<typename T> struct SixStore {
  >     int store; SixStore(): store(6) {}
  >   };
  >
  >   template<typename T> struct Six: public
  > SixStore<T> {
  >     int six() {return store;}
  >   };
  >
  >   int main() {
  >     Six<char> s;
  >     std::cout<<"six = "<<s.six()<<std::endl;
  >   }
  >
  > It complains with:
  >
  >   tst3.cc: In member function `int Six<T>::six()':
  >   tst3.cc:8: error: `store' undeclared (first use
  > this function)
  >
  > If I remove the template stuff however, it compiles
  > fine.  I had
  > a look on the GCC website and on the page
  >
  >   http://gcc.gnu.org/bugs.html#known
  >
  > I found the following information:
  >
  >   This also affects members of base classes, see
  > [14.6.2]:
  >                 template <typename> struct A
  >                 {
  >                     int i, j;
  >                 };
  >
  >                 template <typename T> struct B :
  > A<T>
  >                 {
  >                     int foo1() { return i; }
  > // error
  >                     int foo2() { return this->i; }
  > // OK
  >                     int foo3() { return B<T>::i; }
  > // OK
  >                     int foo4() { return A<T>::i; }
  > // OK
  >
  >                     using A<T>::j;
  >                     int foo5() { return j; }
  > // OK
  >                 };
  >
  > and foo1() seems to be pretty much what I was
  > unsuccessfully trying to
  > do!  But why does g++ now outlaw this?  Presumably
  > the answer lies in
  > 14.6.2 of the standard, but I do not have a copy of
  > this and I can't
  > find it anywhere on the web.  Can anyone enlighten
  > me on what is happening
  > here and why this kind of access to base-class
  > members has been outlawed??
  >
  > Thanks,
  >
  > Mark.
  >
  >
  >
  > _______________________________________________
  > This is the Linux C++ Programming List
  > :
  > http://lists.linux.org.au/listinfo/tuxcpprogramming
  > List
  >





_______________________________________________________
Yahoo! Acesso Grátis - Instale o discador do Yahoo! agora.
http://br.acesso.yahoo.com/ - Internet rápida e grátis


-- __--__--

Message: 11
Date: Wed, 16 Feb 2005 11:35:59 -0700
From: Jack Lloyd <lloyd at randombit.net>
To: tuxcpprogramming at lists.linux.org.au
Subject: Re: [LC++]Why new behaviour of g++?
Reply-To: tuxcpprogramming at lists.linux.org.au

On Wed, Feb 16, 2005 at 06:47:08PM +1030, Dr Mark H Phillips wrote:
  >
  > and foo1() seems to be pretty much what I was unsuccessfully trying to
  > do!  But why does g++ now outlaw this?  Presumably the answer lies in
  > 14.6.2 of the standard, but I do not have a copy of this and I can't
  > find it anywhere on the web.

You can find a fairly late draft at
     http://people.msoe.edu/~sebern/resource/ansicpp/

The standard itself is pay-only, but the drafts were public, you can find
copies online in various places. This was the most recent I found out of the
3
or 4 I could find easily with Google.

  > Can anyone enlighten me on what is happening here and why this kind of
access
  > to base-class members has been outlawed??

No rationale is given by the standard. My guess would be it prevents some
corner cases with regards to what gets bound to an identifier inside a
template.

-Jack


-- __--__--

Message: 12
Date: Mon, 21 Feb 2005 13:53:47 +0000 (GMT)
From: choube mehul <choube_mehul at yahoo.com>
To: tuxcpprogramming at lists.linux.org.au
Subject: [LC++]warning: initialized and declared `extern'
Reply-To: tuxcpprogramming at lists.linux.org.au

Hi,

i am getting following warning

warning: `CLSID_sigSchedule' initialized and declared
`extern'

should i ignore it? or if not how to fix it?

Thanks,
Mehul.


/******* Header file -- Start *******/

#ifdef SIG_DEFINE_EXTERN_GUIDS
#define SIG_DEFINE_UUID(uuidtype, name, a, b, c, d, e,
f, g, h, i, j, k) \
          SIG_EXTERN_C const uuidtype name = \
              { a, b, c, { d, e, f, g, h, i, j, k } };
#elif defined(SIG_EXTERN_GUIDS)
#define SIG_DEFINE_UUID(uuidtype, name, a, b, c, d, e,
f, g, h, i, j, k) \
          SIG_EXTERN_C const uuidtype name;
#else
#define SIG_DEFINE_UUID(uuidtype, name, a, b, c, d, e,
f, g, h, i, j, k) \
          const uuidtype name = { a, b, c, { d, e, f, g,
h, i, j, k } };
#endif

/******* Header file -- End *******/

/******* Source file -- Start *******/

#if defined(SIG_EXTERN_GUIDS) /* { */
#undef SIG_EXTERN_GUIDS			/* This should be defined
for all files that
								   use the Scheduling Service */
#endif /* } */
#if !defined SIG_DEFINE_EXTERN_GUIDS /* { */
#define SIG_DEFINE_EXTERN_GUIDS /* This can only be
defined once */
#endif /* } */

/******* Source file -- End *******/


________________________________________________________________________
Yahoo! India Matrimony: Find your life partner online
Go to: http://yahoo.shaadi.com/india-matrimony


-- __--__--

Message: 13
From: Torsten Rennett <Torsten at Rennett.de>
Organization: Ingenieurbuero RENNETT
To: tuxcpprogramming at lists.linux.org.au
Date: Tue, 22 Feb 2005 14:54:21 +0100
Subject: Re: [LC++]Why new behaviour of g++?
Reply-To: tuxcpprogramming at lists.linux.org.au

On Mittwoch, 16. Februar 2005 09:17, Dr Mark H Phillips wrote:
  > The recent versions of g++ (in contrast to 3.3.* versions) will no
  > longer compile:
  >
  >   #include <iostream>
  >
  >   template<typename T> struct SixStore {
  >     int store; SixStore(): store(6) {}
  >   };
  >
  >   template<typename T> struct Six: public SixStore<T> {
  >     int six() {return store;}
  >   };
  >
  >   int main() {
  >     Six<char> s;
  >     std::cout<<"six = "<<s.six()<<std::endl;
  >   }
  >
  > It complains with:
  >
  >   tst3.cc: In member function `int Six<T>::six()':
  >   tst3.cc:8: error: `store' undeclared (first use this function)

Due to the latest C++ Standard, nondependent names (here: store) are
*not* looked up in dependent base classes (here: base class SixStore
depends on template parameter T of class Six).

  > If I remove the template stuff however, it compiles fine.

It also works with the template stuff, if you change the nondependent
name into a dependent one :-)  You have 2 possibilities to make 'store'
depend on 'T':

    1st solution:
	template<typename T> struct Six : public SixStore<T>
	{
	  int six() { return this->store; }
	};

    2nd solution:
	template<typename T> struct Six : public SixStore<T>
	{
	  int six() { return SixStore<T>::store; }
	};

But be aware, in the case 'store' is not a data member but a member
function (method), that the 2nd solution disables all virtual call
mechanism!


  > I had a look on the GCC website and on the page
  >
  >   http://gcc.gnu.org/bugs.html#known
  >
  > I found the following information:
  >
  >   This also affects members of base classes, see [14.6.2]:
  >                 template <typename> struct A
  >                 {
  >                     int i, j;
  >                 };
  >
  >                 template <typename T> struct B : A<T>
  >                 {
  >                     int foo1() { return i; }       // error
  >                     int foo2() { return this->i; } // OK
  >                     int foo3() { return B<T>::i; } // OK
  >                     int foo4() { return A<T>::i; } // OK
  >
  >                     using A<T>::j;
  >                     int foo5() { return j; }       // OK
  >                 };
  >
  > and foo1() seems to be pretty much what I was unsuccessfully trying to
  > do!

Yep, that's right!

  > But why does g++ now outlaw this?

Suppose you have the following slightly modified code:

      template<typename T> struct SixStore
      {
        int store;
        SixStore() : store(6) {}
      };

      template<typename T> struct Six : public SixStore<T>
      {
        void setStore(int val) { store = val; }	// point (1)
      };

      template<>              // explicit specialization
      struct SixStore<bool>
      {
        enum { store = 1 };			// point (2)
      };

      int main()
      {
        Six<bool> s;
        s.setStore(100);				// point (3)
      }


If the nondependent name ('store') would be looked up at point (1), it
would be bind to the int member of class SixStore.  After this we
declare an explicit specialization of class SixStore for the type bool,
which unfortunately changes the meaning of 'store' (point 2) -- 'store'
is no longer modifiable!  Finally we create an instance of Six<bool> at
point (3). At this point the explicit specialization is known and causes
a conflict, since we have bound 'store' too early at point (1).

To solve this conflict, the C++ Standard says that nondependent names
are *not* looked up in dependent base classes.  So a standard conforming
C++ compiler has to emit an error at point (1) -- and this is what gcc
does :-)

If we modify the code like shown above (1st + 2nd solution), the binding
will be delayed.  The dependent name can be looked up only at the time
of instantiation and at that time the exact base specialization will be
known -- and 'store' will bind correctly to the enum 'store' in class
SixStore<bool>.  This time the compiler will emit an error at point (3),
since setStore() can not modify an enum!

HTH,
Torsten

--
Ingenieurbuero RENNETT      -- innovative Software-Entwicklung --
Torsten Rennett                    http://www.RENNETT.de
Ludwig-Thoma-Weg 14         E-Mail:            Torsten at Rennett.de
D-85551 Heimstetten         Telefon:            +49 89 904 805 38


-- __--__--

Message: 14
From: Dr Mark H Phillips <mark at austrics.com.au>
To: Tux C++ Programming <tuxcpprogramming at lists.linux.org.au>
Organization: Austrics
Date: Mon, 28 Feb 2005 14:11:31 +1030
Subject: Re: [LC++]Why new behaviour of g++?
Reply-To: tuxcpprogramming at lists.linux.org.au

Thanks everyone for your feedback.  And thanks Torsten
for your explanation about why this behaviour is necessary.

Cheers,

Mark.

On Wed, 2005-02-23 at 00:24, Torsten Rennett wrote:
[snip]
  > > But why does g++ now outlaw this?
  >
  > Suppose you have the following slightly modified code:
  >
  >     template<typename T> struct SixStore
  >     {
  >       int store;
  >       SixStore() : store(6) {}
  >     };
  >
  >     template<typename T> struct Six : public SixStore<T>
  >     {
  >       void setStore(int val) { store = val; }	// point (1)
  >     };
  >
  >     template<>              // explicit specialization
  >     struct SixStore<bool>
  >     {
  >       enum { store = 1 };			// point (2)
  >     };
  >
  >     int main()
  >     {
  >       Six<bool> s;
  >       s.setStore(100);				// point (3)
  >     }
  >
  >
  > If the nondependent name ('store') would be looked up at point (1), it
  > would be bind to the int member of class SixStore.  After this we
  > declare an explicit specialization of class SixStore for the type bool,
  > which unfortunately changes the meaning of 'store' (point 2) -- 'store'
  > is no longer modifiable!  Finally we create an instance of Six<bool> at
  > point (3). At this point the explicit specialization is known and causes
  > a conflict, since we have bound 'store' too early at point (1).
  >
  > To solve this conflict, the C++ Standard says that nondependent names
  > are *not* looked up in dependent base classes.  So a standard conforming
  > C++ compiler has to emit an error at point (1) -- and this is what gcc
  > does :-)
  >
  > If we modify the code like shown above (1st + 2nd solution), the binding
  > will be delayed.  The dependent name can be looked up only at the time
  > of instantiation and at that time the exact base specialization will be
  > known -- and 'store' will bind correctly to the enum 'store' in class
  > SixStore<bool>.  This time the compiler will emit an error at point (3),
  > since setStore() can not modify an enum!
  >
  > HTH,
  > Torsten



-- __--__--

Message: 15
Date: Thu, 5 May 2005 11:49:05 +0100 (BST)
From: choube mehul <choube_mehul at yahoo.com>
To: tuxcpprogramming at lists.linux.org.au
Subject: [LC++]problem related to traits
Reply-To: tuxcpprogramming at lists.linux.org.au

Hi,
      i am getting lots of error for the following
      code.

      i am newbie to traits.

      any help will be great.

Thanks,
Mehul.

/************ Code Start **************/

#include <fstream>
#include <streambuf>
#pragma warning (pop)

template <class charT, class
traits=std::char_traits<charT> >
class debugstreambuf : public
std::basic_streambuf<charT, traits>
{
public:
    typedef charT	char_type;
    typedef std::basic_string<char_type, traits>
   LocalString;

    explicit debugstreambuf(void)
    {
    }

    ~debugstreambuf()
    {
    }

    void SetOutputTargetFileName(const LocalString&
fileName)
    {
      if (!fileName.empty())
      {
        m_LogFileName=fileName;
      }
    }

protected:
    virtual std::streamsize xsputn(const char_type* s,
std::streamsize nHowmany)
    {
      CSigGateKeeper myGuard(m_csWriteOutputLock);

      if (m_LogFile.is_open() == false)
      {
        CreateLogFile();
      }

      if (m_LogFile.good())
      {
        m_LogFile << s;
      }

#if defined(_DEBUG) && defined(_WIN32)
    OutputDebugStringA(s);
#endif
      return (nHowmany);
    }

    virtual int_type overflow(int_type c=traits::eof())
    {
      // this method is supposed to flush the put area
of the buffer
      // to the I/O device

      if (m_LogFile.is_open() == false)
      {
        CreateLogFile();
      }

      if (m_LogFile.good())
      {
        m_LogFile << (char_type)c;
      }

#if defined(_WIN32) && defined(_DEBUG)
      TCHAR achOutput[2];

      achOutput[0]=static_cast<TCHAR>(c);
      achOutput[1]='\0';

      OutputDebugString(achOutput);
#endif
      return (1);
    }

    int sync(void)
    {
      m_LogFile.flush();

      return 0;
    }

    virtual void CreateLogFile(void)
    {
      if (m_LogFileName.empty() == false)
      {
        m_LogFile.open(m_LogFileName.c_str(),
std::ios_base::out | std::ios_base::app);
      }
    }

private:
    // not for use
    debugstreambuf(const debugstreambuf&);
    debugstreambuf& operator=(const debugstreambuf&);

    LocalString  m_LogFileName;
    std::basic_ofstream<char_type,traits>	m_LogFile;
};

/************ Code End **************/

/************ Error Start **************/

s:\SigFCL_\v2.7.2.0\include\debugstreambuf.h(61) :
error C2146: syntax error : missing ';' before
identifier 'char_type'
s:\SigFCL_\v2.7.2.0\include\debugstreambuf.h(61) :
error C2868:
'std::basic_streambuf<_Elem,_Traits>::char_type' :
illegal syntax for using-declaration; expected
qualified-name
          with
          [
              _Elem=char,
              _Traits=std::char_traits<char>
          ]
s:\SigFCL_\v2.7.2.0\include\debugstreambuf.h(62) :
error C2065: 'traits' : undeclared identifier
s:\SigFCL_\v2.7.2.0\include\debugstreambuf.h(62) :
error C2955: 'std::basic_string' : use of class
template requires template argument list
          c:\Program Files\Microsoft Visual Studio .NET
2003\Vc7\include\xstring(1542) : see declaration of
'std::basic_string'
s:\SigFCL_\v2.7.2.0\include\debugstreambuf.h(62) :
error C2955: 'std::basic_string' : use of class
template requires template argument list
          c:\Program Files\Microsoft Visual Studio .NET
2003\Vc7\include\xstring(1542) : see declaration of
'std::basic_string'
s:\SigFCL_\v2.7.2.0\include\debugstreambuf.h(181) :
error C3861: 'traits': identifier not found, even with
argument-dependent lookup
s:\SigFCL_\v2.7.2.0\include\debugstreambuf.h(181) :
error C2955: 'std::basic_ofstream' : use of class
template requires template argument list
          c:\Program Files\Microsoft Visual Studio .NET
2003\Vc7\include\iosfwd(454) : see declaration of
'std::basic_ofstream'
s:\SigFCL_\v2.7.2.0\include\debugstreambuf.h(181) :
error C2955: 'std::basic_ofstream' : use of class
template requires template argument list
          c:\Program Files\Microsoft Visual Studio .NET
2003\Vc7\include\iosfwd(454) : see declaration of
'std::basic_ofstream'
s:\SigFCL_\v2.7.2.0\include\debugstreambuf.h(181) :
error C2079:
'SigFoundation::debugstreambuf::m_LogFile' uses
undefined class 'std::basic_ofstream'
s:\SigFCL_\v2.7.2.0\source\datatypes\path\path.cpp(841)
: fatal error C1903: unable to recover from previous
error(s); stopping compilation

/************ Error End **************/


________________________________________________________________________
Yahoo! India Matrimony: Find your life partner online
Go to: http://yahoo.shaadi.com/india-matrimony


-- __--__--

Message: 16
Date: Tue, 11 Oct 2005 23:02:24 +0100 (BST)
From: relan vivek <relanvivek123 at yahoo.co.in>
To: tuxcpprogramming at lists.linux.org.au
Subject: [LC++]Reader Writer Problem ............
Reply-To: tuxcpprogramming at lists.linux.org.au

Hi,
    One of the famous synchronization problems in OS is
reader-writer problem. This problem can be solved by
using semaphores. Does anyone have 'C' code for the
same?

     Thanks in advance.

     Bye.



__________________________________________________________
Yahoo! India Matrimony: Find your partner now. Go to http://yahoo.shaadi.com


-- __--__--

Message: 17
Date: Wed, 12 Oct 2005 08:45:08 +0930
From: David Lloyd <lloy0076 at adam.com.au>
To: tuxcpprogramming at lists.linux.org.au
Cc: relanvivek123 at yahoo.co.in
Subject: Re: [LC++]Reader Writer Problem ............
Reply-To: tuxcpprogramming at lists.linux.org.au


Hi There,

  >   One of the famous synchronization problems in OS is
  > reader-writer problem. This problem can be solved by
  > using semaphores. Does anyone have 'C' code for the
  > same?

Do you mean:

   * how do I use semaphores (in which case I'd suggest there'd be plenty
of examples if you looked that phrase up on google or another search
engine)?

   * how do I implement semaphores (in which case you could download the
open source Linux or FreeBSD or NetBSD or OpenBSD kernels [and others]
and look at their implementations for hints)?

DSL


-- __--__--

Message: 18
From: Dr Mark H Phillips <mark at austrics.com.au>
To: Tux C++ Programming <tuxcpprogramming at lists.linux.org.au>
Date: Tue, 25 Oct 2005 16:45:23 +0930
Subject: [LC++]Compiles with g++-3.2 but later versions flakey.  Why?
Reply-To: tuxcpprogramming at lists.linux.org.au


--=-E7gMGu9eNyCCAZ5ZeiNu
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: quoted-printable
X-MIME-Autoconverted: from 8bit to quoted-printable by
ash25e.internode.on.net id j9P7FNg7039875

Hi,

I've attached some test code below.  It compiles fine with
g++ version 3.2.3, but fails for later versions.  The strange
thing is that different versions fail in different cases.  Have
I uncovered genuine compiler bugs, or is there something else
going on?

Here's the errors I'm getting:
$ g++-3.3 testit.cc
testit.cc: In function `int main()':
testit.cc:22: error: `dummyx::dummyFunct' cannot be used as a function
$ g++-3.4 testit.cc
testit.cc: In function `int main()':
testit.cc:23: error: `dummyx::dummyFunct' cannot be used as a function
$ g++-4.0 testit.cc
testit.cc: In function =E2=80=98int main()=E2=80=99:
testit.cc:23: error: =E2=80=98dummyx::dummyFunct=E2=80=99 cannot be used =
as a function
$

Thanks,

Mark.


--=-E7gMGu9eNyCCAZ5ZeiNu
Content-Description:
Content-Disposition: inline; filename=testit.cc
Content-Type: text/x-c++src; charset=UTF-8
Content-Transfer-Encoding: 7bit

#include <iostream>

namespace dummyx {

    struct Dummy {
      Dummy() {}
    };

    struct DummyFunct {
      int operator()(Dummy d) const {return 5;}
      static DummyFunct& full() {static DummyFunct f; return f;}
    };
    static DummyFunct& dummyFunct=DummyFunct::full();

}

int main() {

    ::dummyx::Dummy const d;

    std::cout<<"(dummyx::dummyFunct)(d) =
"<<(dummyx::dummyFunct)(d)<<std::endl; // succeeds with all
    std::cout<<"dummyx::dummyFunct(d) = "<<dummyx::dummyFunct(d)<<std::endl;
// fails with 3.3
    std::cout<<"dummyFunct(d) = "<<dummyFunct(d)<<std::endl; // fails with
3.4 and 4.0

}

--=-E7gMGu9eNyCCAZ5ZeiNu--




-- __--__--

_______________________________________________
tuxCPProgramming mailing list
tuxCPProgramming at lists.linux.org.au
http://lists.linux.org.au/listinfo/tuxcpprogramming


End of tuxCPProgramming Digest




--__--__--

Message: 5
From: Dr Mark H Phillips <mark at austrics.com.au>
To: tuxcpprogramming at lists.linux.org.au
Date: Wed, 26 Oct 2005 10:45:53 +0930
Subject: Re: [LC++]Compiles with g++-3.2 but later versions flakey.  Why?
Reply-To: tuxcpprogramming at lists.linux.org.au

On Tue, 2005-10-25 at 21:49 +0200, Carlo Wood wrote:
 > I had not much time last time, lemme add some remarks now.

Thanks!

 > Obviously, the correct way to interpret dummyx::dummyFunct(d) is to first
 > evaluate dummyx::dummyFunct and then call operator()(Dummy) on it.  Thus,
 > it should do the same as (dummyx::dummyFunct)(d).

I think you're probably right, g++-3.3 has a bug here.

 > Because dummyFunct is only declared in namespace dummyx, it is not
 > declared in main(), hence, the last line should always fail.

But this doesn't take into account Koenig lookup.  "dummyFunct" is
being used as a function, so if we can't find this identifier in the
visible namespaces, we look at the namespaces of the arguments.  In this
case the argument is d, of type dummyx::Dummy, so dummyFunct should
become visible.  Which explains the following:

 > The error is a bit weird though "cannot be called as function"
 > should be "is not declared".

So obviously g++ is using Koenig to find the "dummyFunct" identifier,
but for some reason is not allowing it to be applied, even though it
is a functoid object (ie has an operator()).

If I do:

namespace dummyx {

   // as before but also include the following

   DummyFunct myDummyFunct;

}

int main() {

   ::dummyx::Dummy const d;

   std::cout<<"myDummyFunct(d) = "<<myDummyFunct(d)<<std::endl;

}

This compiles fine on everything.

So obviously there is no problem with using Koenig lookup for
functoids in general.  It appears that problems only arise when
we try to use references to such an object.

Surely this is a bug?  Or perhaps there's some obscure C++ standard
rule which disallows this?

Cheers,

Mark.




--__--__--

Message: 6
From: Dr Mark H Phillips <mark at austrics.com.au>
To: tuxcpprogramming at lists.linux.org.au
Date: Wed, 26 Oct 2005 10:49:38 +0930
Subject: Re: [LC++]Compiles with g++-3.2 but later versions flakey.  Why?
Reply-To: tuxcpprogramming at lists.linux.org.au

On Tue, 2005-10-25 at 20:54 +0100, Chris Vine wrote:
 > I should have thought they would all compile, the last because of Koenig
 > lookup.

That's what I thought.  Indeed, that's what I a relying on.  My code
worked fine on g++-3.2 but now fails on the newer versions of g++.  Very
frustrating!

 > Does it make any difference if you make dummyFunct a DummyFunct object 
rather
 > than a reference to a DummyFunct object?

Yes it does (see the email I just sent to the list).  It works fine if I
use a functoid object rather than a reference to one.

Thanks for your thoughts,

Mark.





--__--__--

_______________________________________________
tuxCPProgramming mailing list
tuxCPProgramming at lists.linux.org.au
http://lists.linux.org.au/listinfo/tuxcpprogramming


End of tuxCPProgramming Digest






More information about the tuxCPProgramming mailing list