Topic: Function Declared but not Defined


Author: "Sebastian Moleski" <smoleski@surakware.com>
Date: 2000/11/07
Raw View
If you create a Derived using new, you will have to provide a definition for
delete. The reason is that if new throws, delete will be used to get rid of
the just created object.

sm

"Wil Evers" <bouncer@dev.null> wrote in message
news:aai8u8.ln1.ln@tinus.intra.doosys.com...
> In article <8u7659$tot$1@nnrp1.deja.com>, wmm@fastdial.net wrote:
>
> > Non-pure virtual functions are always considered "used,"
> > regardless of whether they appear in an expression or not, to
> > allow for the common implementation technique of virtual function
> > tables.
>
> This makes me remember a question I asked a few years ago in this
> newsgroup, which I think is still unanswered.  If I have
>
>   struct Base {
>      virtual ~Base();
>   };
>   struct Derived : Base {
>      void operator delete(void *, size_t);
>      ~Derived();
>   };
>
> and the program doesn't delete any object whose dynamic type is
> Derived (or derived from Derived), is Derived's deallocation
> function then considered used, and am I therefore required to define
> it?
>
> - Wil
>
> --
> Wil Evers, DOOSYS IT Consultants, Maarssen, Holland
> [Wil underscore Evers at doosys dot com]
>
> ---
> [ comp.std.c++ is moderated.  To submit articles, try just posting with ]
> [ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
> [              --- Please see the FAQ before posting. ---               ]
> [ FAQ: http://www.research.att.com/~austern/csc/faq.html                ]
> [ Note that the FAQ URL has changed!  Please update your bookmarks.     ]
>


---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.research.att.com/~austern/csc/faq.html                ]
[ Note that the FAQ URL has changed!  Please update your bookmarks.     ]






Author: wmm@fastdial.net
Date: 2000/11/07
Raw View
In article <aai8u8.ln1.ln@tinus.intra.doosys.com>,
  Wil Evers <bouncer@dev.null> wrote:
> In article <8u7659$tot$1@nnrp1.deja.com>, wmm@fastdial.net wrote:
>
> > Non-pure virtual functions are always considered "used,"
> > regardless of whether they appear in an expression or not, to
> > allow for the common implementation technique of virtual function
> > tables.
>
> This makes me remember a question I asked a few years ago in this
> newsgroup, which I think is still unanswered.  If I have
>
>   struct Base {
>      virtual ~Base();
>   };
>   struct Derived : Base {
>      void operator delete(void *, size_t);
>      ~Derived();
>   };
>
> and the program doesn't delete any object whose dynamic type is
> Derived (or derived from Derived), is Derived's deallocation
> function then considered used, and am I therefore required to define
> it?

That's a good question! :-)

I think the Standard _hints_ that it must be defined, but doesn't
actually say so.  3.2p2 says that a deallocation function is used
by a delete expression appearing in a potentially-evaluated
expression and references 12.5.  12.5p4 says that, for a
polymorphic deletion, the selected deallocation function is the
one found in the lookup from the virtual destructor, described in
12.4.  12.4p11 says that the lookup of the deallocation function
occurs unconditionally at the definition of a virtual destructor,
without regard to any delete expression.

The reason for this circumlocution is to allow, but not require,
the typical implementation technique of invoking the deallocation
function from the (virtual) destructor of the most-derived class.
Of course, in implementation terms, that means that there will be
a reference from the virtual destructor (which must be defined by
virtue of its being virtual) to the deallocation function (which
will require it also to be defined).

I think 3.2p2 ought to be amended to mention the lookup in 12.4
as another "use".  I'll add this to the core language issues list.
Thanks for pointing this out.

--
William M. Miller, wmm@fastdial.net
Vignette Corporation (www.vignette.com)


Sent via Deja.com http://www.deja.com/
Before you buy.

---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.research.att.com/~austern/csc/faq.html                ]
[ Note that the FAQ URL has changed!  Please update your bookmarks.     ]






Author: "John Hickin" <hickin@nortelnetworks.com>
Date: Wed, 8 Nov 2000 00:50:54 GMT
Raw View
wmm@fastdial.net wrote:
>

>
> The reason for this circumlocution is to allow, but not require,
> the typical implementation technique of invoking the deallocation
> function from the (virtual) destructor of the most-derived class.

This begs the question: what if the destructor throws? Of course,
destructors that throw are known to cause problems, but I'm wondering
what happens in this specific case as far as the standard is concerned.
The standard must specify a behavior that neither disallows nor favours
the outlined lookup technique.

At least one compiler seems to get the following test [1] incorrect.


Regards, John.

[1] test code; lack of throw specs and use of C-style cast not
encouraged (just faster to write for an example)

#include <new>
#include <memory>
#include <iostream>

struct B { virtual ~B(){} };
struct D : B {
  bool Throw;
  D(bool Throw = false) : Throw(Throw) {}
  void* operator new( size_t );
  void operator delete( void* , size_t );
  ~D();
};

D::~D() { if ( Throw ) throw 42; }

void* D::operator new( size_t sz )
{
  D* ptr = (D*) malloc( 2*sizeof(D) );
  std::cout << "D::op new(" << sz << ") ===> " << (ptr+1) << std::endl;
  return ptr+1;
}

void D::operator delete( void* p , size_t q )
{
  std::cout << "D::op del(" << p << ',' << q << ")\n";
  D* x = ((D*)p) - 1;
  free( x );
}

