Jump to content

  • Log In with Google      Sign In   
  • Create Account

Banner advertising on our site currently available from just $5!

1. Learn about the promo. 2. Sign up for GDNet+. 3. Set up your advert!


Member Since 02 Oct 2013
Offline Last Active Yesterday, 10:43 AM

Topics I've Started

Doge Indirection

19 March 2015 - 12:42 PM

Hackers have been around for too long, usually associated with dark themes and “the evil side” they represent the minority of IT Gurus that just have too much time on their hands, and a touch of evilness. Usually represented with a skull or “horrifically” they are iconic in a never ending battle against internet crime.
For this reason, I encourage all of us to start utilising the technique of indirection for storing all primitive datatypes in our programs. Not only will this make it impossible for hackers to track our variables, it will also allow us programmers to taste the sweet taste of having stopped said hackers with a doge meme.
#include <iostream>

template <class T, int N>
struct Indirection
    typedef typename Indirection<T, N-1>::type* type;
    typedef typename Indirection<T, N-1>::type  child_type;
    static void init(type& p)
        p = new child_type;
        Indirection<T, N-1>::init(*p);
    static void cleanup(type& p)
        Indirection<T, N-1>::cleanup(*p);
        delete p;

template <class T>
struct Indirection<T, 0>
    typedef T type;
    static void init(type& p) {}
    static void cleanup(type& p) {}

int main()

    /* there happen to be 272 stars in the doge below */
    Indirection<int, 272>::type cpu_cache_will_enjoy_this;
    Indirection<int, 272>::init(cpu_cache_will_enjoy_this);
     * set the value of our variable using the power of the shibe

         *              *    
        * *           ** *     *         *     ****     *         *
        *  *        **   *     *         *   *      *   *         *
       ***  ********     *      *       *   *        *   *       *
     ***           *  ** *      *   *   *   *        *   *   *   *
   **               **** *       * * * *     *      *     * * * *
  *   **              **  *       *   *        ****        *   *
  *  ***     ****       * *  
 *           ****        *** 
 *  ****                   * 
* ******** *               * 
*  ****  ** *               *          **              *
*   ****   *               *          *                *
 *      ***                *           **   *  *   **  * **
 *                     *  *              *  *  *  *    **  *
  **                 *    *            **    **    **  *   *
    **          ****    **   
      **********     ***                     *            *  *                *   *
                   **                                     *                  ***
                                             *  * **   ** *  *  ***  **   **  *   *   **   * **
                                             *  *   * *  **  *  *   * ** *    *   *  *  *  *   *
                                             *  *   *  ** *  *  *    **   **   *  *   **   *   *

    cpu_cache_will_enjoy_this = 20;
     * now output the value to stdout
    std::cout << " the value is: " << ****************************************** // make absolutely sure not to go over the 80 character per line limit, as to not enrage The Powers That Be (Linus Torvalds) in the mailing list
    ********************* ******************************************************
    ***cpu_cache_will_enjoy_this << std::endl;
     * clean up like good programmers - no memory leaks, check it with valgraind
     * if you don't believe
    Indirection<int, 272>::cleanup(cpu_cache_will_enjoy_this);
    return 0;
Granted, the error messages can become a little bit confusing, but all you have to do is write a batch script to parse the error output in order to understand how many stars you forgot:
/home/thecomet/documents/programming/test/main.cpp: In function ‘int main()’:
/home/thecomet/documents/programming/test/main.cpp:81:61: error: no matching function for call to ‘Indirection<int, 273>::cleanup(Indirection<int, 0>::type********************************************************************************************************************************************************************************************************************************************************************************&)’
     Indirection<int, 273>::cleanup(cpu_cache_will_enjoy_this);
