Splitting a program up

If you are a new Irrlicht Engine user, and have a newbie-question, this is the forum for you. You may also post general programming questions here.
Post Reply
wizard4
Posts: 183
Joined: Thu Jan 25, 2024 6:54 pm
Location: UK

Splitting a program up

Post by wizard4 »

I think I'll say what I need first, and that might be wrong.

In main.cpp where irrlicht.h is included, I wanted irrlicht stuff to stay in main. I wanted date to be in date, and calendar to be in calendar.

I'm adding a gui table with an event from the examples and I wanted calendar.cpp to handle the set up, but it needs irrlicht stuff. Irrlicht was meant to stay in main.

I can't pass SContext from main.cpp to calendar.cpp without it. I made a calendar.h that includes irrlicht.h and printCalendar().

Am I going about it the right way? There are ifdef guards, but I'd be unnecessarily adding headers without understanding.
CuteAlien
Admin
Posts: 9935
Joined: Mon Mar 06, 2006 2:25 pm
Location: Tübingen, Germany
Contact:

Re: Splitting a program up

Post by CuteAlien »

If it compiles and links it's probably the right way ;-)

So in short: Yes - use ifdef guards. And in general each header should include those headers it will need to compile. And one class per file is also good way to split up the program. Usually with class declaration in the header and implementation in the .cpp file.


Slightly longer: Inside headers you will often work with forward declarations instead of including other headers. You can use forward declarations if you don't work with a type but instead only use a pointer or reference to a type. And sometimes you will _need_ to work with forward declarations because if you have 2 types (lets call them class A and class B) which each need the other internally then there is no other solution. One will need to use a pointer and the type of that pointer will have to be forward declared first.


And there is a very long answer, which I probably wrote down in the forum before, so might repeat myself here. So if you want to know about _why_ it works as it does continue reading, otherwise you can stop here ;-)

The first thing you have to know is that #include commands are basically copy-pasting everything in the header file to replace the include command itself. So Visual Studio silently first runs a preprocessor (also called precompiler) which does that copy-pasting. Afterwards the compiler works only with the now huge merged files (which it copies internally, it won't change your original .cpp files). And then those files are compiled into object files (.o).

And that is the reason for header guards. Precompiler does one more thing besides copy-pasting - it also resolves all other preprocessor commands first (everything starting with # like #ifdef and #pragma). Without header guards if you had two header files which both include for example irrlicht.h you would end up having irrlicht.h pasted into the same cpp file twice. Or more than twice, depending on how many times you do that. And the compiler really doesn't like to have the same info several times.

Next thing you should know is that each .cpp file needs enough information to be able to compile. And one of the infos the compiler needs to know is about types. A type can be a base type like char, int, float, double (I might have forgotten some). It can be a pointer (to any other type) or a reference (to any other type). And in c++ it can also be an aggregate type (a struct or a class) which puts together several other types into a single new one.

And what the compiler really, really needs to know about types is their size! How many bits a variable of that type will need in memory. Like 'char' will need 8 bits and 'int' may need 32 bits (on most platforms these days). And every pointer (no matter to which type) will have the same size which depends on your target platform (usually 64 bit these days, but for example 32 bit if you compile for 32 bit platforms). The compiler already knows the sizes for those built-in types. But it needs that info also for the user defined types (structs/classes) where the size depends on the sum of all the variables inside. So to calculate that sum it needs the class declaration with all the variables inside.

You can never use a type - like for creating a variable - before the compiler knows about it. And _before_ literally means the type has to be declared _above_ the line where you use it the first time. Because the compiler always goes through the cpp from top to the bottom of the file exactly once. This can be different in other programming languages which may for example just say: Hey I see an unknown type, let's wait if I can find that one later in the file. But, nope - not in c/c++! You use a type in one line you must tell the compiler about it first!

And that's basically what headers are used for - you give the compiler enough information to know the name and size of types. So every .cpp file using a type just has to include a header declaring it first.

Meanwhile forward declarations are telling the compiler just the name - without the size. Which means you still can't use that type. But you can already create pointer variables because the compiler knows that each pointer has the same size. Thought you still have to include the header for the real size information later before you actually create that object (with new) or use it. So forward declarations have 2 uses:
a) They allow 2 classes to refer to each other. Because the compiler always needs to know types before using them it wouldn't be possible otherwise as one type has to be declared "first" (above the other - they can't be both at the top of the file). But you can say first "that class exists, I just don't know it's size yet". That's the forward declaration. And then you can use a pointer to it. As the compiler knows the pointer size (64-bit), it has no problem with that. So both classes can work now with pointers to each other in their header without having to include the other header. And later you include the full header in the cpp file (cpp itself has no header guard so it can include both headers). And then from that point on the compiler knows the real sizes of the types and can use them in the cpp file completely.
b) Forward declarations are also good because they sometimes allow your cpp files to become smaller (after the precompiler run). Don't worry about this for now, I already wrote too much ;-) Just keep in mind - using forward declarations instead of includes inside headers is generally a good thing, which is why you will see that lot when you read other people's code. Often when people work with pointers they will use forward declarations inside headers instead of including other headers. And then users will have to include all headers in the .cpp file (or have one header file including all others - irrlicht.h is doing that which is why you only ever need that one include and not all other Irrlicht headers).

