• Announcements

    • khawk

      Download the Game Design and Indie Game Marketing Freebook   07/19/17

      GameDev.net and CRC Press have teamed up to bring a free ebook of content curated from top titles published by CRC Press. The freebook, Practices of Game Design & Indie Game Marketing, includes chapters from The Art of Game Design: A Book of Lenses, A Practical Guide to Indie Game Marketing, and An Architectural Approach to Level Design. The GameDev.net FreeBook is relevant to game designers, developers, and those interested in learning more about the challenges in game development. We know game development can be a tough discipline and business, so we picked several chapters from CRC Press titles that we thought would be of interest to you, the GameDev.net audience, in your journey to design, develop, and market your next game. The free ebook is available through CRC Press by clicking here. The Curated Books The Art of Game Design: A Book of Lenses, Second Edition, by Jesse Schell Presents 100+ sets of questions, or different lenses, for viewing a game’s design, encompassing diverse fields such as psychology, architecture, music, film, software engineering, theme park design, mathematics, anthropology, and more. Written by one of the world's top game designers, this book describes the deepest and most fundamental principles of game design, demonstrating how tactics used in board, card, and athletic games also work in video games. It provides practical instruction on creating world-class games that will be played again and again. View it here. A Practical Guide to Indie Game Marketing, by Joel Dreskin Marketing is an essential but too frequently overlooked or minimized component of the release plan for indie games. A Practical Guide to Indie Game Marketing provides you with the tools needed to build visibility and sell your indie games. With special focus on those developers with small budgets and limited staff and resources, this book is packed with tangible recommendations and techniques that you can put to use immediately. As a seasoned professional of the indie game arena, author Joel Dreskin gives you insight into practical, real-world experiences of marketing numerous successful games and also provides stories of the failures. View it here. An Architectural Approach to Level Design This is one of the first books to integrate architectural and spatial design theory with the field of level design. The book presents architectural techniques and theories for level designers to use in their own work. It connects architecture and level design in different ways that address the practical elements of how designers construct space and the experiential elements of how and why humans interact with this space. Throughout the text, readers learn skills for spatial layout, evoking emotion through gamespaces, and creating better levels through architectural theory. View it here. Learn more and download the ebook by clicking here. Did you know? GameDev.net and CRC Press also recently teamed up to bring GDNet+ Members up to a 20% discount on all CRC Press books. Learn more about this and other benefits here.
Sign in to follow this  
Followers 0
Norman Barrows

c++ oo syntax behind the scenes behavior

22 posts in this topic

if i declare a class, then declare an instance of that class, when is the instance allocated on the heap (assuming it has member variables) ?

 

where is the VMT stored, and when ?

 

and there's just one VMT per class, right?

 

non virtual method calls require no vmt lookup, correct?

 

 

 

 

0

Share this post


Link to post
Share on other sites

I think you're confusing a pointer to the vtable and the vtable itself. An object will store a pointer to the vtable not the full table. The vtables themselves are generally stored in a read only data segment. 

Yep, already edited my post. I should remember to hold off on posting in the morning until after breakfast. laugh.png

0

Share this post


Link to post
Share on other sites


The instance is allocated on the heap when you call new (or malloc() or another similar func). No sooner, no later.

 

what about something like:

 

class myclass
etc
 
 
 
void main
{
myclass object1;   // declare an instance of a myclass object called object1
etc
}
 

 

note that my syntax may be off a bit there, but i think you get the type of declaration i'm talking about.

 

that would get allocated when main was called, right?

 

but something like....

 

 
class myclass
etc
 
myclass object1;   // declare an instance of a myclass object called object1, global to everything that follows in the module.
 
 
void main
{
etc
}
 
0

Share this post


Link to post
Share on other sites


When you define/instantiate an instance of a class on the stack, the memory is guaranteed to be allocated when you need it.
ClassName instance; // Memory is allocated on the stack here
instance.doSomething();

 

fascinating! i thought local declarations did a new in the background and a dispose on return, using the heap.

 

so locally declared objects go on the stack. that would imply no memory leaks possible, correct?

0

Share this post