/home/thecomet/documents/programming/test/main.cpp:81:61: note: candidate is:
/home/thecomet/documents/programming/test/main.cpp:15:17: note: static void Indirection<T, N>::cleanup(typename Indirection<T, (N - 1)>::type*&) [with T = int; int N = 273; Indirection<T, N>::type = int*********************************************************************************************************************************************************************************************************************************************************************************; typename Indirection<T, (N - 1)>::type = int********************************************************************************************************************************************************************************************************************************************************************************]
     static void cleanup(type& p)
/home/thecomet/documents/programming/test/main.cpp:15:17: note:   no known conversion for argument 1 from ‘Indirection<int, 272>::type {aka int********************************************************************************************************************************************************************************************************************************************************************************}’ to ‘Indirection<int, 0>::type*********************************************************************************************************************************************************************************************************************************************************************************& {aka int*********************************************************************************************************************************************************************************************************************************************************************************&}’
CMakeFiles/indirection.dir/build.make:54: recipe for target 'CMakeFiles/indirection.dir/main.cpp.o' failed

Best programming paradigm for noobs?

10 March 2015 - 04:53 PM

If a noob, who knows nothing about computer programming, wishes to embark on the painful journey of developing software, what is the best paradigm to start with and why? Procedural? OO? Functional?
I've been thinking about this lately because at college Java is the first thing to be taught and I noticed there to be a lot of confusion among the students. Those who have never been close to computer code are having an extremely hard time grasping the concepts. Those who have programmed before are having less of a hard time, but are still utterly confused (try explaining to them what the "this" keyword does, for instance).
I personally started out with BASIC when I was 14, and much much later I decided to learn about OO. I think it's a lot easier to learn a procedural language before learning OO.
What do you think?

dllimport/dllexport with multiple depending shared libs

18 February 2015 - 06:45 AM

Most people will tell you that every DLL will have to #include an export.h header file with something like the following in it:

#   define LIBRARY_API __declspec(dllexport)
#   define LIBRARY_API __declspec(dllimport)
Then, when you build the library, simply globally define LIBRARY_BUILDING, and when you're linking against the library, don't define it.
My questions are: 
1) What happens when you have multiple DLLs that depend on each other and include each other's header files? Do I need to create two export.h header files, one for each DLL?
2) If one global export.h file is sufficient for all DLLs, can you please explain to me in the example below why the linker doesn't throw any errors or warnings?
Here's an example demonstrating what I mean:

#   define FOO_API __declspec(dllexport)
#   define FOO_API __declspec(dllimport)

FOO_API some_function_foo(void);

#   define BAR_API __declspec(dllexport)
#   define BAR_API __declspec(dllimport)

#include "foo.h"

/* this function calls some_function_foo() from foo.DLL */
BAR_API some_function_bar(void);

#include "bar.h"

int main()
    return 0;
When this project gets built, the following occurs:
1) foo.DLL: FOO_BUILDING gets defined, which means all of foo's functions are declared with dllexport.
2) bar.DLL: BAR_BUILDING gets defined, but FOO_BUILDING isn't defined. This means all of foo's functions are declared with dllimport, and all of bar's functions are declared with dllexport when bar includes foo's headers. I would assume this is the intended behaviour.
3) application: Neither FOO_BUILDING nor BAR_BUILDING is defined, therefore all of foo's and bar's functions are declared with dllimport.
If I had only one export.h header file, then step 2) would not be possible, because either everything gets declared with dllexport or everything gets declared with dllimport, ignoring the fact that one of the libraries is already built and the other one isn't. However, I'm not getting any link errors/warnings if I use only one global export.h header file, even though I expect them. Why?

Forum Broken?

10 February 2015 - 03:11 AM

Am I the only one who sees the forums like this?

http://i.imgur.com/ZE979Z5.jpg http://i.imgur.com/o82XDJr.jpg

It's been like this for the last 2 days for me. Every other website, every other forum, every other social platform, they all work for me. It's only GDNet that's doing this to me. Why?

Can someone explain this to me?

