Welcome, Guest. Please login or register.

Login with username, password and session length

 
Advanced search

1412053 Posts in 69447 Topics- by 58483 Members - Latest Member: Exye

June 22, 2024, 07:06:45 PM

Need hosting? Check out Digital Ocean
(more details in this thread)
TIGSource ForumsDeveloperTechnical (Moderator: ThemsAllTook)Coding styles
Pages: 1 2 3 [4] 5 6 7
Print
Author Topic: Coding styles  (Read 18977 times)
terloon
Level 0
**


View Profile WWW
« Reply #60 on: February 28, 2010, 09:13:04 PM »

#defines are like global search and replace and really should have no place in c++. enums give you data encapsulation and type checking.
Logged
Glaiel-Gamer
Guest
« Reply #61 on: February 28, 2010, 10:30:21 PM »

I don't see any benefits of using enums instead of good old defines.

embed an enum in a struct
Code:
struct ColorChannelMask { 
  enum {
    RED = 0xFF000000,
    BLUE = 0x0000FF00,
    GREEN = 0x00FF0000,
    ALPHA = 0x000000FF
  };
};

Now, unlike a define, the values are relative to the struct

ColorChannelMask::RED
ColorChannelMask::GREEN
ColorChannelMask::BLUE
ColorChannelMask::ALPHA
Logged
Average Software
Level 10
*****

Fleeing all W'rkncacnter


View Profile WWW
« Reply #62 on: February 28, 2010, 11:36:59 PM »

I don't see any benefits of using enums instead of good old defines.

embed an enum in a struct
Code:
struct ColorChannelMask { 
  enum {
    RED = 0xFF000000,
    BLUE = 0x0000FF00,
    GREEN = 0x00FF0000,
    ALPHA = 0x000000FF
  };
};

Now, unlike a define, the values are relative to the struct

ColorChannelMask::RED
ColorChannelMask::GREEN
ColorChannelMask::BLUE
ColorChannelMask::ALPHA


Even better, the new C++ standard provides scoped enums via "enum class"

Code:
enum class DayOfWeek {monday, tuesday, ...etc};

DayOfWeek today = DayOfWeek::sunday;
Logged



What would John Carmack do?
Fallsburg
Level 10
*****


Fear the CircleCat


View Profile
« Reply #63 on: March 01, 2010, 08:03:20 AM »

//I prefer to use
#pragma once
//Instead of
#ifndef MY_HEADER_H
#define MY_HEADER_H
#endif
// Mostly because I am completely anal and am afraid that I am going to step on someone else's #define
// and while I know that #pragma once is compiler dependent, I am not so concerned with portability

//I prefer curly brackets as follows
for (int ii = 0; ii < 10; ii++){
}
//And I don't use single letter variables (i,j,k,etc.) but instead use double letters
//as it makes it much easier to find/replace operations on the variables

//I only do trivial definitions in header files, i.e. nothing beyond a get/set method
class MyClass{
public:
   int getVar(){
       return var;
   }
   void setVar(int var_){
       var = var_;
   }
private:
   int var;
};

// I only capitalize user defined data structures (classes, enums, structs,etc.)
// In a physics setting, if the units of something are not in SI units,
// I will specify the units at the end of the variable name
double myMass; //Assumed to be kg
double myStupidMass_slug; //Honestly, why would you ever use slugs?

« Last Edit: December 18, 2015, 05:08:37 PM by Silbereisen » Logged
Mikademus
Level 10
*****


The Magical Owl


View Profile
« Reply #64 on: March 01, 2010, 08:26:00 AM »

//I prefer to use
#pragma once
//Instead of
#ifndef MY_HEADER_H
#define MY_HEADER_H
#endif

Have you tried compiling that on a compiler not MSVC?
Logged

\\\"There\\\'s a tendency among the press to attribute the creation of a game to a single person,\\\" says Warren Spector, creator of Thief and Deus Ex. --IGN<br />My compilation of game engines for indies
Kadoba
Level 3
***



View Profile
« Reply #65 on: March 01, 2010, 09:01:40 AM »

Have you tried compiling that on a compiler not MSVC?

I know it also works with GCC but it's considered depreciated. I use to use "#pragma once" exclusively but I've heard a lot of arguments against it. So now I risk straining myself by adding two extra lines.
Logged
Sos
Level 8
***


I make bad games


View Profile WWW
« Reply #66 on: March 01, 2010, 10:33:56 AM »

Yeah, #pragma is compiler specific, but it's safe unless you plan portability.

also: I hate errors like "expected const char*, but got char **, there is no possibility of cast there" or sth like this in MSVC particularily. this example might not give the error, but I got many like these from stuffing regular types, where GL* were expected.
AAAAnd, that's why I don't use enums.
Logged

