Live data from Hacker News

C Strings and my slow descent to madness

deusinmachina.net

301–310 of 329 posts

Re: C Strings and my slow descent to madness

#301

Earlier quoted context omitted.

> In C everyone starts out as a "bad programmer" In everything in life one starts out as a "bad ". I would be a bad free diver (I'd probably kill myself). People inexperienced in lack knowledge in . That is not an insult. That's just reality. One can do some pretty serious mistakes as an inexperienced Python programmer (example: async/await) or downhill skier. It's not the language, it's lack of knowledge and experie…

Funnily, GPT-4 seems like it generates pretty bad C code but pretty good Python code. The C code will have silly things, like bad style or `double d = malloc(sizeof(double))` (instead of `double*`), which makes it evident that its training data was full of pretty bad C code. Which makes sense since most C code out there, like on StackOverflow, is bad. Same with Bash code. The worse quality of code available in these…

> Funnily, GPT-4 seems like it generates pretty bad C code but pretty good Python code.

Back when OpenAI had code-specific models based on GPT-n they were generally specifically advertised as best at Python; I suspect their coding-related training data and human feedback on coding tasks all favors Python by a significant amount (and I supect that that actually gets reinforced by positive feedback, since this makes it most likely that they get used with Python over time, too.)

Re: C Strings and my slow descent to madness

#302

Earlier quoted context omitted.

Funnily, GPT-4 seems like it generates pretty bad C code but pretty good Python code. The C code will have silly things, like bad style or `double d = malloc(sizeof(double))` (instead of `double*`), which makes it evident that its training data was full of pretty bad C code. Which makes sense since most C code out there, like on StackOverflow, is bad. Same with Bash code. The worse quality of code available in these…

> Funnily, GPT-4 seems like it generates pretty bad C code but pretty good Python code. Back when OpenAI had code-specific models based on GPT- n they were generally specifically advertised as best at Python; I suspect their coding-related training data and human feedback on coding tasks all favors Python by a significant amount (and I supect that that actually gets reinforced by positive feedback, since this makes i…

:o Huh. I guess it's not a fair sampling of code out in the wild then.

Re: C Strings and my slow descent to madness

#303

Earlier quoted context omitted.

Yeah, and I wouldn't say it's definitely unsafe. You can memchr a '\0' out of it (or not) to determine if a null terminator got in there or not.

I mean, you could but a lot of people do not. Plus, strncpy is terribly inefficient if the source string is tiny, because it’ll fill the rest of the buffer with NULs.

One mans inefficiency is another mans resistance to timing attacks :P

(this is tongue-in-cheek, the function is still bad IMO because it almost never does what you need it to. If it guaranteed null termination it would be more useful)

Re: C Strings and my slow descent to madness

#304

If you are using C and do some non-trivial work with strings you should either use a good library to handle strings or build your own. It is not that difficult in practice. The old C std lib is, in my opinion, outdated, obsolete and a very bad fit for complex string handling, especially on the memory management side. In my own framework, the string management module is using a dedicated memory allocator and a "high l…

> the C std lib is the weakest part of the C language and it should only be used as a fallback. I've been musing for a while now: what would it look like if we were to discard the C library and design a new one, leaving the language itself intact?

GLib is an alternative to the standard library.

Re: C Strings and my slow descent to madness

#305

Earlier quoted context omitted.

> In C everyone starts out as a "bad programmer" In everything in life one starts out as a "bad ". I would be a bad free diver (I'd probably kill myself). People inexperienced in lack knowledge in . That is not an insult. That's just reality. One can do some pretty serious mistakes as an inexperienced Python programmer (example: async/await) or downhill skier. It's not the language, it's lack of knowledge and experie…

Funnily, GPT-4 seems like it generates pretty bad C code but pretty good Python code. The C code will have silly things, like bad style or `double d = malloc(sizeof(double))` (instead of `double*`), which makes it evident that its training data was full of pretty bad C code. Which makes sense since most C code out there, like on StackOverflow, is bad. Same with Bash code. The worse quality of code available in these…

> Funnily, GPT-4 seems like it generates pretty bad C code but pretty good Python code.

It's only a matter of time. And likely not a lot of time.

I asked ChatGPT to write a fast CRC-16 calculation algorithm in ARM assembler given a set of preferred registers and other constraints. I compared it to my own code, written a while back. Not too bad.

It wasn't clever about using assembler tricks experienced assembler coders understand, yet the code passed my test suite. My code was much faster because it was written with the benefit of experience that had me reaching for optimizations ChatGPT did not.

The interesting part was when I asked that it modify the code to work with a different buffer structure and be able to compute CRC-8, CRC-16 and CRC-32 with various modifiers.

It did it in just a few seconds. The code passed 100% of my tests. Not super fast or efficient, but it worked. I remember when I had to do that myself with my own code, it took over a day.

This is today, mid 2023. Give it a year or two (maybe less?) and it will be a tool to contend with. People who like to blame everything else rather than their lack of knowledge and experience will not do very well in that world.

Why would I pay someone to do when they bring nothing special to the table?

Here's the huge paradigm shift (at least for me):

I could not care less what someone knows or does not know. I care about the range and breath of their experience and how they approach learning that which you do not know.

Someone like that can use any available tool, including AI tools, to deliver value in almost any domain. Someone who blames others (tools, people, the system, whatever), cannot.

We might just be entering an era in which experience will be shown to have serious value.

Re: C Strings and my slow descent to madness

#306

Earlier quoted context omitted.

> A knowledgeable software developer, among other things, stays clear of these issues. This is the "no true scotsman" fallacy. Languages can be designed so that less than perfectly knowledgeable programmers fall into the pit of success, or they can be designed so that they fall into the pit of failure. For people making your argument, I like to provide this challenge: Go take a flight on a 737 MAX that hasn't had its…

> This is the "no true scotsman" fallacy. Sorry. Not even close. Source: I actually studied Phisolophy/Logic at Uni. Good try though. Also, your aircraft example is absolutely ridiculous. This isn't an appeal to purity at all. This is about domain knowledge and experience. A more appropriate example might be the contrast between someone who has only done 3D printing now deciding to design and make parts meant for CNC…

> I actually studied Phisolophy/Logic at Uni. Good try though.

Appeal to authority.

PS: I studied philosophy too.

Re: C Strings and my slow descent to madness

#307

If you are using C and do some non-trivial work with strings you should either use a good library to handle strings or build your own. It is not that difficult in practice. The old C std lib is, in my opinion, outdated, obsolete and a very bad fit for complex string handling, especially on the memory management side. In my own framework, the string management module is using a dedicated memory allocator and a "high l…

"If you are using C and do some non-trivial work with strings you should either use a good library to handle strings or build your own." unsigned int str_len(const char *s) { register const char *t; t = s; for (;;) { if (!*t) return t - s; ++t; if (!*t) return t - s; ++t; if (!*t) return t - s; ++t; if (!*t) return t - s; ++t; } } I still use this instead of stdlib strlen. Of course I also use software everyday that…

glibc strlen:

https://sourceware.org/git/?p=glibc.git;a=blob_plain;f=strin...

   #include 
   #include 
   #include 
   #include 
   #include 
   #include 
   
   #ifdef STRLEN
   # define __strlen STRLEN
   #endif
   
   /* Return the length of the null-terminated string STR.  Scan for
      the null terminator quickly by testing four bytes at a time.  */
   size_t
   __strlen (const char *str)
   {
     /* Align pointer to sizeof op_t.  */
     const uintptr_t s_int = (uintptr_t) str;
     const op_t *word_ptr = (const op_t*) PTR_ALIGN_DOWN (str, sizeof (op_t));
   
     op_t word = *word_ptr;
     find_t mask = shift_find (find_zero_all (word), s_int);
     if (mask != 0)
       return index_first (mask);
   
     do
       word = *++word_ptr;
     while (! has_zero (word));
   
     return ((const char *) word_ptr) + index_first_zero (word) - str;
   }
   #ifndef STRLEN
   weak_alias (__strlen, strlen)
   libc_hidden_builtin_def (strlen)
   #endif
   
NetBSD common strlen:

https://ftp.netbsd.org/pub/NetBSD/NetBSD-current/src/common/...

   size_t
   strlen(const char *str)
   {
   const char *s;
   
   for (s = str; *s; ++s)
   continue;
   return(s - str);
   }
Apple strlen:

https://opensource.apple.com/source/Libc/Libc-1244.50.9/stri...

Apple strlen comes from FreeBSD. Until 2009, FreeBSD used an unoptimised strlen.

https://svnweb.FreeBSD.org/base/head/lib/libc/string/strlen....

   size_t
   strlen(str)
           const char *str;
   {
           const char *s;
   
           for (s = str; *s; ++s);
           return(s - str);
   }

FreeBSD eventually copied^1 NetBSD's x86_64 strlen.

1. "modeled after", "inspired by", etc.

https://svnweb.FreeBSD.org/base?view=revision&revision=18770...

   #include 
   __FBSDID("$FreeBSD$");
   
   #include 
   #include 
   #include 
   
   /*
    * Portable strlen() for 32-bit and 64-bit systems.
    *
    * Rationale: it is generally much more efficient to do word length
    * operations and avoid branches on modern computer systems, as
    * compared to byte-length operations with a lot of branches.
    *
    * The expression:
    *
    *      ((x - 0x01....01) & ~x & 0x80....80)
    *
    * would evaluate to a non-zero value iff any of the bytes in the
    * original word is zero.  However, we can further reduce ~1/3 of
    * time if we consider that strlen() usually operate on 7-bit ASCII
    * by employing the following expression, which allows false positive
    * when high bit of 1 and use the tail case to catch these case:
    *
    *      ((x - 0x01....01) & 0x80....80)
    *
    * This is more than 5.2 times as compared to the raw implementation
    * on Intel T7300 under EM64T mode for strings longer than word length.
    */
   
   /* Magic numbers for the algorithm */
   #if LONG_BIT == 32
   static const unsigned long mask01 = 0x01010101;
   static const unsigned long mask80 = 0x80808080;
   #elif LONG_BIT == 64
   static const unsigned long mask01 = 0x0101010101010101;
   static const unsigned long mask80 = 0x8080808080808080;
   #else
   #error Unsupported word size
   #endif
   
   #define LONGPTR_MASK (sizeof(long) - 1)
   
   /*
    * Helper macro to return string length if we caught the zero
    * byte.
    */
   #define testbyte(x)                             \
           do {                                    \
                   if (p[x] == '\0')               \
                       return (p - str + x);       \
           } while (0)
   
   size_t
   strlen(const char *str)
   {
           const char *p;
           const unsigned long *lp;
   
           /* Skip the first few bytes until we have an aligned p */
           for (p = str; (uintptr_t)p & LONGPTR_MASK; p++)
               if (*p == '\0')
                   return (p - str);
   
           /* Scan the rest of the string using word sized operation */
           for (lp = (const unsigned long *)p; ; lp++)
               if ((*lp - mask01) & mask80) {
                   p = (const char *)(lp);
                   testbyte(0);
                   testbyte(1);
                   testbyte(2);
                   testbyte(3);
   #if (LONG_BIT >= 64)
                   testbyte(4);
                   testbyte(5);
                   testbyte(6);
                   testbyte(7);
   #endif
               }
   
           /* NOTREACHED */
           return 0;
   }

Re: C Strings and my slow descent to madness

#308

Earlier quoted context omitted.

One could take a glance at these and easily believe that they do the right thing. I don’t think that no one would accidentally miss such a small error from time to time.

Of course, and the more experience you have the less of this will happen. I've been writing software in over a dozen languages for over 30 years. Generally speaking, when I write code, even complex code, in any language, it just works. Not because I am something special. I have done a lot of of work across a wide range of application domains and have made my share of mistakes over the years. Of course I make mistakes…

So, there are no bad tools, no bad languages, ever? A chainsaw without hand guard is a fine tool, and the blame is on whoever got their own arm chopped?

I find that dubious, to say the least. Languages are not all equal, obviously. You can take an existing language and make it worse by removing some useful features of degrading existing ones; so why couldn't you make it better? In the case of C, its string handling has been proven time and time again to be a (collection of) footgun.

Re: C Strings and my slow descent to madness

#309

Earlier quoted context omitted.

> This is the "no true scotsman" fallacy. Sorry. Not even close. Source: I actually studied Phisolophy/Logic at Uni. Good try though. Also, your aircraft example is absolutely ridiculous. This isn't an appeal to purity at all. This is about domain knowledge and experience. A more appropriate example might be the contrast between someone who has only done 3D printing now deciding to design and make parts meant for CNC…

> I actually studied Phisolophy/Logic at Uni. Good try though. Appeal to authority. PS: I studied philosophy too.

Nope. Wrong again. You should probably take that class again.

I am telling you that I evaluated your claim, I didn’t google it or ask ChatGPT.

Re: C Strings and my slow descent to madness

#310
post #308

Earlier quoted context omitted.

Of course, and the more experience you have the less of this will happen. I've been writing software in over a dozen languages for over 30 years. Generally speaking, when I write code, even complex code, in any language, it just works. Not because I am something special. I have done a lot of of work across a wide range of application domains and have made my share of mistakes over the years. Of course I make mistakes…

So, there are no bad tools, no bad languages, ever? A chainsaw without hand guard is a fine tool, and the blame is on whoever got their own arm chopped? I find that dubious, to say the least. Languages are not all equal, obviously. You can take an existing language and make it worse by removing some useful features of degrading existing ones; so why couldn't you make it better? In the case of C, its string handling h…

> A chainsaw without hand guard is a fine tool, and the blame is on whoever got their own arm chopped?

I think you are stretching it. Still, let's go with it.

I have done a ton of construction work in my life. From large projects at home ($200K-ish) to managing the build of a $12MM data center I designed. Because of this I have been around construction guys of all kinds and skill levels. And, of course, I have a lot of personal experience doing the work as well, from carpentry to just-about anything in a typical home or commercial project.

Anyhow, I always cringe when I see experienced construction guys work with modified tools that have had safeties removed to make the work go faster. One example of this was when I watched these guys cutting concrete blocks with a handheld grinder. They had removed the guard that typically covers half the blade. The entire blade was fully open and spinning at 10K+ RPM. When asked they said they'd been doing it this way for twenty years, it's faster, they can see the cut and control it far better. Still had all fingers.

Same is true of guys cutting framing lumber with circular saws or skillsaw's while propping-up the pieces with their bodies.

To me, someone with not even 10% of the experience they have, that was unthinkable. I would have lost fingers and limbs. I would have ended-up in the hospital almost instantly and possibly take others with me.

It's a relative term. Are the tools bad? Well, when experienced professionals can use them safely day in and out (this is their job, they've been doing it this way every day for twenty years), can we really blame the tool of I grab it and proceed to remove a finger or three?

No. Of course not. I know the American system of liability doesn't work that way, but that would be and should be 100% my fault for not having the experience necessary to approach such a thing safely.

It's the same thing, it doesn't matter if we are talking about coding, CNC machining or downhill skiing. Newbies love to blame the skis for what they did wrong, or the $150K CNC machine for crashing the $10K spindle into the table. It's never their fault. Sure.

Post reply on HN