Forward declare class specifying size - c++

Is it possible to forward declare a class, and actually specify its size, such that in that same header I can use the class in a class definition?
For instance something like:
class Foo = 3 * sizeof(int);
class Bar
{
Foo foo;
};
Instead of having to #include "Foo.h", where that would be something like:
class Foo
{
int a, b, c;
};
FYI: no worries, I'd never want to do something like this (hopefully), I'm just being curious.
Note that for forward declaring enum classes the above is possible, which sounds a bit similar.

No this is not possible.
Why not?
Note that the compiler needs the complete type for instantiation an object not only for knowing the size but also to know which constructors and destructors have to be used, in your example this would only be a problem if a constructor or destructor has to be generated for Bar. There may also be alignment restrictions for Foo on a given platform.
In your case the compiler may have to generate default constructor(s) and a destructor for Bar. If Foo happens to have a non-trivial constructor and/or destructor, default or explicitly specified, that must be called in those constructors/destructors.
Comments have already mentioned that for enum classes, the complete type is in fact specified sufficiently by the forward declaration: the enum cannot have a constructor or destructor and its size and alignment restrictions are also known from the underlying integer type.
I presume the decision not to allow this was made because if class definitions could be spread around in different files, ensuring consistency would make the build process more complex and different from C. Note that C++ can be linked with rather "dumb" linkers, just like C, not actually caring about types and just filling in the right addresses for symbols (I'm simplifying a bit of course).
Not checking consistency would be very risky indeed if we could specify the size of a class in one file and then forget updating it when we add a member in another. The way it is the "one-definition-rule" says basically that anything can happen if a class has more than one non-identical definition in a program.

Related

Changing struct to class (and other type changes) and ABI/code generation

It is well-established and a canonical reference question that in C++ structs and classes are pretty much interchangeable, when writing code by hand.
However, if I want to link to existing code, can I expect it to make any difference (i.e. break, nasal demons etc.) if I redeclare a struct as a class, or vice versa, in a header after the original code has been generated?
So the situation is the type was compiled as a struct (or a class), and I'm then changing the header file to the other declaration before including it in my project.
The real-world use case is that I'm auto-generating code with SWIG, which generates different output depending on whether it's given structs or classes; I need to change one to the other to get it to output the right interface.
The example is here (Irrlicht, SVertexManipulator.h) - given:
struct IVertexManipulator
{
};
I am redeclaring it mechanically as:
/*struct*/class IVertexManipulator
{public:
};
The original library compiles with the original headers, untouched. The wrapper code is generated using the modified forms, and compiled using them. The two are then linked into the same program to work together. Assume I'm using the exact same compiler for both libraries.
Is this sort of thing undefined? "Undefined", but expected to work on real-world compilers? Perfectly allowable?
Other similar changes I'm making include removing some default values from parameters (to prevent ambiguity), and removing field declarations from a couple of classes where the type is not visible to SWIG (which changes the structure of the class, but my reasoning is that the generated code should need that information, only to link to member functions). Again, how much havoc could this cause?
e.g. IGPUProgrammingServices.h:
s32 addHighLevelShaderMaterial(
const c8* vertexShaderProgram,
const c8* vertexShaderEntryPointName/*="main"*/,
E_VERTEX_SHADER_TYPE vsCompileTarget/*=EVST_VS_1_1*/,
const c8* pixelShaderProgram=0,
...
CIndexBuffer.h:
public:
//IIndexList *Indices;
...and so on like that. Other changes include replacing some template parameter types with their typedefs and removing the packed attribute from some structs. Again, it seems like there should be no problem if the altered struct declarations are never actually used in machine code (just to generate names to link to accessor functions in the main library), but is this reliably the case? Ever the case?
This is technically undefined behavior.
3.2/5:
There can be more than one definition of a class type, [... or other things that should be defined in header files ...] in a program provided that each definition appears in a different translation unit, and provided the definitions satisfy the following requirements. Given such an entity named D defined in more than one translation unit, then
each definition of D shall consist of the same sequence of tokens; and
...
... If the definitions of D satisfy all these requirements, then the program shall behave as if there were a single definition of D. If the definitions of D do not satisfy these requirements, then the behavior is undefined.
Essentially, you are changing the first token from struct to class, and inserting tokens public and : as appropriate. The Standard doesn't allow that.
But in all compilers I'm familiar with, this will be fine in practice.
Other similar changes I'm making include removing some default values from parameters (to prevent ambiguity)
This actually is formally allowed, if the declaration doesn't happen to be within a class definition. Different translation units and even different scopes within a TU can define different default function arguments. So you're probably fine there too.
Other changes include replacing some template parameter types with their typedefs
Also formally allowed outside of a class definition: two declarations of a function that use different ways of naming the same type refer to the same function.
... removing field declarations ... and removing the packed attribute from some structs
Now you're in severe danger territory, though. I'm not familiar with SWIG, but if you do this sort of thing, you'd better be darn sure the code using these "wrong" definitions never:
create or destroy an object of the class type
define a type that inherits or contains a member of the class type
use a non-static data member of the class
call an inline or template function that uses a non-static data member of the class
call a virtual member function of the class type or a derived type
try to find sizeof or alignof the class type

class names after namespace in C++

New to C++
there is a namespace i.e. and right after it a couple of class names
namespace abc {
class Cursor;
class BufferAllocator;
....
....
}
What does the above class declaration of Cursor and BufferAllocator do here?
It simply means "these classes exists" in the namespace abc, without providing any informations on their implementations.
It's called forward declarations.
It can be useful for :
Avoiding cycles in header inclusions (When class A has a member of class B, and class B has a member of class A)
Reducing dependencies between classes (because you can have a member pointer to a forward-declared class, but can't have directly a member, as the compiler doesn't know what's the size of the class without its implementation details, but know the size of a pointer). This is used notably in the Pimpl idiom.
(There might be other uses for this, but these are the most obvious that come to mind).
It's a forward declaration. It tells the following code that "there is a class called Cursor. You don't need to know what's in it [because we're only using it as a pointer or reference in the code, until it has been defined]".
Cursor and BufferAllocator are simply being forward-declared in their namespace (so they can be used in pointer/reference contexts).
It's a forward declaration. It can be used to inform the compiler of the existence of types when you're only going to use a pointer or reference to that type. The size of a pointer or reference is invariant of the type that it refers to, so the compiler doesn't need to see the entire definition of the type in that case; it just needs to know that the type exists first.
This can be useful in cases where the header that normally declares the type is large (think headers that include a lot of declarations or template instantiations), in which case it can decrease your compile times (sometimes significantly). You can just forward-declare the type and skip including the header, so your compiler doesn't need to process it.
namespace are helpful in a way they avoid typing particular classname in front of every function.
As you are new you will mostly see using namespace std;
so now you can use cout directly if you do not use this statement then you have to write std::cout for every use of cout
hope this helps

Forward declaration of a class in a namespace

How can i forward declare a class in a namespace. For example below is a header file of a library and user dont need to know about private myPtr so dont need to include boost headers when include below header file. So how can I forward declare the boost::shared_ptr to enable user code compilation?
MyClass.h
class MyClass
{
private:
boost::shared_ptr<Mytype> myPtr;
}
TL;DR The inclusion of <boost/shared_ptr.hpp> is required here. No (intelligent) way around it. MyType itself can be forward-declared though.
Of course, you can just write #include <boost/shared_ptr.hpp> at the top of your header so your users don't have to do it themselves. It's actually good practice to provide autonomous headers (ie headers that can be included first without errors).
The rules about forward compilation are slightly complicated. It is easier to understand the reason about them than to try and memorize all the cases.
There are two factors:
semantics
memory attributes (size & alignment)
Semantics: in order to access the objects' methods, attributes or base classes, you need to know about them. Seems obvious, of course, except that the constructors, assignment operators and destructors, even when automatically generated, are methods. It is easy to forget about them.
Memory attributes: unlike most languages, C++ tries to be as efficient as possible, which means that it will allocate memory for the object right there rather than allocate it somewhere and just use a pointer at the point of use, unless you instruct it to do so of course (by using either pointer or reference). In order to know how much to allocate, the compiler needs to see the guts of the object, ie what's underneath the hood. This means that even though the exact details are not accessible (private/protected stuff) they need be visible so it can see that 24 bytes aligned on a 8-bytes boundary are required (not relevant to shared_ptr by the way).
In the Standard we say the object's definition is required for either of those two needs (methods and memory layout). If the definition is required, then it must be available obviously.
Okay, now that we know the reasons, we can check various things. Is a definition needed when:
using an object as argument to sizeof or alignof? yes (obviously, memory attributes required)
using an object as attribute? yes (memory attributes required)
using an object as static attribute? no (1)
using a pointer or reference to an object as attribute? no (2)
using an object as an argument in a function declaration? no (3)
using an object as a return type in a function declaration? no (3)
passing a pointer or reference to an object around? no (4)
casting to base class? yes (semantic check of presence & accessibility of base class)
converting to another type? depends (5)
(1) the declaration does not require anything, however the definition of the static attribute will require the object's definition.
(2) a pointer is either 32 bits or 64 bits large (depending on how you compile, ...) independently of the object. A reference has an implementation-defined representation.
(3) even if taken/returned by value! It may be required for the function definition (if used within) or the function call site though.
(4) of course, should you try to use it (p->foo() or p.foo()) then it's another story.
(5) if you need to use the object's conversion operators, then it's required obviously; otherwise if you use a constructor of the other type then the same rules as for functions apply (the other type definition is required though).
I hope things are clearer now.

Why doesn't C++ need forward declarations for class members?

I was under the impression that everything in C++ must be declared before being used.
In fact, I remember reading that this is the reason why the use of auto in return types is not valid C++0x without something like decltype: the compiler must know the declared type before evaluating the function body.
Imagine my surprise when I noticed (after a long time) that the following code is in fact perfectly legal:
[Edit: Changed example.]
class Foo
{
Foo(int x = y);
static const int y = 5;
};
So now I don't understand:
Why doesn't the compiler require a forward declaration inside classes, when it requires them in other places?
The standard says (section 3.3.7):
The potential scope of a name declared in a class consists not only of the declarative region following the name’s point of declaration, but also of all function bodies, brace-or-equal-initializers of non-static data members, and default arguments in that class (including such things in nested classes).
This is probably accomplished by delaying processing bodies of inline member functions until after parsing the entire class definition.
Function definitions within the class body are treated as if they were actually defined after the class has been defined. So your code is equivalent to:
class Foo
{
Foo();
int x, *p;
};
inline Foo::Foo() { p = &x; }
Actually, I think you need to reverse the question to understand it.
Why does C++ require forward declaration ?
Because of the way C++ works (include files, not modules), it would otherwise need to wait for the whole Translation Unit before being able to assess, for sure, what the functions are. There are several downsides here:
compilation time would take yet another hit
it would be nigh impossible to provide any guarantee for code in headers, since any introduction of a later function could invalidate it all
Why is a class different ?
A class is by definition contained. It's a small unit (or should be...). Therefore:
there is little compilation time issue, you can wait until the class end to start analyzing
there is no risk of dependency hell, since all dependencies are clearly identified and isolated
Therefore we can eschew this annoying forward-declaration rule for classes.
Just guessing: the compiler saves the body of the function and doesn't actually process it until the class declaration is complete.
unlike a namespace, a class' scope cannot be reopened. it is bound.
imagine implementing a class in a header if everything needed to be declared in advance. i presume that since it is bound, it was more logical to write the language as it is, rather than requiring the user to write forwards in the class (or requiring definitions separate from declarations).

Unions as Base Class

The standard defines that Unions cannot be used as Base class, but is there any specific reasoning for this? As far as I understand Unions can have constructors, destructors, also member variables, and methods to operate on those varibales. In short a Union can encapsulate a datatype and state which might be accessed through member functions. Thus it in most common terms qualifies for being a class and if it can act as a class then why is it restricted from acting as a base class?
Edit: Though the answers try to explain the reasoning I still do not understand how Union as a Derived class is worst than when Union as just a class. So in hope of getting more concrete answer and reasoning I will push this one for a bounty. No offence to the already posted answers, Thanks for those!
Tony Park gave an answer which is pretty close to the truth. The C++ committee basically didn't think it was worth the effort to make unions a strong part of C++, similarly to the treatment of arrays as legacy stuff we had to inherit from C but didn't really want.
Unions have problems: if we allow non-POD types in unions, how do they get constructed? It can certainly be done, but not necessarily safely, and any consideration would require committee resources. And the final result would be less than satisfactory, because what is really required in a sane language is discriminated unions, and bare C unions could never be elevated to discriminated unions in way compatible with C (that I can imagine, anyhow).
To elaborate on the technical issues: since you can wrap a POD-component only union in a struct without losing anything, there's no advantage allowing unions as bases. With POD-only union components, there's no problem with explicit constructors simply assigning one of the components, nor with using a bitblit (memcpy) for compiler generated copy constructor (or assignment).
Such unions, however, aren't useful enough to bother with except to retain them so existing C code can be considered valid C++. These POD-only unions are broken in C++ because they fail to retain a vital invariant they possess in C: any data type can be used as a component type.
To make unions useful, we must allow constructable types as members. This is significant because it is not acceptable to merely assign a component in a constructor body, either of the union itself, or any enclosing struct: you cannot, for example, assign a string to an uninitialised string component.
It follows one must invent some rules for initialising union component with mem-initialisers, for example:
union X { string a; string b; X(string q) : a(q) {} };
But now the question is: what is the rule? Normally the rule is you must initialise every member and base of a class, if you do not do so explicitly, the default constructor is used for the remainder, and if one type which is not explicitly initialised does not have a default constructor, it's an error [Exception: copy constructors, the default is the member copy constructor].
Clearly this rule can't work for unions: the rule has to be instead: if the union has at least one non-POD member, you must explicitly initialise exactly one member in a constructor. In this case, no default constructor, copy constructor, assignment operator, or destructor will be generated and if any of these members are actually used, they must be explicitly supplied.
So now the question becomes: how would you write, say, a copy constructor? It is, of course quite possible to do and get right if you design your union the way, say, X-Windows event unions are designed: with the discriminant tag in each component, but you will have to use placement operator new to do it, and you will have to break the rule I wrote above which appeared at first glance to be correct!
What about default constructor? If you don't have one of those, you can't declare an uninitialised variable.
There are other cases where you can determine the component externally and use placement new to manage a union externally, but that isn't a copy constructor. The fact is, if you have N components you'd need N constructors, and C++ has a broken idea that constructors use the class name, which leaves you rather short of names and forces you to use phantom types to allow overloading to choose the right constructor .. and you can't do that for the copy constructor since its signature is fixed.
Ok, so are there alternatives? Probably, yes, but they're not so easy to dream up, and harder to convince over 100 people that it's worthwhile to think about in a three day meeting crammed with other issues.
It is a pity the committee did not implement the rule above: unions are mandatory for aligning arbitrary data and external management of the components is not really that hard to do manually, and trivial and completely safe when the code is generated by a suitable algorithm, in other words, the rule is mandatory if you want to use C++ as a compiler target language and still generate readable, portable code. Such unions with constructable members have many uses but the most important one is to represent the stack frame of a function containing nested blocks: each block has local data in a struct, and each struct is a union component, there is no need for any constructors or such, the compiler will just use placement new. The union provides alignment and size, and cast free component access.
[And there is no other conforming way to get the right alignment!]
Therefore the answer to your question is: you're asking the wrong question. There's no advantage to POD-only unions being bases, and they certainly can't be derived classes because then they wouldn't be PODs. To make them useful, some time is required to understand why one should follow the principle used everywhere else in C++: missing bits aren't an error unless you try to use them.
Union is a type that can be used as any one of its members depending on which member has been set - only that member can be later read.
When you derive from a type the derived type inherits the base type - the derived type can be used wherever the base type could be. If you could derive from a union the derived class could be used (not implicitly, but explicitly through naming the member) wherever any of the union members could be used, but among those members only one member could be legally accessed. The problem is the data on which member has been set is not stored in the union.
To avoid this subtle yet dangerous contradiction that in fact subverts a type system deriving from a union is not allowed.
Bjarne Stroustrup said 'there seems little reason for it' in The Annotated C++ Reference Manual.
The title asks why unions can't be a base class, but the question appears to be about unions as a derived class. So, which is it?
There's no technical reason why unions can't be a base class; it's just not allowed. A reasonable interpretation would be to think of the union as a struct whose members happen to potentially overlap in memory, and consider the derived class as a class that inherits from this (rather odd) struct. If you need that functionality, you can usually persuade most compilers to accept an anonymous union as a member of a struct. Here's an example, that's suitable for use as a base class. (And there's an anonymous struct in the union for good measure.)
struct V3 {
union {
struct {
float x,y,z;
};
float f[3];
};
};
The rationale for unions as a derived class is probably simpler: the result wouldn't be a union. Unions would have to be the union of all their members, and all of their bases. That's fair enough, and might open up some interesting template possibilities, but you'd have a number of limitations (all bases and members would have to be POD -- and would you be able to inherit twice, because a derived type is inherently non-POD?), this type of inheritance would be different from the other type the language sports (OK, not that this has stopped C++ before) and it's sort of redundant anyway -- the existing union functionality would do just as well.
Stroustrup says this in the D&E book:
As with void *, programmers should know that unions ... are inherently dangerous, should be avoided wherever possible, and should be handled with special care when actually needed.
(The elision doesn't change the meaning.)
So I imagine the decision is arbitrary, and he just saw no reason to change the union functionality (it works fine as-is with the C subset of C++), and so didn't design any integration with the new C++ features. And when the wind changed, it got stuck that way.
I think you got the answer yourself in your comments on EJP's answer.
I think unions are only included in C++ at all in order to be backwards compatible with C. I guess unions seemed like a good idea in 1970, on systems with tiny memory spaces. By the time C++ came along I imagine unions were already looking less useful.
Given that unions are pretty dangerous anyway, and not terribly useful, the vast new opportunities for creating bugs that inheriting from unions would create probably just didn't seem like a good idea :-)
Here's my guess for C++ 03.
As per $9.5/1, In C++ 03, Unions can not have virtual functions. The whole point of a meaningful derivation is to be able to override behaviors in the derived class. If a union cannot have virtual functions, that means that there is no point in deriving from a union.
Hence the rule.
You can inherit the data layout of a union using the anonymous union feature from C++11.
#include <cstddef>
template <size_t N,typename T>
struct VecData {
union {
struct {
float x;
float y;
float z;
};
float a[N];
};
};
template <size_t N, typename T>
class Vec : public VecData<N,T> {
//methods..
};
In general its almost always better not work with unions directly but enclose them within a struct or class. Then you can base your inheritance off the struct outer layer and use unions within if you need to.