40

While compiling on GCC I get the error: pure-specifier on function-definition, but not when I compile the same code using VS2005.

class Dummy {   
  //error: pure-specifier on function-definition, VS2005 compiles 
  virtual void Process() = 0 {};
};

But when the definition of this pure virtual function is not inline, it works:

class Dummy
{
  virtual void Process() = 0;
};
void Dummy::Process()
{} //compiles on both GCC and VS2005

What does the error means? Why cannot I do it inline? Is it legal to evade the compile issue as shown in the second code sample?

Bébul
  • 575
  • 1
  • 5
  • 7

6 Answers6

40

Ok, I've just learned something. A pure virtual function must be declared as follows:


class Abstract 
{
public:
   virtual void pure_virtual() = 0;
};

It may have a body, although it is illegal to include it at the point of declaration. This means that to have a body the pure virtual function must be defined outside the class. Note that even if it has a body, the function must still be overridden by any concrete classes derived from Abstract. They would just have an option to call Abstract::pure_virtual() explicitly if they need to.

The details are here.

Dima
  • 38,860
  • 14
  • 75
  • 115
  • 2
    Yes it should, if you need one. It's perfectly legal to have one. –  Jun 01 '10 at 16:00
  • But with a body it would just be a virtual function. What should a pure virtual function with a body do??? – Martin Tilsted Jun 01 '10 at 16:04
  • 1
    @Martin Possibly nothing - if you declare a pure virtual destructor (for example) you must give it a body. –  Jun 01 '10 at 16:06
  • @MartinTilsted Not really, see http://stackoverflow.com/questions/5481941/c-pure-virtual-function-have-body. – Melebius Jan 21 '14 at 08:30
20

C++ Standard, 10.4/2:

a function declaration cannot provide both a pure-specifier and a definition

Paul
  • 13,042
  • 3
  • 41
  • 59
  • This is not normative but taken from a note. – Columbo Apr 19 '15 at 19:28
  • @Columbo Well, according to §6.5.1 of ISO/IEC Directives Part 2 notes shall not contain permissions at all. While this note clearly contains one, which mislead me. Still modern GCC and Clang don't allow this, do they violate the standard? – Paul Apr 20 '15 at 12:34
  • Protip: Read my answer. The note *is* correct, but to 'prove' this one has to show up the grammar rules. – Columbo Apr 20 '15 at 12:37
13

This syntax:

virtual void Process() = 0 {};

is not legal C++, but is supported by VC++. Exactly why the Standard disallows this has never been obvious to me. Your second example is legal.

4

Pure virtual functions in C++ by definition have no definition in the declaration.

You second code block is not avoiding the compiler issue. It is implementing a pure virtual function the way it was intended.

The question to ask is, why do you need to declare it pure virtual if you intend to have a default implementation?

Amardeep AC9MF
  • 18,464
  • 5
  • 40
  • 50
  • 2
    Pure virtual functions may have definition. Think about pure virtual destructor - it MUST be defined. – Paul Jun 01 '10 at 16:03
  • 1
    Please enlighten me with the purpose of a pure virtual destructor? – Amardeep AC9MF Jun 01 '10 at 16:06
  • 1
    You make a destructor pure when you don't want its class instantiated and there are no other PVF candidates. Quite a rare requirement, I agree. –  Jun 01 '10 at 16:10
  • 3
    > why do you need to declare it pure virtual if you intend to have a default implementation? As an author of the code in question I will answer: the default implementation is provided as a helper for derived classes. They are expected to call the default implementation, but they need to do so explicitly. This is to make sure calling default implementation is a conscious design, and not an unintended behaviour. Kind like "explicit" with conversion / construction. It does not provide any new possibilities, but it can help avoiding mistakes. – Suma Jun 01 '10 at 17:02
3

This is gramatically disallowed - the declarator that can include pure-specifiers, i.e. the member-declarator, only appears in declarations that aren't definitions. [class.mem] :

member-declaration:
         attribute-specifier-seqopt decl-specifier-seqopt member-declarator-listopt ;
         function-definition
         [...]

member-declarator-list:
         member-declarator
         member-declarator-list , member-declarator

member-declarator:
         declarator virt-specifier-seqopt pure-specifieropt
         declarator brace-or-equal-initializeropt
         identifieropt attribute-specifier-seqopt : constant-expression

The grammar of function-definition does not include a pure-specifier, [dcl.fct.def.general]:

function-definition:
     attribute-specifier-seqopt decl-specifier-seqopt declarator virt-specifier-seqopt function-body

Columbo
  • 60,038
  • 8
  • 155
  • 203
0

You can certainly provide a body for pure virtual function. That function will be pointed to by that abstract class vtable. Otherwise the same slot will point to compiler-specific trap function like __cxa_pure_virtual for GCC. There's of course nothing about this in the standard.

Nikolai Fetissov
  • 82,306
  • 11
  • 110
  • 171