Live data from Hacker News

Massacring C Pointers

wozniak.ca

101–110 of 300 posts

Re: Massacring C Pointers

#101
post #81

C'mon, viewing a book from 1990 with the lens of 2018 must be funny of course; almost nothing in programming languages aged well, baring some theoretical principles. Many of the things the book author tried to avoid (like not using integer indexes) were necessary for writing fast code on 4MHz processors with 256kB of RAM in primitive compilers back in the day... Can you please add some xBase book review to the mix fo…

Hindsight isn't really in play, here. The examples given are just plain wrong, rather than outmoded.

Back in those days 100 bytes was like a huge string; when you raised your hands that there will be a problem you were told to shut up, that you don't get the efficiency of computing and that you won't see strings longer than 16 characters or similar. This Zeitgeist is completely lost and viewing it with contemporary optics is just funny at best. IIRC most of early hacks on Internet exploited the lack of boundaries in strings and returning pointers on stack, which is something the book author got wrong but given how wide-spread it was, likely most of C programmers were doing it incorrectly. With contemporary optics I'd tend to say: "It's purely fault of C language designers!" but I know better.

Re: Massacring C Pointers

#102
post #27

Earlier quoted context omitted.

Most of these points are covered by the other comments. As a C programmer professionally, I'll go into a little more depth, and offer an alternative implementation for comparison. The function in question: char *combine(s, t) char *s, *t; { int x, y; char r[100]; strcpy(r, s); y = strlen(r); for (x = y; *t != '\0'; ++x) r[x] = *t++; r[x] = '\0'; return(r); } 1. The array 'r' is allocated on the stack, and returned fr…

if (NULL == s) Ouch. I haven't seen a single case where this abomination actually helped catching the fearsome 'if (s = NULL)' typo. One needs to be a sloppy typist, not paying attention to what they write, not proof-reading the code before committing and ignoring compiler warnings for this disaster of a notation to be even remotely justified.

And thus in your disgust you have actually given a case where this convention might actually save somebody time. If it happens to end up being your own time, you ought to be thankful for it. You certainly don't want it to be wasting your customer's time.

I actually recently saw an 'if (x = 0)' or similar get caught in review recently. Time pressure increases, tests are rushed, and authors proof-read the code in their head, and not what's on the screen. These things do happen, and if your personal style preferences get in the way of using a simple trick to save your own time at best case, or multiple other people's time at worst, then you might wish to reconsider your preferences - even if it is at 1 in 1000 odds.

Re: Massacring C Pointers

#103

Earlier quoted context omitted.

I would say "it depends". Just as poor programmers came later from Visual Basic, or MSVC++ (somehow we went through a phase were everyone coming for interview with MSVC++ actually had C with classes, and for a while it was a warning sign and standing joke at the place I then worked). Getting people who claimed C++ who actually knew it was pretty challenging around the millennium. In the 80s just about everyone who ha…

Might be totally wrong, but it's possible that MSVC++ programmers typically knowing 'C with classes' might come from the gaming world, as that's a fairly accurate description of some very popular game engines (Valve's Source engine[1] being the one I'm most familiar with, where e.g. std::string is unused in favor of char/wchar arrays). [1] https://github.com/ValveSoftware/source-sdk-2013 (originally released in 2004)

It is a bit more complicated than that.

C wasn't much used in MS-DOS, as it was yet another systems language trying to gain the place of Assembly for high performance applications.

In some countries Pascal dialects (mostly TP compatible), Modula-2 reigned, while in others C and C++ were other contenders.

By the time Windows (written in C) became mature enough people started caring about it (3.x), C++ was already having its place via OWL (later VCL) on the Borland side, and Microsoft eventually came up with MFC.

However these were the days when C++ still didn't had a standard (which came in 1998), beyond the C++ARM book, so either you would stick with the compiler framework, or try to minimize language features for better portability.

Additionally on Windows everyone was learning it via Petzold's book, where he takes the approach C compiled with C++, not even "C with Classes".

Also although OWL and VCL were great OOP libraries with nice abstractions, MFC was pretty much a Win32 thin wrapper as its initial internal implementation (AFX) wasn't well received by internal MS employees as not being low level enough over Win32.

