Return Styles: Pseud0ch, Terminal, Valhalla, NES, Geocities, Blue Moon.

Pages: 1-4041-

Stylistic choices

Name: Anonymous 2011-12-13 3:18

I tend to prefer to use namespaces filled with constants, rather than using enums in most cases. For example using

namespace Element {
const uint8_t No_Element = 0;
const uint8_t Air = 1;
const uint8_t Water = 2;
const uint8_t Earth = 3;
const uint8_t Fire = 4;
};


instead of


enum Element {
No_Element, Air, Water, Earth, Fire
};


Is this bad practice?

Name: Anonymous 2011-12-13 3:25

Typedef'd enums give better protection for correctness, but there's no reason you can't put those in namespaces.

Name: Anonymous 2011-12-13 3:27

>>1
Yes. See below for a better enterprice programming practice:


namespace Error {
    enum Category {
        no_error
    };
}

int main()
{
    return Error::no_error;
}

Name: Anonymous 2011-12-13 3:29

>>3

/* Version 1.1, more verbose */

namespace Error {
    enum Category {
        no_error
    };
}

int main()
{
    Error::Category return_value = Error::no_error;
    return return_value;
}

Name: Anonymous 2011-12-13 3:31

Yes, use C++11 typesafe enum classes.

Name: 5 2011-12-13 3:36

example
a.cpp:
enum class Element {
    No_Element,
    Air,
    Water,
    Earth,
    Fire
};

int main() {
    Element x = Element::Air;
    int i = x;
    x = 3;
    return 0;
}



$ gcc -std=c++0x a.cpp
a.cpp: In function ‘int main()’:
a.cpp:11:10: error: cannot convert ‘Element’ to ‘int’ in initialization
a.cpp:12:6: error: cannot convert ‘int’ to ‘Element’ in assignment

Name: Anonymous 2011-12-13 3:41

>>6
But I want to convert between elements and integers...

Name: F r o z e n V o i d !!mJCwdV5J0Xy2A21 2011-12-13 3:46

using the #define sounds like better alternative, without any reliance on enum/class interface format
#define d #define
d No_Element  0
d Air 1
d Water 2
d Earth 3
d Fire 4

Name: Anonymous 2011-12-13 3:49

>>8
#define d #define
Oh god, my eyes!

Name: F r o z e n V o i d !!mJCwdV5J0Xy2A21 2011-12-13 3:49

Since the #define is preprocessor-based it also guarantees zero code bloat, zero namespace pollution and zero abstraction layers in the code.

Name: Anonymous 2011-12-13 4:06

>>10
Except you've just polluted 1/26th of the entire namespace.

Name: F r o z e n V o i d !!mJCwdV5J0Xy2A21 2011-12-13 4:10

>>11
you can #undef the words to reuse them
Try that with classes or enums

Name: Cudder !MhMRSATORI!FBeUS42x4uM+kgp 2011-12-13 4:17

Those constants are actually stored in the binary and using them results in a load from memory.


No_Element dd 0
Air        dd 1
...
mov eax, [Air]


An enum is an integral type so you get the value directly.


...
mov eax, 1  ; or "push 1; pop eax" to be compact

Name: Anonymous 2011-12-13 4:23

>>12

With namespaces, I don't have to undefine shit. I can have a namespace of elements, and a namespace of something else with members that have the same name. For example:

namespace Element {
const uint8_t Fire = 4;
};
namespace Attack_Damage {
const double Fire = 9.0;
};


Or some shit like that.

Name: F r o z e n V o i d !!mJCwdV5J0Xy2A21 2011-12-13 4:27

>>14
I never use #undef actually(only in extremely limited instances where the #define controls a global setting)
 because i can use namespace in the name
#define ELEMENTS_EARTH 1
See the above is just like your namespace without any bloat

Name: Anonymous 2011-12-13 4:39