The homepage works, and browsing threads and boards works to some degree. By "some degree" I mean icons are missing, and weird stretching occurs, as can be seen here:


That last screenshot has always been the case for me, not only since the last 2 days. The forum has always stretched and missed icons like that.

$ uname -a
3.17.7-gentoo #1 SMP Sun Feb 1 05:45:15 CET 2015 x86_64 AMD Phenom™ II X6 1090T Processor AuthenticAMD GNU/Linux

$ eix google-chrome
[?] www-client/google-chrome
Available versions: ~40.0.2214.94_p1^msd {+plugins LINGUAS="+am +ar +bg +bn +ca +cs +da +de +el +en_GB +es +es_LA +et +fa +fi +fil +fr +gu +he +hi +hr +hu +id +it +ja +kn +ko +lt +lv +ml +mr +ms +nb +nl +pl +pt_BR +pt_PT +ro +ru +sk +sl +sr +sv +sw +ta +te +th +tr +uk +vi +zh_CN +zh_TW"}
Installed versions: 39.0.2171.95_p1^msd(18:24:17 19/12/14)(plugins LINGUAS="en_GB -am -ar -bg -bn -ca -cs -da -de -el -es -es_LA -et -fa -fi -fil -fr -gu -he -hi -hr -hu -id -it -ja -kn -ko -lt -lv -ml -mr -ms -nb -nl -pl -pt_BR -pt_PT -ro -ru -sk -sl -sr -sv -sw -ta -te -th -tr -uk -vi -zh_CN -zh_TW")

Generic events - Enforcing the correct function signatures.

18 January 2015 - 02:43 PM

I began development on a game written in C89 about a month ago. The design of this game is entirely centred around a plugin system which basically consists of a module loader, a service directory, and an events system.

The events system is horribly prone to human error and this is what I want to get some input on.

Consider the host application and two plugins, pluginA and pluginB. pluginA registers an event "foo" to the host application, and pluginB listens to that event. The flow of information, thus, looks like this:

         host app
      event dispatcher
        ^          \
       /            \
      /              v
   pluginA         pluginB

The event system is implemented as follows:

/* generic function, any amount of arguments can be passed to a call of this function type (only works in C, not C++) */
typedef void (*event_listener_callback)();

struct event_t
    char* name;
    struct vector_t listeners; /* a vector of event_listener_t objects */

struct event_listener_t
    char* listener_name;
    event_listener_callback exec;

#define EVENT_H(event_name) extern struct event_t* event_name;
#define EVENT_C(event_name) struct event_t* event_name = NULL;

#define EVENT_FIRE0(event_name) \
    VECTOR_FOR_EACH((event_name)->listeners, struct event_listener_t, listener) \
    { \
        listener->exec(event_name); \

#define EVENT_LISTENER0(name) \
    void name(const struct event_t* evt)

Note that there are macros for EVENT_FIRE1, EVENT_FIRE2, etc. depending on how many arguments the event wishes to send.


From pluginA's perspective, this is how it would register an event:


void pluginA_init(void)
    evt_foo = event_create("foo"); /* this returns a new event_t object */

From pluginB's perspective, this is how it would listen to the event "foo":

void register_events(void)
    event_register_listener("foo", on_foo); /* this adds the function "on_foo" to the corresponding event's listeners vector */

    puts("event foo received!");

The Problem


The issue with this system is that the receiving function "on_foo" could have any function signature, and it would compile anyway. Similarly, EVENT_FIRE could callback any number of arguments and yet it would compile anyway.


Furthermore, from pluginB's perspective, it's very hard to figure out what each event's callback function signature should be. The only place where it's defined is EVENT_FIRE0().


Is there any better way to implement this? Is there any way to enforce the programmer to match all function signatures correctly? The fact that the callback is delegated using a generic function probably makes this impossible, so I'm wondering if there's a better way to implement such a system?


[EDIT] How do I add the "C" prefix to my thread?