Link to post
Share on other sites


This sort of thing shows up as a problem if, for example, you add a virtual function to a header file and rebuild a program, but do not rebuild a DLL that also uses the header file.  Bam!

 

the classic code and header out of sync explosion!

0

Share this post


Link to post
Share on other sites

based on the above posts, given:

 

 
class myclass
etc
 
void main
{
myclass object1;
}
 

 

would object1 go on the stack when main was called? or is main a special case and it goes in the data segment?

 

also, i takes it that given:

 

 
class myclass
etc
 
myclass object1;  // global to code that follows in this module
 
void main
{
etc
}
 
 

 

 

object1 (its member var storage space) would go in the data segment?

0

Share this post


Link to post
Share on other sites


 
Quote
non virtual method calls require no vmt lookup, correct?
Yes. And if the class itself has zero virtual functions, then it won't have any Virtual Method Table.

 

 

 

I think you're confusing a pointer to the vtable and the vtable itself. An object will store a pointer to the vtable not the full table. The vtables themselves are generally stored in a read only data segment. 

Yep, already edited my post. I should remember to hold off on posting in the morning until after breakfast. laugh.png

 

 

all this seems to imply that all method calls require dereferencing the object's vmt pointer to get the jump address of the actual method to use. i thought non-virtual methods had their jump addresses stored in the objects, to avoid the derferencing overhead.

 

so all method calls become: gosub vmt_ptr->method->address ?  

 

IE gosub to the address of <method> stored in the vmt pointed to by vmt_ptr ?

 

for non-virtual, I thought it was more like: gosub instance.method_address[method]

 

and a stand alone function, by comparison is simply: gosub method_address, correct?  

0

Share this post


Link to post
Share on other sites
[quote]fascinating! i thought local declarations did a new in the background and a dispose on return, using the heap.[/quote] Things only go on the heap if they are explicitly allocated, either directly or indirectly. If the object you create on the stack uses allocation with new, then that data would go on the heap. The pointer to that data would be on the stack. If the object you created was on the heap then both the pointer and the other data would both go on the heap. Its basically recursive. Say you created an object on the heap and called a member function. If that member function has local variables then they would be pushed onto the stack even though the object itself was allocated on the heap. This is due to the way the compiler treats executable code.

would object1 go on the stack when main was called? or is main a special case and it goes in the data segment?
main is exactly like any other function except it is called by the operating system rather than your program.

object1 (its member var storage space) would go in the data segment?
That would go in the data segment. While I said that main is a special case, it's slightly more complicated than I implied. main is actually called indirectly by the operating system in most environments. The operating system will generally call a function implemented in the run-time library. You can read a little about it here. That link mentions that the run-time library will initialize global variables before main is called. If the operating system called main directly then none of the constructors for the global variables would be called, among other things.
1

Share this post


Link to post
Share on other sites


A non-virtual member function and a stand-alone function are pretty much the same thing. The method address is known after linking.

 

ok, so the vmt addresses replace the non-virtual method calls at link time, correct?

 

i _thought_ they were the same thing....

0

Share this post


Link to post
Share on other sites

Things only go on the heap if they are explicitly allocated, either directly or indirectly.

 

i was under the impression that all were allocated on the heap, except global instances, which were allocated in the data segment at load time.

 

thanks for clarifying that. (lending a machete to my intellectual thicket).

 

and locally declared instances, being allocated on the heap, are automatically de-allocated when they go out of scope. and they don't use the heap so no possibility of memory leak. just the usual cross your i's and dot your t's stuff with malloc and free under different names (new and dispose) - correct?

Edited by Norman Barrows
0

Share this post


Link to post
Share on other sites

 

would object1 go on the stack when main was called? or is main a special case and it goes in the data segment?
main is exactly like any other function except it is called by the operating system rather than your program.

Almost. You cannot legally call main from your program in c++. This design was because the compiler may wish to insert additional setup code at the beginning of main.

2

Share this post


Link to post
Share on other sites
class MyClass; //Declare a class. Nothing created yet.

int main()
{
    MyClass *instance = new MyClass; //An instance created on the heap.

    MyClass instance; //An instance created on the stack.
}

