Live data from Hacker News

Massacring C Pointers

wozniak.ca

91–100 of 300 posts

Re: Massacring C Pointers

#91
post #9

Yesterday I encountered a similar program on a HN comment chain as shown in this link. I am genuinely confused as to why this program is bad. I am a student and I do not know the best practices regarding pointers, but it is how I would write a program to combine two strings. Can someone please elaborate why it is bad? Are their any good resources to fill gaps in my knowledge? Thanks in advance. Edit: Thank you guys f…

Not a C programmer, so I'm sure I'm missing a ton of more subtle issues, but some of the immediate questions to ask: * What happens if s or t are longer than 100 characters? * What happens if s and t are both longer than 50 characters? * What happens if no element of s == '\0'? How about t? * r is allocated on the stack. What happens to the memory pointed at by r when you call another function after calling combine?…

Back in the day it was pretty much granted you ended your strings with a \0.

Re: Massacring C Pointers

#92
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.

Re: Massacring C Pointers

#93

Yesterday I encountered a similar program on a HN comment chain as shown in this link. I am genuinely confused as to why this program is bad. I am a student and I do not know the best practices regarding pointers, but it is how I would write a program to combine two strings. Can someone please elaborate why it is bad? Are their any good resources to fill gaps in my knowledge? Thanks in advance. Edit: Thank you guys f…

I know there are already plenty of comments about the problems but might as well give mine too...

In one sentence: this guy managed to reinvent a variant of strcat and get it completely wrong.

Here's a somewhat better version:

    char *combine(char *s, char *t) {
        size_t m = strlen(s), n = strlen(t);
        char *ret = malloc(m + n + 1);
        if(ret) {
            memcpy(ret, s, m);
            strcpy(ret + m, t);
        }
        return ret;
    }

Re: Massacring C Pointers

#94
The fixed-location variable allocation strategy the author mentions is called overlaying or compile-time stack[0]. It's still very much alive today, thanks to architectures like 8051 that are not really stack-friendly (even though they do have a stack).

> The Keil C51 C Compiler works with the LX51 Linker to store function arguments and local variables in fixed memory locations using well-defined names

[0] http://www.keil.com/support/man/docs/bl51/bl51_overlaying.ht...

Re: Massacring C Pointers

#95
post #17

Earlier quoted context omitted.

I haven't touched C in years, but here's my descending "wtf" list: 1. Returns pointer to stack-allocated data, which immediately becomes invalid. Instead, it should be using some sort of allocation (e.g. 'malloc'), or taking in a destination pointer. 2. 'r' is arbitrarily set with length 100. Smaller strings don't need all that space, and larger strings definitely will overrun. 3. The function signature is really awk…

> 'strcpy' should usually be replaced by 'strncpy' Sorry to butt in, but this is a bit of a trigger for me: I’ve had to fix a number of programs infected with this idea. The main problems with strncpy are: When the source string is shorter than n, strncpy will pad the target to n bytes, filling with zeros. This is bad for performance. When the source string is longer than n, strncpy will copy n bytes but _not_ nul-te…

I agree with you completely, and in general think the whole idea of using "safe" string functions with built-in buffer length checking is wrong because it is a solution to a symptom, not a cause.

Before writing to the buffer you should've ensured that it's big enough, and decided what to do if it's not, long before actually doing it. In other words, what happens if it's not big enough? These "always use $length_checking_function" proponents miss that point. Yes, you've avoided an overflow here, but chances are something was already too small long before the flow reached here, and the fix is not to replace an overflow with truncate/not copy/etc. here, but fix the check/sizing that came before elsewhere.

Re: Massacring C Pointers

#96
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.

Yoda conditions are protection against an issue that no longer exists in most compilers.

(https://en.wikipedia.org/wiki/Yoda_conditions)

Re: Massacring C Pointers

#97
post #86

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.

Better yet, just use the fact that NULL is false and get shorter, cleaner, and safer code. if (!s)

God no... explicit is better than implicit.

Your statement there just does not read correctly, always have the condition explicit.

Re: Massacring C Pointers

#98
post #90
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…

No, all of that example was malpractice in the 80s when it was written. Note the context: it's highlighted as malpractice in a talk by Brian Kernighan!

I'll bite: argument from authority can be reversed - if Brian didn't mess up the language design, these sorts of "code drivels" wouldn't have appeared! I think you've heard that argument from many language designers already... Then we can argue that back in those times it was something progressive etc. And we are straight back with the argument I was making. When you read StackOverflow, books on Deep Learning or computation on Spark, how much drivel did you go through already? Even the language authors are sometimes confused about some unplanned side effects...

Re: Massacring C Pointers

#99
I've found that it's usually those with embedded systems experience who are most knowledgeable about pointers, but I suppose BASIC experence with embedded systems doesn't count --- the ones I'm referring to usually started in Asm/C, and others I know who started in Asm (not necessarily for embedded), also are extremely good at pointer use.

The modern equivalent would probably be Arduino experience. I wonder if there are similar examples in books out there about C++ written by someone with only that...

Re: Massacring C Pointers

#100

Yesterday I encountered a similar program on a HN comment chain as shown in this link. I am genuinely confused as to why this program is bad. I am a student and I do not know the best practices regarding pointers, but it is how I would write a program to combine two strings. Can someone please elaborate why it is bad? Are their any good resources to fill gaps in my knowledge? Thanks in advance. Edit: Thank you guys f…

I know there are already plenty of comments about the problems but might as well give mine too... In one sentence: this guy managed to reinvent a variant of strcat and get it completely wrong. Here's a somewhat better version: char *combine(char *s, char *t) { size_t m = strlen(s), n = strlen(t); char *ret = malloc(m + n + 1); if(ret) { memcpy(ret, s, m); strcpy(ret + m, t); } return ret; }

Minor bug:

If s and t are very long and overlapping, m + n could wrap around.

Post reply on HN