int main()
{
  std::cout << "1\n" << std::flush;
  try { D d; } catch(...) {}
  std::cout << "2\n" << std::flush;
  try { delete new D; } catch(...) {}
  std::cout << "3\n" << std::flush;
  try { delete new D(true); } catch(...) {}
  std::cout << "4\n" << std::flush;
}

> a.out
1
2
D::op new(8) ===> 0x37c78
D::op del(0x37c78,8)
3
D::op new(8) ===> 0x37c78
4
>

A mild surprise is no code dump.

---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.research.att.com/~austern/csc/faq.html                ]
[ Note that the FAQ URL has changed!  Please update your bookmarks.     ]





Author: Joe Allen <joeallen@us.NOSPAMibm.com>
Date: 2000/11/06
Raw View
Does the standard allow for a function declaration to be present without
a
matching definition?  Support for this construct on pre-standard
compilers is
spotty.
--
Joe Allen

---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.research.att.com/~austern/csc/faq.html                ]
[ Note that the FAQ URL has changed!  Please update your bookmarks.     ]






Author: "Victor Bazarov" <vAbazarov@dAnai.com>
Date: 2000/11/06
Raw View
"Joe Allen" <joeallen@us.NOSPAMibm.com> wrote...
> Does the standard allow for a function declaration to be present
without
> a
> matching definition?  Support for this construct on pre-standard
> compilers is
> spotty.

Why not?  Standard headers declare a whole bunch of functions and
not all the functions are used in your program.  Besides, most of
them come from library, so the compiler doesn't get to see the
definitions at all...

Victor
--
Please remove capital A's from my address when replying by mail



---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.research.att.com/~austern/csc/faq.html                ]
[ Note that the FAQ URL has changed!  Please update your bookmarks.     ]






Author: Roger Orr <roger_orr@my-deja.com>
Date: 2000/11/06
Raw View
In article <3A070DAB.C34E09C3@us.NOSPAMibm.com>,
  Joe Allen <joeallen@us.NOSPAMibm.com> wrote:
> Does the standard allow for a function declaration to be present
without
> a
> matching definition?

The general answer is yes.

> Support for this construct on pre-standard compilers is spotty.

Give some examples and we can try give a more specific answer...

Off the top of my head I recall some compilers warning/erroring if you
give a static or anonymous function declaration without a matching
definition.  This seems fair enough to me.


Roger.

--
MVP in C++ for Brainbench at http://www.brainbench.com


Sent via Deja.com http://www.deja.com/
Before you buy.

---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.research.att.com/~austern/csc/faq.html                ]
[ Note that the FAQ URL has changed!  Please update your bookmarks.     ]






Author: wmm@fastdial.net
Date: 2000/11/06
Raw View
In article <3A070DAB.C34E09C3@us.NOSPAMibm.com>,
  Joe Allen <joeallen@us.NOSPAMibm.com> wrote:
> Does the standard allow for a function declaration to be present
without
> a
> matching definition?

Yes, as long as it is not "used" (see 3.2).  Being "used" means
appearing in an expression (other than sizeof and non-polymorphic
typeid) and (for an overloaded function) being selected by
overload resolution.

Non-pure virtual functions are always considered "used,"
regardless of whether they appear in an expression or not, to
allow for the common implementation technique of virtual function
tables.

--
William M. Miller, wmm@fastdial.net
Vignette Corporation (www.vignette.com)


Sent via Deja.com http://www.deja.com/
Before you buy.

---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.research.att.com/~austern/csc/faq.html                ]
[ Note that the FAQ URL has changed!  Please update your bookmarks.     ]






Author: comeau@panix.com (Greg Comeau)
Date: 2000/11/07
Raw View
In article <3A070DAB.C34E09C3@us.NOSPAMibm.com>,
Joe Allen  <joeallen@us.NOSPAMibm.com> wrote:
>Does the standard allow for a function declaration to be present without
>a matching definition?

Yes.

>Support for this construct on pre-standard compilers is spotty.

I don't follow.  Are you talking about virtual functions or something?

- Greg
--
Comeau Computing / Comeau C/C++ "so close" 4.2.44 betas NOW AVAILABLE
TRY Comeau C++ ONLINE at http://www.comeaucomputing.com/tryitout
Email: comeau@comeaucomputing.com / WEB: http://www.comeaucomputing.com

---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.research.att.com/~austern/csc/faq.html                ]
[ Note that the FAQ URL has changed!  Please update your bookmarks.     ]






Author: Wil Evers <bouncer@dev.null>
Date: 2000/11/07
Raw View
In article <8u7659$tot$1@nnrp1.deja.com>, wmm@fastdial.net wrote:

> Non-pure virtual functions are always considered "used,"
> regardless of whether they appear in an expression or not, to
> allow for the common implementation technique of virtual function
> tables.

This makes me remember a question I asked a few years ago in this
newsgroup, which I think is still unanswered.  If I have

  struct Base {
     virtual ~Base();
  };
  struct Derived : Base {
     void operator delete(void *, size_t);
     ~Derived();
  };

and the program doesn't delete any object whose dynamic type is
Derived (or derived from Derived), is Derived's deallocation
function then considered used, and am I therefore required to define
it?

- Wil

--
Wil Evers, DOOSYS IT Consultants, Maarssen, Holland
[Wil underscore Evers at doosys dot com]

---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.research.att.com/~austern/csc/faq.html                ]
[ Note that the FAQ URL has changed!  Please update your bookmarks.     ]