>>10
#define ... no abstraction
tell that to the people who define header only data structures
int main (int argc, char ** argv) {
  int i;
  struct list l;

  do { struct list * __s = (&l); __s->h = ((void *)0); __s->t = ((void *)0); __s->s = 0; } while (0);

  while (--argc)
    do { struct list * __s = (&l); list_type __e = (atoi(*++argv)); struct list_node * __n; __n = list_node_alloc(__e); if (__n == ((void *)0)) break; if (__s->s == 0) { __s->h = __s->t = __n; } else { __n->n = __s->h; __s->h->p = __n; __s->h = __n; } __s->s += 1; } while (0);

  do { struct list_node * __n = (&l)->h; while (__n != ((void *)0)) { int n = __n->e; {
    printf("%d!\n", n);
  } __n = __n->n; } } while (0);

  do { struct list * __s = (&l); struct list_node * __n = __s->h; struct list_node * __t; while (__n != ((void *)0)) { __t = __n; __n = __n->n; do { struct list_node * __s = (__t); ; free(__s); } while (0); } do { struct list * __s = (__s); __s->h = ((void *)0); __s->t = ((void *)0); __s->s = 0; } while (0); } while (0);

  return 0;
}

Name: F r o z e n V o i d !!mJCwdV5J0Xy2A21 2011-12-13 4:46

>>16
The abstraction is not in the binary, it only in your mind.
Constants and classes are real binary objects.
How can you not grasp the difference?

Name: Anonymous 2011-12-13 4:47

>>15

Except here's the thing...

Say I have a function where I only need the elements namespace and not the Attack_Damage namespace. I can

int8_t Damage_Multiplier(const uint8_t element) {
using namespace Elements;
// My code here, uninhibited by Elements::Fire shit
}


and outside, where I have to make the Elements and Attack_Damage namespaces play nicely, I can refer to them by Elements::Fire and Attack_Damage::Fire respectfully.

Name: F r o z e n V o i d !!mJCwdV5J0Xy2A21 2011-12-13 4:54

>>18
You can make mistakes in the Elements::Fire or Attack_Damage::Fire
You can confuse, change them accidentally, or transfer some Fire properties.
when you use the #define you have more verbose, but more more reliable constants which cannot be accidentally refered to,changed  or substituted by something else without #undef or another #define.

Name: Anonymous 2011-12-13 4:57

>>18
#define USING_NAMESPACE_ELEMENTS ...

Name: F r o z e n V o i d !!mJCwdV5J0Xy2A21 2011-12-13 4:59

Compact enough?
#define EL_F 1
#define EL_W 2
#define EL_A 3
#define EL_E 4

Name: Anonymous 2011-12-13 5:01

>>19

>You can confuse, change them accidentally, or transfer some Fire properties.

Confusing them is pretty fucking hard when all you have to do is look at the top of the function definition to know which namespace it belongs to.

Also, change them? You can't change a fucking constant bro.

Name: F r o z e n V o i d !!mJCwdV5J0Xy2A21 2011-12-13 5:04

>>22
using namespace Elements;
all "constants" changed.

Name: F r o z e n V o i d !!mJCwdV5J0Xy2A21 2011-12-13 5:06

You don't accidentaly treat one namespace as another just because they share Fire?
Imagine a cryptic call to Fire in the middle of 100Kb file where you don't know which namespace it refers to

Name: F r o z e n V o i d !!mJCwdV5J0Xy2A21 2011-12-13 5:07

And thats why namespaces and similar defective Sepples shit like classes should not be used at all.

Name: Anonymous 2011-12-13 5:12

>>24
Don't you know that /prog/riders only write small toy programs that are at most 300 lines long?

Where did you get the idea that anyone here would write a 100Kb file anyway?

Name: F r o z e n V o i d !!mJCwdV5J0Xy2A21 2011-12-13 5:16

>>26
Toy programs tend to grow very fast. Imagine that could add couple of features, that would a couple of KB each.
Now multiply the process by days, add some useful abstraction with #define's and its no longer a toy.
In fact i have to restrain myself from growing my "toy programs" so they could be rewritten from scratch anytime i need a completed one with different algorithm/functionality, which would be painful to rewrite/throw away if it was a complete program(the abstraction would be moved to void.h instead).

Name: Anonymous 2011-12-13 5:20

>>27
Silly FrozenVoid, don't you ever split your toys into several files when they grow to be large?

