What does "class classname* funcname(void) "mean in C++?

Viewed 2536

I found the following code in a header file and the "BOOT" class is defined in another header file.

class BOOT* boot(void);

It looks like a declaration of a function, but it begins with class.

4 Answers

This is an elaborated type specifier:

Elaborated type specifiers may be used to refer to a previously-declared class name (class, struct, or union) or to a previously-declared enum name even if the name was hidden by a non-type declaration. They may also be used to declare new class names.

https://en.cppreference.com/w/cpp/language/elaborated_type_specifier

Taking from answers of Artefacto and dfrib because it brings it on point: It is equivalent to:

class BOOT;
BOOT* boot(void);

In your example it essentially does a forward declaration of the class BOOT if it is not known yet. See this example struct Data* Data; from the same page:

struct Node {
    struct Node* Next; // OK: lookup of Node finds the injected-class-name
    struct Data* Data; // OK: declares type Data at global scope
                       // and also declares the data member Data
    friend class ::List; // error: cannot introduce a qualified name
    enum Kind* kind; // error: cannot introduce an enum
};
 
Data* p; // OK: struct Data has been declared

It is the same as this:

class BOOT;
BOOT* boot(void);

So it's a pointer to class BOOT, but with a declaration of the class as well. The class need not be defined at this point.

What does “class classname* funcname(void) ”mean in C++?

It is a function declaration.

It looks like a declaration of a function, but it begins with "class".

class classname* is the return type of the function. class classname is an elaborated type specifier.

Different forms of forward declarations used to introduce class-name:s into its scope

In C++ you may declare a function type whose return type contains a class type that is defined elsewhere, as long as you either explicitly forward declare the class type prior to the function declaration:

class BOOT;
BOOT* boot();

but you may likewise place the forward declaration in-line in the function declaration:

class BOOT* boot();

This is one of the places where, possibly somewhat unexpectedly, forward declarations can be used. Another example is as in the template argument list for a type-template parameter:

template<typename T>
struct Identity { using type = T; };

using IdentityBoot = Identity<struct BOOT>;
//                            ^^^^^^^^^^^ also a forward declaration

// OK
BOOT* boot();

// OK
typename IdentityBoot::type* another_boot();

Elaborated type specifiers can be used to introduce names into its scope

Formally, it's an elaborated-type-specifier, governed by [dcl.type.elab],

elaborated-type-specifier:
    class-key [...]
    [...]

that is used to, as per [class]/1, make a class-name that is introduced into the scope where the elaborated-type-specifier is used [emphasis mine]:

A class is a type. Its name becomes a class-name ([class.name]) within its scope. [...]

Class-specifiers and elaborated-type-specifiers are used to make class-names.

Related