Close Menu
    DevStackTipsDevStackTips
    • Home
    • News & Updates
      1. Tech & Work
      2. View All

      June 2025: All AI updates from the past month

      June 30, 2025

      Building a culture that will drive platform engineering success

      June 30, 2025

      Gartner: More than 40% of agentic AI projects will be canceled in the next few years

      June 30, 2025

      Never Stop Exploring (July 2025 Wallpapers Edition)

      June 30, 2025

      I never thought I’d praise a kickstand power bank – until I tried this one

      June 30, 2025

      I replaced my work PC with this Alienware laptop – now I’m wondering why I hadn’t done this sooner

      June 30, 2025

      How to set up Alexa to receive notifications on Prime Day deals you want

      June 30, 2025

      How proxy servers actually work, and why they’re so valuable

      June 30, 2025
    • Development
      1. Algorithms & Data Structures
      2. Artificial Intelligence
      3. Back-End Development
      4. Databases
      5. Front-End Development
      6. Libraries & Frameworks
      7. Machine Learning
      8. Security
      9. Software Engineering
      10. Tools & IDEs
      11. Web Design
      12. Web Development
      13. Web Security
      14. Programming Languages
        • PHP
        • JavaScript
      Featured

      Top 6 MySQL Database Management Struggles for Laravel Developers (And Smart Fixes)

      June 30, 2025
      Recent

      Top 6 MySQL Database Management Struggles for Laravel Developers (And Smart Fixes)

      June 30, 2025

      What’s the difference between named functions and arrow functions in JavaScript?

      June 30, 2025

      Spring Boot + Swagger: A Complete Guide to API Documentation

      June 30, 2025
    • Operating Systems
      1. Windows
      2. Linux
      3. macOS
      Featured

      Relive the Golden Era: 5 Tools to Get Retro Feel on Linux

      June 30, 2025
      Recent

      Relive the Golden Era: 5 Tools to Get Retro Feel on Linux

      June 30, 2025

      mpvc – mpc-like CLI tool for mpv

      June 30, 2025

      sherpa-onnx is speech-to-text and text-to-speech software

      June 30, 2025
    • Learning Resources
      • Books
      • Cheatsheets
      • Tutorials & Guides
    Home»News & Updates»CodeSOD: itouhhh…

    CodeSOD: itouhhh…

    May 14, 2025

    Frequently in programming, we can make a tradeoff: use less (or more) CPU in exchange for using more (or less) memory. Lookup tables are a great example: use a big pile of memory to turn complicated calculations into O(1) operations.

    So, for example, implementing itoa, the C library function for turning an integer into a character array (aka, a string), you could maybe make it more efficient using a lookup table.

    I say “maybe”, because Helen inherited some C code that, well, even if it were more efficient, it doesn’t help because it’s wrong.

    Let’s start with the lookup table:

    char an[1000][3] = 
    {
    	{'0','0','0'},{'0','0','1'},{'0','0','2'},{'0','0','3'},{'0','0','4'},{'0','0','5'},{'0','0','6'},{'0','0','7'},{'0','0','8'},{'0','0','9'},
    	{'0','1','0'},{'0','1','1'},{'0','1','2'},{'0','1','3'},{'0','1','4'},{'0','1','5'},{'0','1','6'},{'0','1','7'},{'0','1','8'},{'0','1','9'},
        …
    

    I’m abbreviating the lookup table for now. This lookup table is meant to be use to convert every number from 0…999 into a string representation.

    Let’s take a look at how it’s used.

    int ll = f->cfg.len_len;
    long dl = f->data_len;
    // Prepare length
    if ( NULL == dst )
    {
        dst_len = f->data_len + ll + 1 ;
        dst = (char*) malloc ( dst_len );
    }
    else
    //if( dst_len < ll + dl )
    if( dst_len < (unsigned) (ll + dl) )
    {
        // TO DOO - error should be processed
        break;
    }
    long i2;
    switch ( f->cfg.len_fmt)
    {
        case ASCII_FORM:
        {
            if ( ll < 2 )
            {
                dst[0]=an[dl][2];
            }
            else if ( ll < 3 )
            {
                dst[0]=an[dl][1];
                dst[1]=an[dl][2];
            }
            else if ( ll < 4 )
            {
                dst[0]=an[dl][0];
                dst[1]=an[dl][1];
                dst[2]=an[dl][2];
            }
            else if ( ll < 5 )
            {
                i2 = dl / 1000;
                dst[0]=an[i2][2];
                i2 = dl % 1000;
                dst[3]=an[i2][2];
                dst[2]=an[i2][1];
                dst[1]=an[i2][0];
            }
            else if ( ll < 6 )
            {
                i2 = dl / 1000;
                dst[0]=an[i2][1];
                dst[1]=an[i2][2];
                i2 = dl % 1000;
                dst[4]=an[i2][2];
                dst[3]=an[i2][1];
                dst[2]=an[i2][0];
            }
            else
            {
                // General case
                for ( int k = ll  ; k > 0  ; k-- )
                {
                    dst[k-1] ='0' + dl % 10;
                    dl/=10;
                }
            }
    
            dst[dl]=0;
    
            break;
        }
    }
    

    Okay, we start with some reasonable bounds checking. I have no idea what to make of a struct member called len_len– the length of the length? I’m lacking some context here.

    Then we get into the switch statement. For all values less than 4 digits, everything makes sense, more or less. I’m not sure what the point of using a 2D array for you lookup table is if you’re also copying one character at a time, but for such a small number of copies I’m sure it’s fine.

    But then we get into the len_lens longer than 3, and we start dividing by 1000 so that our lookup table continues to work. Which, again, I guess is fine, but I’m still left wondering why we’re doing this, why this specific chain of optimizations is what we need to do. And frankly, why we couldn’t just use itoa or a similar library function which already does this and is probably more optimized than anything I’m going to write.

    When we have an output longer than 5 characters, we just use a naive for-loop and some modulus as our “general” case.

    So no, I don’t like this code. It reeks of premature optimization, and it also has the vibe of someone starting to optimize without fully understanding the problem they were optimizing, and trying to change course midstream without changing their solution.

    But there’s a punchline to all of this. Because, you see, I skipped most of the lookup table. Would you like to see how it ends? Of course you do:

    {'9','8','0'},{'9','8','1'},{'9','8','2'},{'9','8','3'},{'9','8','4'},{'9','8','5'},{'9','8','6'},{'9','8','7'},{'9','8','8'},{'9','8','9'}
    };
    

    The lookup table doesn’t work for values from 990 to 999. There are just no entries there. All this effort to optimize converting integers to text and we end up here: with a function that doesn’t work for 1% of the possible values it could receive. And, given that the result is an out-of-bounds array access, it fails with everyone’s favorite problem: undefined behavior. Usually it’ll segfault, but who knows! Maybe it returns whatever bytes it finds? Maybe it sends the nasal demons after you. The compiler is allowed to do anything.

    [Advertisement]
    ProGet’s got you covered with security and access controls on your NuGet feeds. Learn more.

    Source: Read More 

    Facebook Twitter Reddit Email Copy Link
    Previous ArticleMlmmj is a simple and slim mailing list manager
    Next Article FreeBSD is an operating system powering servers and desktops

    Related Posts

    News & Updates

    I never thought I’d praise a kickstand power bank – until I tried this one

    June 30, 2025
    News & Updates

    I replaced my work PC with this Alienware laptop – now I’m wondering why I hadn’t done this sooner

    June 30, 2025
    Leave A Reply Cancel Reply

    For security, use of Google's reCAPTCHA service is required which is subject to the Google Privacy Policy and Terms of Use.

    Continue Reading

    CVE-2025-42998 – SAP Business One Authentication Bypass

    Common Vulnerabilities and Exposures (CVEs)

    ELI5 Toolkit – Explain It Like I’m 5

    Development

    CVE-2025-5304 – PT Project Notebooks WordPress Privilege Escalation

    Common Vulnerabilities and Exposures (CVEs)

    How Node.js Handles Async Operations

    Development

    Highlights

    Microsoft’s Latest Copilot Update Will Change How You Work Forever

    April 24, 2025

    Microsoft just dropped some big updates to its 365 Copilot, and it’s all about making…

    CVE-2025-5940 – Osom Blocks – WordPress Stored Cross-Site Scripting

    June 27, 2025

    CVE-2022-45114 – Apache Struts Remote Code Execution Vulnerability

    May 28, 2025

    AI and Machine Learning in Selenium Testing: Revolutionizing Test Automation

    June 19, 2025
    © DevStackTips 2025. All rights reserved.
    • Contact
    • Privacy Policy

    Type above and press Enter to search. Press Esc to cancel.