Name: F r o z e n V o i d !!mJCwdV5J0Xy2A21 2011-12-13 5:25

>>28
Only header files. The program is always monolithic.

Name: Anonymous 2011-12-13 5:27

>>29
So you can never re-use a function from one program in another, they're all static?
Sounds like an odd way of coding.

Name: F r o z e n V o i d !!mJCwdV5J0Xy2A21 2011-12-13 5:32

>>30
I can export useful stuff to headers, like void.h
and use the header in another program like #include "VOID_[HEADERTYPE]_[FUNCTIONALITY].H"

Name: Anonymous 2011-12-13 5:42

>>31
KEKEKEKEKEKEKEKEKEKE

Name: Anonymous 2011-12-13 5:47

>>24

There shouldn't ever be a time where you don't know what namespace something is from. The using keyword should be used sparingly, and only in cases where other namespaces with the same variables will never be used.

>>29

There's a reason you have a linker you know. By only splitting up your code into a bunch of header files with a single source file, your compiler is effectively compiling a single giant mess of code. If you happen to make an error in one function, you have to recompile everything else from scratch. You should separate your source code so that you don't have to recompile the entire thing every time something needs to be changed.

Name: F r o z e n V o i d !!mJCwdV5J0Xy2A21 2011-12-13 5:53

>>33
I don't split my code this is counter-productive: my code is integrated, single-form procedural action which uses all parts of itself.
Splitting code is importing defective OOP shit from sepples, trying to make "Object Modules" from raw .C files and "Link the modules".
Suffice to say, my single file+headers always compiles fast(DMC is way faster than GCC btw), it doesn't need such OOP mess as thousands of tiny .c/.o files

Name: Anonymous 2011-12-13 5:56

>>34
Several different files for different stuff came long before OOP.
It's about making ravioli code instead of spaghetti code.

Name: F r o z e n V o i d !!mJCwdV5J0Xy2A21 2011-12-13 5:59

>>35
OOP is not a limited to languages.
This approach is OOP applied to design.

Name: Anonymous 2011-12-13 6:01

>>34

Splitting your code has nothing to do with OOP. Do you know why stdio.h only declares the printf function and doesn't define it? Because otherwise we'd have to compile the printf function every time we wanted to make a program that used it. If you consider every other function that is declared in that header, you'd find yourself compiling way more than you need to.

Name: F r o z e n V o i d !!mJCwdV5J0Xy2A21 2011-12-13 6:02

>>37
stdio.h is not a real header, its an interface to default library.
>we'd have to compile the printf function every time
Its in the C runtime.

Name: Anonymous 2011-12-13 6:13

>>38

>stdio.h is not a real header, it's an interface to default library

So you're saying there is not an stdio.h located in /usr/include on Unix and in C:/MinGW/include on Windows?

Oh, but who needs stdio.h anyways, when you can always
extern int printf(const char* str, ...);
If all you need is some basic formatted output.

Name: F r o z e n V o i d !!mJCwdV5J0Xy2A21 2011-12-13 6:26

>when you can always
Thats the point stdio.h is an empty shell to C runtime without any useful code you can compile.

Name: Anonymous 2011-12-13 7:03

>>40

Exactly, that's the purpose of a header file. To give you access to resources without actually having the resources.

Name: F r o z e n V o i d !!mJCwdV5J0Xy2A21 2011-12-13 7:06

>>41
That is called "interface"

Name: F r o z e n V o i d !!mJCwdV5J0Xy2A21 2011-12-13 7:07

Real header files  include code, templates, functions,etc
Interface headers are wrapper layers to existing functionality

Name: Anonymous 2011-12-13 7:41

>>7
LOL, type safety has its price, you need an explicit cast (int y = (int) Elements::Air;) or just use C #defines like FV.

>>8-25
Ridiculous, you're fighting for nothing. C++11 enum classs aren't common types or namespaces with const variables, and so they're treated as defined ints, but without implicit casts, and with static type and namespace checks.

Ah, FV you're a noob. Namespaces are superior than your shitty defines, because they're modular (nested), checked at compile time and don't generate a cluttered mess after preprocessor pass. The ONLY fucking disadvantage is the lack of stardard (and reasonable) name mangling.