If declared on the stack, the class is constructed when the code calls that function and the function reaches that line of code. Whether or not they are allocated before the function is called I *think* might be up to the compiler.

 

The above has to do with variables created inside functions.

 

If a variable is global, or if a variable is a static member-variable of a class (which is just a global variable in the class's namespace), then you can't count on the order or timing of when they are constructed. The only thing you can depend on is that they'll be constructed before int main() enters... but other than that, the order is compiler-specific.

 

This is one of the reasons why programmers avoid global variables in C++. I've dealt with, in my own code, far too many bugs caused by global variables.

 

Global variables are a convenience, but they end up hurting more than they help. Global constants are usually fine though.

1

Share this post


Link to post
Share on other sites


If a variable is global, or if a variable is a static member-variable of a class (which is just a global variable in the class's namespace), then you can't count on the order or timing of when they are constructed. The only thing you can depend on is that they'll be constructed before int main() enters... but other than that, the order is compiler-specific.

 

right, startup code constructor hell. you can't rely on other globals being valid during your custom constructor. i hear about this a fair amount. i would think an explicit init() would take care of it. bad form?

0

Share this post


Link to post
Share on other sites

If a variable is global, or if a variable is a static member-variable of a class (which is just a global variable in the class's namespace), then you can't count on the order or timing of when they are constructed. The only thing you can depend on is that they'll be constructed before int main() enters... but other than that, the order is compiler-specific.

 
right, startup code constructor hell. you can't rely on other globals being valid during your custom constructor. i hear about this a fair amount. i would think an explicit init() would take care of it. bad form?
Very bad.

I once had the misfortune of working on a port that severely abused global variables.

It took so long to run the pre-main initialization that we could not pass certification as-is. We had to hack in to the runtime and display the splash screen. Rather than the normal sleep while a splash was running, it spent those seconds initializing variables and doing other pre-main work.

IIRC it took something like five seconds between execution start and the beginning of main.

Just don't start down that road. It is a horrible thing.
0

Share this post


Link to post
Share on other sites

except global instances, which were allocated in the data segment at load time.

 

It depends on the compiler you use, but generally yes, a global object will exist in the data segment, specifically in the bss section if it is a basic datatype or a structure containing basic datatypes. This isn't written in stone, though, and it's possible for it to also be allocated on the heap, or even on the stack.

Edited by TheComet
0

Share this post


Link to post
Share on other sites


It took so long to run the pre-main initialization that we could not pass certification as-is. We had to hack in to the runtime and display the splash screen. Rather than the normal sleep while a splash was running, it spent those seconds initializing variables and doing other pre-main work.

 

OMG! LOL!

 

so it had a ton of global instances with custom constructor code that took many seconds before you got control in main() ? <g>

 

i had to "hack in" a loading splash screen for caveman too. the game does a one time load of all assets at program start, about 10-20 seconds - after that, no load screens whatsoever. when i switched from d3dx fonts to a custom font using d3dx sprites for speed, i found i no longer had a font available for loading progress messages. i had to temporarily load in a splash screen. the only non sequential vidram allocation in the whole game. and its the first one!  i really should fix that. make it texture #0, the first texture loaded, and move texture #0 (grass tile #1) to the end of the list. but then i have a 1024x1024 sitting at the base of graphics ram the whole game for no reason. but right now, it loads the splash screen, then it loads everything else, then frees the splash screen. so i have nice contiguous ram, with a 1024x1024 hole at the start! <g>.

Edited by Norman Barrows
0

Share this post


Link to post
Share on other sites

If a variable is global, or if a variable is a static member-variable of a class (which is just a global variable in the class's namespace), then you can't count on the order or timing of when they are constructed. The only thing you can depend on is that they'll be constructed before int main() enters... but other than that, the order is compiler-specific.

You can't count on the initialization of globals defined in different translation units. Globals defined in the same translation unit are well defined to initialize in the order they are found. Not that that helps much.

2

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!


Register a new account

Sign in

Already have an account? Sign in here.


Sign In Now
Sign in to follow this  
Followers 0