Like Tree3Likes
  • 1 Post By Salem
  • 2 Post By Syscal

What do you guys make of someone who writes code like this?

This is a discussion on What do you guys make of someone who writes code like this? within the C++ Programming forums, part of the General Programming Boards category; Seems like an amazing coder to me but there are things like magic numbers and one letter variables that I ...

  1. #1
    C lover
    Join Date
    Oct 2007
    Location
    Virginia
    Posts
    265

    What do you guys make of someone who writes code like this?

    Seems like an amazing coder to me but there are things like magic numbers and one letter variables that I notice him using. I have always read that it's bad to do stuff like that:

    Creating a NES emulator in C++11 (PART 1/2) - YouTube

    To me if that's for educational purposes, I think he should have at least slowed it down and had some discussion while he wrote it (Of course the video would be a lot longer)

  2. #2
    and the hat of wrongness Salem's Avatar
    Join Date
    Aug 2001
    Location
    The edge of the known universe
    Posts
    32,451
    Awful waste of bandwidth and crap music soundtrack.

    Seriously, far more could be accomplished in 10K of text on a web page (source code and explanatory notes) than watching 100+MB of crazy typing and pointless music.
    phantomotap likes this.
    If you dance barefoot on the broken glass of undefined behaviour, you've got to expect the occasional cut.
    If at first you don't succeed, try writing your phone number on the exam paper.
    I support http://www.ukip.org/ as the first necessary step to a free Europe.

  3. #3
    C lover
    Join Date
    Oct 2007
    Location
    Virginia
    Posts
    265
    LOL! Not sure if he purposely obscures the code too... What the heck:

    Code:
            #define t(s,code) { enum { \
                i=o8m & (s[o8]>90 ? (130+" (),-089<>?BCFGHJLSVWZ[^hlmnxy|}"[s[o8]-94]) \
                                  : (s[o8]-" (("[s[o8]/39])) }; if(i) { code; } }
    iMalc and Elysia like this.

  4. #4
    Registered User
    Join Date
    Oct 2006
    Posts
    2,293
    Quote Originally Posted by Syscal View Post
    Code:
            #define t(s,code) { enum { \
                i=o8m & (s[o8]>90 ? (130+" (),-089<>?BCFGHJLSVWZ[^hlmnxy|}"[s[o8]-94]) \
                                  : (s[o8]-" (("[s[o8]/39])) }; if(i) { code; } }
    that is probably the ugliest bit of code I've ever seen. what is the context of the code? what exactly is it supposed to do? is it deliberately obfuscated?
    Code:
    namespace life
    {
        const bool change = true;
    }

  5. #5
    C lover
    Join Date
    Oct 2007
    Location
    Virginia
    Posts
    265
    Can't say that it's deliberate since he posted the video and code for "educational purposes". The code is part of an NES emulator he has written. I for one can't follow the code when the most of it is written like that.

  6. #6
    C++まいる!Cをこわせ! Elysia's Avatar
    Join Date
    Oct 2007
    Posts
    22,437
    Quote Originally Posted by Elkvis View Post
    that is probably the ugliest bit of code I've ever seen. what is the context of the code? what exactly is it supposed to do? is it deliberately obfuscated?
    It's part of the "opcode decoding matrix." Can't say I approve of this obfuscation. Better to have many functions decoding these opcodes instead of this obfuscation.
    Overall impressions, though: Minus points for use of C I/O, some bad brace placement, use of unions, long complex expressions, C-style arrays and abusing enums as constants.
    Use of namespace and templates are nice, though overall, save for a little use of some vector, this differs not much from C code. Now that I'd expect it to. This is very low-level code, and that in turn often makes it close to how C would do it.
    Last edited by Elysia; 07-08-2013 at 02:06 PM.
    Quote Originally Posted by Adak View Post
    io.h certainly IS included in some modern compilers. It is no longer part of the standard for C, but it is nevertheless, included in the very latest Pelles C versions.
    Quote Originally Posted by Salem View Post
    You mean it's included as a crutch to help ancient programmers limp along without them having to relearn too much.

    Outside of your DOS world, your header file is meaningless.

  7. #7
    C lover
    Join Date
    Oct 2007
    Location
    Virginia
    Posts
    265
    It's amazingly confusing yet it works... Somehow he operates on string literals to execute opcodes... I have a function for every single opcode in my MOS 6502 emulator and I think anyone could follow through it. He has these strings that somehow perform the operations themselves... Blows my mind. Below is the snippet that follows the above define. Do people do stuff like this in production code and is it a big no no?


    Code:
    /* Decode address operand */
            t("                                !", addr = 0xFFFA) // NMI vector location
            t("                                *", addr = 0xFFFC) // Reset vector location
            t("!                               ,", addr = 0xFFFE) // Interrupt vector location
            t("zy}z{y}zzy}zzy}zzy}zzy}zzy}zzy}z ", addr = RB(PC++))
            t("2 yy2 yy2 yy2 yy2 XX2 XX2 yy2 yy ", d = X) // register index
            t("  62  62  62  62  om  om  62  62 ", d = Y)
            t("2 y 2 y 2 y 2 y 2 y 2 y 2 y 2 y  ", addr=u8(addr+d); d=0; tick())              // add zeropage-index
            t(" y z!y z y z y z y z y z y z y z ", addr=u8(addr);   addr+=256*RB(PC++))       // absolute address
            t("3 6 2 6 2 6 286 2 6 2 6 2 6 2 6 /", addr=RB(c=addr); addr+=256*RB(wrap(c,c+1)))// indirect w/ page wrap
            t("  *Z  *Z  *Z  *Z      6z  *Z  *Z ", Misfire(addr, addr+d)) // abs. load: extra misread when cross-page
            t("  4k  4k  4k  4k  6z      4k  4k ", RB(wrap(addr, addr+d)))// abs. store: always issue a misread
            /* Load source operand */
            t("aa__ff__ab__,4  ____ -  ____     ", t &= A) // Many operations take A or X as operand. Some try in
            t("                knnn     4  99   ", t &= X) // error to take both; the outcome is an AND operation.
            t("                9989    99       ", t &= Y) // sty,dey,iny,tya,cpy
            t("                       4         ", t &= S) // tsx, las
            t("!!!!  !!  !!  !!  !   !!  !!  !!/", t &= P.raw|pbits; c = t)// php, flag test/set/clear, interrupts
            t("_^__dc___^__            ed__98   ", c = t; t = 0xFF)        // save as second operand
            t("vuwvzywvvuwvvuwv    zy|zzywvzywv ", t &= RB(addr+d)) // memory operand
            t(",2  ,2  ,2  ,2  -2  -2  -2  -2   ", t &= RB(PC++))   // immediate operand
            /* Operations that mogrify memory operands directly */
            t("    88                           ", P.V = t & 0x40; P.N = t & 0x80) // bit
            t("    nink    nnnk                 ", sb = P.C)       // rol,rla, ror,rra,arr
            t("nnnknnnk     0                   ", P.C = t & 0x80) // rol,rla, asl,slo,[arr,anc]
            t("        nnnknink                 ", P.C = t & 0x01) // lsr,sre, ror,rra,asr
            t("ninknink                         ", t = (t << 1) | (sb * 0x01))
            t("        nnnknnnk                 ", t = (t >> 1) | (sb * 0x80))
            t("                 !      kink     ", t = u8(t - 1))  // dec,dex,dey,dcp
            t("                         !  khnk ", t = u8(t + 1))  // inc,inx,iny,isb
            /* Store modified value (memory) */
            t("kgnkkgnkkgnkkgnkzy|J    kgnkkgnk ", WB(addr+d, t))
            t("                   q             ", WB(wrap(addr, addr+d), t &= ((addr+d) >> 8))) // [shx,shy,shs,sha?]
            /* Some operations used up one clock cycle that we did not account for yet */
            t("rpstljstqjstrjst - - - -kjstkjst/", tick()) // nop,flag ops,inc,dec,shifts,stack,transregister,interrupts
            /* Stack operations and unconditional jumps */
            t("     !  !    !                   ", tick(); t = Pop())                        // pla,plp,rti
            t("        !   !                    ", RB(PC++); PC = Pop(); PC |= (Pop() << 8)) // rti,rts
            t("            !                    ", RB(PC++))  // rts
            t("!   !                           /", d=PC+(op?-1:1); Push(d>>8); Push(d))      // jsr, interrupts
            t("!   !    8   8                  /", PC = addr) // jmp, jsr, interrupts
            t("!!       !                      /", Push(t))   // pha, php, interrupts
            /* Bitmasks */
            t("! !!  !!  !!  !!  !   !!  !!  !!/", t = 1)
            t("  !   !                   !!  !! ", t <<= 1)
            t("! !   !   !!  !!       !   !   !/", t <<= 2)
            t("  !   !   !   !        !         ", t <<= 4)
            t("   !       !           !   !____ ", t = u8(~t)) // sbc, isb,      clear flag
            t("`^__   !       !               !/", t = c | t)  // ora, slo,      set flag
            t("  !!dc`_  !!  !   !   !!  !!  !  ", t = c & t)  // and, bit, rla, clear/test flag
            t("        _^__                     ", t = c ^ t)  // eor, sre
            /* Conditional branches */
            t("      !       !       !       !  ", if(t)  { tick(); Misfire(PC, addr = s8(addr) + PC); PC=addr; })
            t("  !       !       !       !      ", if(!t) { tick(); Misfire(PC, addr = s8(addr) + PC); PC=addr; })
            /* Addition and subtraction */
            t("            _^__            ____ ", c = t; t += A + P.C; P.V = (c^t) & (A^t) & 0x80; P.C = t & 0x100)
            t("                        ed__98   ", t = c - t; P.C = ~t & 0x100) // cmp,cpx,cpy, dcp, sbx
            /* Store modified value (register) */
            t("aa__aa__aa__ab__ 4 !____    ____ ", A = t)
            t("                    nnnn 4   !   ", X = t) // ldx, dex, tax, inx, tsx,lax,las,sbx
            t("                 !  9988 !       ", Y = t) // ldy, dey, tay, iny
            t("                   4   0         ", S = t) // txs, las, shs
            t("!  ! ! !!  !   !       !   !   !/", P.raw = t & ~0x30) // plp, rti, flag set/clear
            /* Generic status flag updates */
            t("wwwvwwwvwwwvwxwv 5 !}}||{}wv{{wv ", P.N = t & 0x80)
            t("wwwv||wvwwwvwxwv 5 !}}||{}wv{{wv ", P.Z = u8(t) == 0)
            t("             0                   ", P.V = (((t >> 5)+1)&2))         // [arr]
    Last edited by Syscal; 07-08-2013 at 05:52 PM.

  8. #8
    - - - - - - - - oogabooga's Avatar
    Join Date
    Jan 2008
    Posts
    2,808
    It's a way of compressing the source code. He gets the compiler (and preprocessor) to create 264 functions. He encodes the information for the construction of these functions in character-encoded bit-strings.

    This function creates a static jump table for the opcodes (and interrupts).
    Code:
    void Op()
    {
        #define c(n) Ins<0x##n>,Ins<0x##n+1>,
        #define o(n) c(n)c(n+2)c(n+4)c(n+6)
        static void(*const i[0x108])() =
        {
            o(00)o(08)o(10)o(18)o(20)o(28)o(30)o(38)
            o(40)o(48)o(50)o(58)o(60)o(68)o(70)o(78)
            o(80)o(88)o(90)o(98)o(A0)o(A8)o(B0)o(B8)
            o(C0)o(C8)o(D0)o(D8)o(E0)o(E8)o(F0)o(F8) o(100)
        };
    
        unsigned op = RB(PC++);
        i[op]();
    }
    Each o() defines 4 c()'s, which each define two Ins()'s. There are 33 o()'s, so Ins() is instantiated 264 times.

    The program simulates the 6502 using micro-instructions. The list of t()'s in Ins() associates micro-instructions with op-codes. Since the whole thing is done at compile time, a final Ins() might look something like
    Code:
    void Ins()
    {
        unsigned addr=0, d=0, t=0xFF, c=0, sb=0, pbits = op<0x100 ? 0x30 : 0x20;
    
        {
          enum { i = 0x80 };
          ////if (i)   // removed by compiler since always true
          {
            addr=u8(addr+d); d=0; tick();  // THIS MICRO-INSTRUCTION EXECUTED
          }
        }
    
        {
          enum { i = 0x00 };
          ////if (i)   // removed by compiler since always false
          {
            ////RB(wrap(addr, addr+d));
          }
        }
    
        {
          enum { i = 0x02 };
          ////if (i)   // removed by compiler since always true
          {
             t = (t << 1) | (sb * 0x01);  // THIS MICRO-INSTRUCTION EXECUTED
          }
        }
    
        // etc
    }
    So each Ins() instantiation is a different list of micro-instructions designed to carry out that op-code's operation.


    The actual encoding of the bit strings is a little complicated. Note that o8 is set to the high 5 bits of op while o8m is set to a single bit in the location given by the low 3 bits of op. o8 indexes s (the string). o8m will select a bit from the final value given by the conditional operator.

    The t() character strings encode indices into the two character arrays in t() itself. Then THAT character is offset and used to test against the single bit of o8m. If that bit is set, the micro-instruction is included.

  9. #9
    Master Apprentice phantomotap's Avatar
    Join Date
    Jan 2008
    Posts
    4,172
    Code:
    " (),-089<>?BCFGHJLSVWZ[^hlmnxy|}"[s[o8]-94]
    O_o

    I didn't realize you could still do this in C++.

    Soma
    “Often out of periods of losing come the greatest strivings toward a new winning streak.” -- Fred Rogers
    “Salem Was Wrong!” -- Pedant Necromancer

  10. #10
    Registered User
    Join Date
    Jun 2005
    Posts
    6,206
    Quote Originally Posted by phantomotap View Post
    I didn't realize you could still do this in C++.
    Yeah. It's a <cough> wonderful feature of the language, isn't it.
    Right 98% of the time, and don't care about the other 3%.

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Could you guys rate my code?
    By Syscal in forum C Programming
    Replies: 2
    Last Post: 06-22-2013, 06:24 PM
  2. Installer only writes a few KBs
    By binks in forum C Programming
    Replies: 11
    Last Post: 07-21-2011, 11:15 AM
  3. Replies: 1
    Last Post: 04-14-2011, 04:11 AM
  4. What do you guys use to make GUIs in C++?
    By thefeedinghand in forum C++ Programming
    Replies: 11
    Last Post: 01-31-2011, 09:35 PM
  5. OK, guys, here is my code to stop confusion
    By meili100 in forum C++ Programming
    Replies: 10
    Last Post: 11-29-2007, 03:06 PM

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21