If you all just had read >>5-6, this thread would have almost 20 less shitposts.

>>26-41
FV has a point here, but I think you mean modular programming, not OOP. And this means just to apply a divide and conquer approach to code organization, defining functions and modules. C headers are a form of modularization that can give you some reuse and black-box abstraction, but it's weak because it lacks proper scoping. Yes you can work without it, but it's easier and cleaner to write than with STD_ALGORITHM_BINARYSEARCH(v, v+v_length, cmp).
About your hungarian notation (#define EL_E 4): thank God that I don't have to read your code, I can't stand with these cryptic minified notations!

Name: F r o z e n V o i d !!mJCwdV5J0Xy2A21 2011-12-13 8:43

>STD_ALGORITHM_BINARYSEARCH(
If i'm going to use it often would make a wrapper for convinience
#define BS STD_ALGORITHM_BINARYSEARCH

Name: Anonymous 2011-12-13 9:23

>>45
Your source is bloated as fuck.

Name: Anonymous 2011-12-13 12:48

FrozenVoid telling people to abuse the preprocessor

Please Frozenshit, gtfo of prog. No one like you and your self-taught lazy C programming experience. You barely know C allow, you write shitty code and 90% of your posts make no sense because you have not a clue what you're doing.


Fuck off troll

Name: Anonymous 2011-12-13 14:38

i like fv even though i dont agree with him

Name: Anonymous 2011-12-13 15:00

>>48
You suck cocks, faggot touhou.

Name: Anonymous 2011-12-13 18:30

i love fv even though he doesnt agree with me

Name: Anonymous 2011-12-13 18:35

>>1

Constants cannot be used in switch statements. Enumerations are provided mostly for that purpose. Therefore, replacing enumerations with constants are not a good choice. It is not simply a stylistic decision.

If you're worried with namespace pollution, enclose your enumeration in a namespace.

Name: Anonymous 2011-12-13 18:42

>>51
Constants can't be used in switch

are C++ compilers that stupid still?

I thought by now any modern compiler knows how to deal with constants when it comes to switch

Name: Anonymous 2011-12-13 19:21

>>52
If the compiler can prove a value won't be modified, it doesn't need const to tell it.

Name: Anonymous 2011-12-13 20:02

>>52

C++ compilers are smart. The stupidity in this regard is in the language: it's forbidden.

Name: Anonymous 2011-12-13 20:09

>>54
Why is that stupid?

Name: Anonymous 2011-12-13 20:37

>>42

Header (.h) = Interface
Source (.c) = Implementation

That's how it's always done.

Name: Anonymous 2011-12-14 4:43

>>52

Constants cannot be used in switch statements

OP here, that's objectively wrong and you know it. I've got a 187 line of fucking code function that uses constants in what is effectively a giant fucking switch statement. I just compiled it again to see if it worked. It does, perfectly.

Name: Anonymous 2011-12-14 9:43

>>57
I've got a 187 line of fucking code function that uses constants in what is effectively a giant fucking switch statement.
Seriously?

Name: Anonymous 2011-12-14 10:38

>>57

Well, indeed there is a case when it works: when the constant is defined in the same TU as the switch statement. For other scenarios, it doesn't work.

Consider:

extern const int i;

int main() {
    int j(0);
    switch (j) {
    case i: break;
    }
}


This code is illegal. If you remove extern, the code compiles fine, because i gets invariably defined in the file scope (with the provided value, or zero if nothing is given).

Another thing which might be considered a disadvantage over enumerations is that such constans may consume storage, albeit usually a tiny one.

Name: Anonymous 2011-12-14 10:47

>>57
I've got a 187 line of fucking code function that uses constants in what is effectively a giant fucking switch statement.
You never heard of a map?

Name: Anonymous 2011-12-14 11:55

>>56
Shit, I only have a .h and a .lib - what now?

Name: Anonymous 2011-12-14 12:02

>>61
Look for an open source alternative. If one doesn't exist, write one and make it free.

Don't change these.
Name: Email:
Entire Thread Thread List