Sorry, info overkill probably, hope there was something useful in there ;-) (edit: Also I reworked this answer a few times, so don't be surprised if the text in here changes)
IRC: #irrlicht on irc.libera.chat
Code snippet repository: https://github.com/mzeilfelder/irr-playground-micha
Free racer made with Irrlicht: http://www.irrgheist.com/hcraftsource.htm
Noiecity
Posts: 324
Joined: Wed Aug 23, 2023 7:22 pm
Contact:

Re: Splitting a program up

Post by Noiecity »

Interesting, I was also taking with the subject of headers and separating the files, there are important things that are difficult to find in books, I think what cutealien explains is in fact, something essential to start, and at the same time not.

With this I want to say that c++ is not an easy book to introduce, let's say that you have many introductions, and all of them are necessary, and as you say, there are languages that for example, if you write a function at the end you can use it at the beginning, in c++ not.

It is also worth mentioning that the compiler does an excellent job in producing the compiled file, most of the time the assembly code is practically unbeatable (MSVC versions were not as pro in its early days as mingw, but it was almost at the same level in terms of final performance).

I recently learned that in c++98 the word auto was used in a different way than now (now it is gone), it was a keyword that seems to have the purpose of letting people know that when declaring a variable (like int anumber;) this by default uses a stack memory that allocates the memory automatically, so in c++98 you could write "auto int anumber; "to identify that int is auto (which is redundant since just writing int anumber makes it auto), although it is still useful since it helps to let you know that you can manually allocate variables to memory yourself under other conditions, it is also ironic since modern versions auto is totally different except for automating something (the type of variable).

C++98 was developed for more than 10 years by many people, apart from its creator, before being released.


I was trying to write a c++ book, since I learn more if I am teaching things and realizing what I don't know, and it starts like this:
"What is c++98?

C++98 is a version of the C++ programming language that was released in 1998.

Bjarne Stroustrup, a researcher at Bell Labs, developed c++ based on "C", another programming language. Initially in 1979 c++ was called "C with Classes", it was renamed to c++ in 1983.

In its early days there were compatibility problems, especially in the early days of c++ (and many other programming languages). Each processor architecture had its own instruction set assembly. C++ compilers had to generate architecture-specific assembly code, which complicated compiler development and maintenance. ...Although standardization later helped to mitigate these problems by providing a clear and uniform definition of the language...
In 1985, Bjarne, the creator of c++, published the book "The C++ Programming Language".
In 1989, the C++ standardization committee was formed under the auspices of ISO. ISO is an international non-governmental organization that develops and publishes international standards in a wide variety of areas, including technology, manufacturing, agriculture, health, and more. ISO is composed of representatives of national standards organizations from more than 160 countries. These members collaborate to develop standards that are accepted and used globally.
As C++ gained popularity, the well-known "Technical Committee J16," which is a specific technical committee within ISO that had language experts and representatives from the developer community, began working on creating an official standard for the language.

In 1998, the committee completed its work and published the first official c++ standard, known as ISO/IEC 14882:1998. This standard defined the language formally and provided a solid foundation for future versions.

The publication of C++98 was an important milestone in the history of developers.

Compiler vendors, such as Microsoft (Visual C++), Borland (C++Builder), and GNU (GCC), were key in the adoption of the standards. These manufacturers implemented the standards in their compilers to ensure that c++ code was compiled on different processor architectures((x32, x86, x64)(AMD,Intel, Alpha, Motorola, etc)."


Ironically I have re-written the book several times, as it is very difficult to get into c++, it touches on too many topics before moving on to the next one, and many times it touches on the same thing several times as you can write the same thing in many different ways.
Irrlicht is love, Irrlicht is life, long live to Irrlicht
CuteAlien
Admin
Posts: 9935
Joined: Mon Mar 06, 2006 2:25 pm
Location: Tübingen, Germany
Contact:

Re: Splitting a program up

Post by CuteAlien »

@Noiecity: You're going very far off-topic. That was bot-like to read. And yes, I was also a bit rambling above, cramming too much info in my answer (too tired probably...), but at least I tried to answer the question.
IRC: #irrlicht on irc.libera.chat
Code snippet repository: https://github.com/mzeilfelder/irr-playground-micha
Free racer made with Irrlicht: http://www.irrgheist.com/hcraftsource.htm
Noiecity
Posts: 324
Joined: Wed Aug 23, 2023 7:22 pm
Contact:

Re: Splitting a program up

Post by Noiecity »

CuteAlien wrote: Tue Feb 04, 2025 9:52 pm @Noiecity: You're going very far off-topic. That was bot-like to read. And yes, I was also a bit rambling above, cramming too much info in my answer (too tired probably...), but at least I tried to answer the question.
I am thinking...
It is probably because I chat a lot with AI to learn programming, it is much easier for me to understand different contexts with which to understand the code, and I certainly adapted their way of communicating (because if you talk like them they give you better answers)
Irrlicht is love, Irrlicht is life, long live to Irrlicht
wizard4
Posts: 183
Joined: Thu Jan 25, 2024 6:54 pm
Location: UK

Re: Splitting a program up

Post by wizard4 »

Forum rules please. I don't want to abandon Irrlicht and move onto Allegro and start at the beginning again :crying_face:
wizard4
Posts: 183
Joined: Thu Jan 25, 2024 6:54 pm
Location: UK

Re: Splitting a program up

Post by wizard4 »

I know both me and Noiecity need to post way less and ask specific questions about Irrlicht when we face problems. CuteAlien does dedicate his time in answering our posts and his time can be spent elsewhere.

Scores: Noiecity 1 : 1 CuteAlien
wizard4
Posts: 183
Joined: Thu Jan 25, 2024 6:54 pm
Location: UK

Re: Splitting a program up

Post by wizard4 »

Oh God I'm going to get banned.

I'm going to download Hover Racer on my Intel Lenovo Ideapad 110S and test it thoroughly on Linux but might run into a few problems.

It's just more piling up but I practically have infinite time to do so.
Noiecity
Posts: 324
Joined: Wed Aug 23, 2023 7:22 pm
Contact:

Re: Splitting a program up

Post by Noiecity »

It is interesting how much code irrlicht must have, I would like to participate in the code but I am very dumb
Irrlicht is love, Irrlicht is life, long live to Irrlicht
wizard4
Posts: 183
Joined: Thu Jan 25, 2024 6:54 pm
Location: UK

Re: Splitting a program up

Post by wizard4 »

I think you are young is all. Make lots of mistakes. I did as well.
CuteAlien
Admin
Posts: 9935
Joined: Mon Mar 06, 2006 2:25 pm
Location: Tübingen, Germany
Contact:

Re: Splitting a program up

Post by CuteAlien »

Don't worry so much about my comment above. I should have done that via PM, just was too tired that day. I simple want threads to stay on topic instead of drifting completely off (as this one is now more and more). And not going to ban anyone (unless they start posting fascist stuff or something like that). And I have 5 decades behind me, hasn't stopped me from making mistakes yet ;-) (so I'm more of a grumpy old alien by now)
IRC: #irrlicht on irc.libera.chat
Code snippet repository: https://github.com/mzeilfelder/irr-playground-micha
Free racer made with Irrlicht: http://www.irrgheist.com/hcraftsource.htm
wizard4
Posts: 183
Joined: Thu Jan 25, 2024 6:54 pm
Location: UK

Re: Splitting a program up

Post by wizard4 »

Code: Select all

and Cute
Post Reply