So there were lots of issues going on that lead to such cases.

Re: Massacring C Pointers

#105

Earlier quoted context omitted.

if (NULL == s) Ouch. I haven't seen a single case where this abomination actually helped catching the fearsome 'if (s = NULL)' typo. One needs to be a sloppy typist, not paying attention to what they write, not proof-reading the code before committing and ignoring compiler warnings for this disaster of a notation to be even remotely justified.

Yoda conditions are protection against an issue that no longer exists in most compilers. ( https://en.wikipedia.org/wiki/Yoda_conditions )

Precisely! Yet they still pop up and ruin readability of the code just the same.

Re: Massacring C Pointers

#107

A few years ago, I saw a classroom video (I would guess ~8-10 year olds, in the American public school system) as a demonstration of a teacher's technique called "my favourite wrong answer". She would have them solve a problem (a math problem, in this particular case), collect the answers, show the distribution of the answers, and then pick out one answer (possibly with the student's name redacted) as her "favourite…

Where I was teaching, we've started doing code review in classroom in basically the same spirit.

The amount of students prevents us from real selection, instead we take exercises which failed tests (and that are not empty) and explain what was wrong, identify common mistakes or bad style and try to make it correct.

We had a very good feedback on this. And we saw an evolution in students' code. It was way better than trying to do collection of bad practice ...

Re: Massacring C Pointers

#108
post #102

Earlier quoted context omitted.

if (NULL == s) Ouch. I haven't seen a single case where this abomination actually helped catching the fearsome 'if (s = NULL)' typo. One needs to be a sloppy typist, not paying attention to what they write, not proof-reading the code before committing and ignoring compiler warnings for this disaster of a notation to be even remotely justified.

And thus in your disgust you have actually given a case where this convention might actually save somebody time. If it happens to end up being your own time, you ought to be thankful for it. You certainly don't want it to be wasting your customer's time. I actually recently saw an 'if (x = 0)' or similar get caught in review recently. Time pressure increases, tests are rushed, and authors proof-read the code in their…

For all intents and purposes this is one of many typo classes that just happens to have a cute "antidote", and which also has been all but rendered pointless by the existence of respective compiler warnings.

I've seen weirder stuff get through the reviews and compile cleanly, something like "f,()". Typos happen, but (a) it's not a good enough reason to make the code less readable (b) if the code is prone to this sort of errors, just pay closer attention to them during the review phase. Hedging against a single exotic type of mistake that virtually never happens at the expense of code readability is unacceptable.

Re: Massacring C Pointers

#109
post #101

Earlier quoted context omitted.

Hindsight isn't really in play, here. The examples given are just plain wrong, rather than outmoded.

Back in those days 100 bytes was like a huge string; when you raised your hands that there will be a problem you were told to shut up, that you don't get the efficiency of computing and that you won't see strings longer than 16 characters or similar. This Zeitgeist is completely lost and viewing it with contemporary optics is just funny at best. IIRC most of early hacks on Internet exploited the lack of boundaries in…

This doesn't explain why one would ever want to return a pointer to a local variable.

Re: Massacring C Pointers

#110
post #63
post #24

Earlier quoted context omitted.

It is wrong in many ways. It copies s and then t to a fixed size buffer, without any checks. That will write to invalid memory (probably smashing the stack) if len(s), len(t) or len(s) + len(t) > 100. It returns a stack allocated buffer (r) pointer to the caller. The array will be invalid when the function returns, as the automatic variables only live in the function scope (during the call), they are deallocated when…

You're right, although any mention of strncpy should come with a big disclaimer that it's effectively broken because you can end up with a non-NULL terminated string in some cases. strlcpy should be the way to go but unfortunately it's not part of the C standard and not available everywhere (sometimes for rather bullshit reason IMO, but that's a different story).

Documented behaviour is a little different to "effectively broken". The difference between strncpy and strlcpy is that strlcpy will NUL terminate the last byte for you always. There is nothing stopping you from doing the same thing yourself when you use strncpy. If you care enough, write your own strlcpy - it's only one extra line.
Post reply on HN