Some programmers actually hate OOP languages? WHAT?!

Started by
91 comments, last by Washu 9 years, 2 months ago

I get that Object-Oriented Programming is clearly intended to pay a lot more attention to objects and use them as the core concept of the software's architecture, but I find it hard to imagine any kind of even somewhat blurry line that demarcates proper OOP and something like...

One reason for that is that is a lack of definition. There is no clear line because making any kind of line requires a definition.

I have never seen any group -- from rooms of engineers to standards groups -- define what OOP means with any clarity. "Proper OOP" has no definition. It means one thing to somebody, another thing to somebody else.

Even the name itself, "oriented", is ambiguous. The language or design or style tends to direct toward objects. It is oriented around or toward objects. That is not a feature list or strict definition, just a tendency in a direction.

As Hogman, Ravyne, myself, and others are repeating, languages like C++ don't fit nicely into any particular bucket for various definitions. That is one reason C++ is often called multi-paradigm. Sometimes, some features of the language do not meet one definition's strict requirement, but they might satisfy requirements for other definitions. It all comes to definitions.

Some definitions are a continuum, some definitions are checklists requiring absolute adherence, some definitions are nominal scales with clusters of features, some definitions are other variants entirely.

When undefined terms like "Proper OOP" are used, as though a term that has no solid definition has a precise and agreed-upon definition, the argument is pointless. When even the experts cannot come up with definitions of the terms an attempt to use the term as an authority is a logical error.

Advertisement

When you go to break your problem into managable chunks, do you think "what parts make this up?" (OO), "what steps do I need to take?" (procedural), or "what operations make this up?" (functional).


Personally I use a combination of all three in my head and the program I create reflects what solution I dream up...
One reason for that is that is a lack of definition. There is no clear line because making any kind of line requires a definition.

I have never seen any group -- from rooms of engineers to standards groups -- define what OOP means with any clarity. "Proper OOP" has no definition. It means one thing to somebody, another thing to somebody else.

That's what I was afraid of unsure.png.

Still... what might "well-coded" games in C look like? Or would it be quite close to a game in C++ but mostly just without the encapsulation given by things like access modifiers, and semi-advanced concepts like templates?

One reason for that is that is a lack of definition. There is no clear line because making any kind of line requires a definition.

I have never seen any group -- from rooms of engineers to standards groups -- define what OOP means with any clarity. "Proper OOP" has no definition. It means one thing to somebody, another thing to somebody else.

That's what I was afraid of unsure.png.

Still... what might "well-coded" games in C look like? Or would it be quite close to a game in C++ but mostly just without the encapsulation given by things like access modifiers, and semi-advanced concepts like templates?

Pretty much. You'd mostly see well-designed independent modules and libraries using either PIMPL (= opaque structures in C) or stack-allocated "please don't mess with the internals" structs, or a mix thereof, mutable state would be minimized instead preferring to pass data back and forth in arrays of small compact structures, any dynamic dispatch would probably be implemented either through function pointers or jump tables (most likely though you would instead see composition via structures of structures and possibly tagged unions, which tend to be easier to manage in terms of complexity especially if your build system doesn't suck - protip, offloading some work to your build system can often go a long way in simplifying details of your implementation). Templates would be a bit of a problem, macros can be made to work in some limited sense. The code would probably also be interfaced with a scripting language such as Lua to overcome some of the lacking bits of the language and get the best of both worlds.

It can be quite readable, honestly, you have to go without many of the conveniences (and optimization avenues!) available to C++, in exchange you get a reasonably compact language that can for the most part be learnt inside out, a relatively uniform way of doing things without many syntactic features, and I suppose faster build times in most cases. It may not necessarily be the optimal choice by any metric, but it's certainly not the worst one I can think of. It's ridiculous how many people seem to equate C with spaghetti procedural code with globals and gotos everywhere, I personally find well-written C code to be quite pleasing actually. And it's not "OOP", it's just the sensible way of doing things given the tools at your disposal.

“If I understand the standard right it is legal and safe to do this but the resulting value could be anything.”


Still... what might "well-coded" games in C look like? Or would it be quite close to a game in C++ but mostly just without the encapsulation given by things like access modifiers, and semi-advanced concepts like templates?

Being someone who is currently coding a game in C for the lulz, I think I can answer this.

The structure of code is quite different than what I'd do in C++, but the same basic concepts apply. For instance, a lot of systems have system_init() and system_deinit() functions instead of constructors/destructors. There are no classes with methods, but there are structs for holding data and functions which act upon the data of these structs. Templates don't exist, but you can implement the majority of what templates are used for with macros. Compositing can be done with structs.