LemonScented
Level 7
**



View Profile
« Reply #67 on: March 01, 2010, 10:56:21 AM »

All caps enum (and const) values are another thing that can be very dangerous, since it's just begging for macro clashes.  I think this comes from the fact that enums and const were relatively late additions to C, and I think people used to convert #define macros without the changing the names.  It's the only explanation I can come up with for why people do this.

It's worth noting than modern C++ authorities like Stroustrup all recommend against doing this.

My coding style tends to be shaped by things that have bitten me in the ass before, and the enum thing is something that's never been a problem for me. That said, I tend to (as in my example) declare enums inside the classes they're relevant to, so it's not often I have one in the global namespace anyway. With that being the case, having an all caps convention for anything that's constant (const variables, #defines and enums) is a good way to identify something as being a value that can't be changed.
Logged

Average Software
Level 10
*****

Fleeing all W'rkncacnter


View Profile WWW
« Reply #68 on: March 01, 2010, 12:17:53 PM »

That said, I tend to (as in my example) declare enums inside the classes they're relevant to, so it's not often I have one in the global namespace anyway.

Macros don't care about scopes and namespaces, that's no protection.

Quote
With that being the case, having an all caps convention for anything that's constant (const variables, #defines and enums) is a good way to identify something as being a value that can't be changed.

Why do you need to identify this?  The compiler won't let you change them anyway.
Logged



What would John Carmack do?
skyy
Level 2
**


[ SkyWhy ]


View Profile
« Reply #69 on: March 01, 2010, 01:19:38 PM »

Why do you need to identify this?  The compiler won't let you change them anyway.
But isn't that compile time?

personally I'd like to know this before compiling and this way not waste compile time (yeah, those precious milliseconds...).

So I'm guessing seeing them all caps is like: "a-ha.. I already know this is a constant, I cannot change it", instead of doing the same thing once the compiler starts crying about it during compile and THEN changing the variable/constant/what ever you are working on that caused the problem and re-compile.

Did I even hit close LemonScented?

But yeah, macros really do not care about scopes or namespaces, it's all open warzone for those babies. When I'm doing C++, I only tend to use macros inside .cpp files ... Not the best solution but sometimes I just love having macros. Cannot help it. I guess it's the nostalgy from good old C and being punched in the face..? Who knows.
Logged

Fallsburg
Level 10
*****


Fear the CircleCat


View Profile
« Reply #70 on: March 01, 2010, 01:23:41 PM »

Have you tried compiling that on a compiler not MSVC?

I know it also works with GCC but it's considered depreciated. I use to use "#pragma once" exclusively but I've heard a lot of arguments against it. So now I risk straining myself by adding two extra lines.

Yeah, I have with GCC.  But I use the #defines as well, just to be extra safe. 
Logged
LemonScented
Level 7
**



View Profile
« Reply #71 on: March 01, 2010, 02:57:17 PM »

@skyy: Yes, you've pretty much got it.

If you're going to get super-cautious about the possibility of macros trampling all over stuff, there's additional spookiness in the fact that there's nothing to stop macros containing lowercase characters anyway, so in theory they post a risk right across the board, not just to things with uppercase names. In practise, it's not something that's ever bitten me, so I don't tend to lose sleep over it - I knowingly do a lot of things in my coding style which are potentially risky, but I figure if I'm aware of the risks, and consider the benefits of my approach to outweigh them, it's all good. For instance this:
Code:
if(SOME_CONSTANT == someVariable)
is safer than this:
Code:
if(someVariable == SOME_CONSTANT)

but the former just reads all backwards, which is why I don't use it - I just crank up the warning level to maximum, treat warnings as errors, and let the compiler catch it that way.

Of course, as I said, you should really prefer const int over #define, but I don't (because the syntax colouring in my IDE picks out #defines better, so the constants are easier to see, and again I like my code as quick to read and comprehend as poosible). But either way, it's good practise in general to keep consts or #defines (or pretty much anything else for that matter) as closely-scoped and descriptively-named as possible, and to avoid libraries with poorly-named and scoped elements which might clash with your own.
Logged

jotapeh
Level 10
*****


View Profile
« Reply #72 on: March 01, 2010, 08:23:41 PM »

For instance this:
Code:
if(SOME_CONSTANT == someVariable)
is safer than this:
Code:
if(someVariable == SOME_CONSTANT)

Yeah. I actually first saw this when perusing metanet's N source code for collisions. It really confused me when I saw < and > signs, with the literal on the left-hand side.. I'm not sure why it reads so poorly (it's still logically correct), but you are right that it is awkward
Logged
Glaiel-Gamer
Guest
« Reply #73 on: March 01, 2010, 08:59:47 PM »

For instance this:
Code:
if(SOME_CONSTANT == someVariable)
is safer than this:
Code:
if(someVariable == SOME_CONSTANT)

Yeah. I actually first saw this when perusing metanet's N source code for collisions. It really confused me when I saw < and > signs, with the literal on the left-hand side.. I'm not sure why it reads so poorly (it's still logically correct), but you are right that it is awkward

It's cause like, in english, you're going to ask yourself "Do I have greater than 4 eggs?", not "Is 4 less than the number of eggs I have?". Even though both sentences are "correct", one is easy to understand and the other is yoda-talk.

Also, the only reason the first form is "safer" is "just in case" you type 1 equals sign instead of 2. It'll still compile and run, but you'll get unexpected results. If the constant comes first, 4=variable is a compile-time error. It's dumb though, I don't write my code to plan for tiny mistakes like that, those are the easiest to find and fix. The hard ones are when your code isn't readable in english, and you need to go through and go "ok so if 4 is less than speed and (there is a collision on the ground but not in the water+20pixels) or there's a collision in the water-20 pixels, and (timer is less than 0 and there is a timer) or there is no timer and... wait I lost track"
« Last Edit: March 01, 2010, 09:03:00 PM by Glaiel-Gamer » Logged
Glaiel-Gamer
Guest
« Reply #74 on: March 01, 2010, 09:16:12 PM »

"ok so if 4 is less than speed and (there is a collision on the ground but not in the water+20pixels) or there's a collision in the water-20 pixels, and (timer is less than 0 and there is a timer) or there is no timer and... wait I lost track"

Also this tends to happen to a lot of my logic code, and I usually deal with it until it REALLY pisses me off. For instance, in Closure, the logic for dropping an orb was as follows:

if the character is grounded, and the orb is not in a no drop zone, and the orb is not colliding with the ground, and the key is pressed, then drop the orb

it was a long block of code, duplicated a few times here and there for pedestals

later I needed to change the behavior of an orb to

if the character is grounded and the key is pressed
and the orb is not in a no drop zone, and either the orb is unlit OR the (orb is lit and the orb is not in the ground)

duplicated of course for some sound effects, slightly modified.

Became super sphaghetti-y, so I've started putting those types of tests into "verb-able" functions

so the orb has a function "droppable", "pickupable", and the door has a function for "openable", etc. Makes it super so much easier to read when I can look at the code and read "if the character is grounded, the key is pressed, and the orb is droppable, then drop the orb", rather than a mess of shit
Logged
Sos
Level 8
***


I make bad games


View Profile WWW
« Reply #75 on: March 01, 2010, 11:04:02 PM »

I don't narrate my code. Anyways, I can speak ANSI C, so I don't need to.
Logged

shrimp
Level 5
*****


View Profile WWW
« Reply #76 on: March 02, 2010, 01:38:50 AM »

I worked with a guy once who used arbitrary numbers for switch cases, e.g.

switch(x)
{
 case 2:
    // something
    break;
 case 3:
    // something
    break;
 case 75:
    // something
    break;
 case 1010101101:
    // something
    break;
}

With the accompanying x = 75, x = 10100101101 etc through the code.

Also his keys/hotkeys were mapped completely uniquely, so if anyone else on the team had to do something with his code on his machine whilst he was away (say, the day before a deadline) it looked like they were getting a sequence of strong electric shocks whenever they looked at the screen or touched the keyboard.
Logged

skyy
Level 2
**


[ SkyWhy ]


View Profile
« Reply #77 on: March 02, 2010, 02:26:02 AM »

Also his keys/hotkeys were mapped completely uniquely, so if anyone else on the team had to do something with his code on his machine whilst he was away (say, the day before a deadline) it looked like they were getting a sequence of strong electric shocks whenever they looked at the screen or touched the keyboard.

There are still people like this? Oh wow... Big Laff
Logged

st33d
Guest
« Reply #78 on: March 02, 2010, 02:59:19 AM »

MAGIC NUMBERS ARE MAGIC!

 Hand Shake Left Wizard Hand Shake Right
Logged
Average Software
Level 10
*****

Fleeing all W'rkncacnter


View Profile WWW
« Reply #79 on: March 02, 2010, 05:49:27 AM »

I worked with a guy once who used arbitrary numbers for switch cases, e.g.

switch(x)
{
 case 2:
    // something
    break;
 case 3:
    // something
    break;
 case 75:
    // something
    break;
 case 1010101101:
    // something
    break;
}

With the accompanying x = 75, x = 10100101101 etc through the code.

This can be annoying, but I've also seen people take this way too far in the other direction, basically trying to never use a raw value.  Sometimes a number really is just a number.
Logged



What would John Carmack do?
Pages: 1 2 3 [4] 5 6 7
Print
Jump to:  

Theme orange-lt created by panic