Polymorphism doesn't exist per se. I've seen my fair share of home made polymorphism in C, but I believe it's not really necessary. Most of the time you can composite.

"I would try to find halo source code by bungie best fps engine ever created, u see why call of duty loses speed due to its detail." -- GettingNifty

macros?


Still... what might "well-coded" games in C look like? Or would it be quite close to a game in C++ but mostly just without the encapsulation given by things like access modifiers, and semi-advanced concepts like templates?

Being someone who is currently coding a game in C for the lulz, I think I can answer this.

The structure of code is quite different than what I'd do in C++, but the same basic concepts apply. For instance, a lot of systems have system_init() and system_deinit() functions instead of constructors/destructors. There are no classes with methods, but there are structs for holding data and functions which act upon the data of these structs. Templates don't exist, but you can implement the majority of what templates are used for with macros. Compositing can be done with structs.

Polymorphism doesn't exist per se. I've seen my fair share of home made polymorphism in C, but I believe it's not really necessary. Most of the time you can composite.

Can I say that.. I really hate macros? tongue.png Of course I'm not talking about _DEBUG... but macros "abusing" like in the low level parts of the UE4 (e.g. RHI)

"Recursion is the first step towards madness." - "Skegg?ld, Skálm?ld, Skildir ro Klofnir!"
Direct3D 12 quick reference: https://github.com/alessiot89/D3D12QuickRef/

Still... what might "well-coded" games in C look like?

May as well check out the work of one of the original rock star gamedevs:
https://github.com/id-Software/Quake-III-Arena
http://fabiensanglard.net/quake3/index.php
http://fabiensanglard.net/quake2/index.php
http://fabiensanglard.net/quakeSource/index.php
http://fabiensanglard.net/doomIphone/index.php
http://fabiensanglard.net/doomIphone/doomClassicRenderer.php

Still... what might "well-coded" games in C look like? Or would it be quite close to a game in C++ but mostly just without the encapsulation given by things like access modifiers, and semi-advanced concepts like templates?

You can download the source code for most of the older Id games on GitHub. Prior to Doom 3, they used plain C (or C with assembly in the older titles). I'm not a C jock, so I won't speak for how "well-coded" these are by modern standards, but its clear enough that I can read through and understand most of what is happening without struggling too hard.

From what I remember, at least the Quake engine is laid out in a sorta-vaguely object-oriented fashion, although it would probably be more correct to say it is component-oriented. There are variables associated with the memory allocator, and functions that perform various actions operating on them, allocating chunks of memory, freeing chunks, getting the next available chunk, and so on. Same for the renderer, or the resource loader, or the console, etc. So you can still have separation of concerns, but you have to enforce them. Again, IANACJ, but I believe you can also use static globals in a .c file to restrict visibility of a variable to just code within that file.

You can also do some templatey stuff if you use macros in C. Whether that is a good idea, well...

EDIT: Ninja'd!

Eric Richards

SlimDX tutorials - http://www.richardssoftware.net/

Twitter - @EricRichards22

... assorted things found in C ...

Also, function pointers. Be prepared for them.

C++ and the virtual function table -- one of the things people think of as a key feature of object oriented languages -- came from function pointer tables that were and still are common in idomatic C.

The common features of C++'s classes stem from common naming conventions in C. It is common to see function families in the form: SystemFunction(SomeStruct* ...);

For some examples: file streams you've got fxxx family: fopen, fclose, fread, fwrite, fgetc, fputc, ftell, fseek, and on and on. Each uses a pointer to a FILE object, which holds super-secret information about the file, very often as a struct with function pointers. The string family of functions are similar, strxxx for strings (strcpy, strcat, strlen, strcmp, etc), wcs for "wide character strings" (wsccpy, wcscat, wcslen, wcscmp). Or va_start, va_end, va_copy. For threading with the Posix library you've got pthread_create, pthread_join, pthread_detach, pthread_exit, pthread_mutex_init, pthread_mutex_lock, pthread_mutex_unlock, pthread_mutex_destory... should be enough to get the picture.

Instead of the common C pattern of passing an object pointer to every function, C++ secretly passes a structure you call the this pointer. Instead of having a function table that lets you modify functionality you've got a (hidden from the programmer) vtable and inheritence. Instead of prefixing the names of all the functions with a system, you have a class name or namespace name.

The languages diverged quickly, but a great number of the C++ language features were syntactic sugar over idiomatic C.

The languages diverged quickly, but a great number of the C++ language features were syntactic sugar over idiomatic C.


Especially since the very first C++ compilers were C pre-processors! You'd run them on your C++ code and it would output C code that you'd put into your favorite C compiler to produce the exe.

This topic is closed to new replies.

Advertisement