The angry programmer thread (24)

1 Name: !WAHa.06x36 2005-08-15 22:49 ID:oZGYsOI+

In this thread we rant and rave when the world conspires against us! Allow me to start by quoting the Apple Cocoa reference docs:

draggingEnded:

- (void)draggingEnded:(id <NSDraggingInfo>)sender

Implement this method to be notified when a drag operation ends in some other destination. This method might be used by a destination doing autoexpansion in order to collapse any autoexpands. sender contains details about the dragging operation. This method has not yet been implemented.

What the FUCK? What the hell is this shit doing in the docs, then? Jesus fucking fuck, I just lost fifteen minutes of my life trying to figure out why it was doing nothing! I was in a foul mood already, and I don't need some fucking Apple engineer's little practical joke to deal with on top of everything else.

2 Name: #!usr/bin/anon 2005-08-16 18:39 ID:rfL7R8n9

In 1987, Bantam published The Official GEOS Programmer's Reference Guide, a nice book for writing assembly programs for GEOS on the Commodore 64. However, so much information was inaccurate and so much more was missing that I was never able to keep straight where exactly some functions were and how to use them well. For example, GEOS had the ability to page variable-length portions of program and data files into memory by what were called "variable length indexed record" (VLIR) files, but Bantam's guide didn't accurately document how.

http://en.wikipedia.org/wiki/GEOS_%288-bit_operating_system%29

3 Name: !WAHa.06x36 2005-08-16 19:33 ID:oZGYsOI+

>>2

You are a master at holding grudges!

4 Name: #!usr/bin/anon 2005-08-17 00:46 ID:rfL7R8n9

>>3 -- You asked... :3

5 Name: #!usr/bin/anon 2005-09-09 22:09 ID:q8XgBXk1

I am supposed to port about 50 pages of printed-out, uncommented pascal code to Visual Basic, using MS Access as the database system. As if that wasn't bad enough, documentation is nonexistant, global variables are used everywhere and the variable names are super-duper-descriptive (lf_ghlt_f, abz_f_pr etc...). Hours of fun.

6 Name: #!usr/bin/anon 2005-09-10 16:09 ID:p+bem3ds

Once I tried to convert the INTERCAL manual to html (because it's in roff, which is completely unreadable, and groff -Tps covers the last two pages in black which can't be good for the toner supply). I stopped after discovering CSS counters, making fancy automatic section numbering with them, and discovering that Opera was the only browser to support them.

7 Name: #!usr/bin/anon 2005-09-10 16:22 ID:Heaven

Getting a new job would probably be less painful.

8 Name: #!/usr/bin/anon 2006-01-17 00:57 ID:WBWEvxEy

Aargh! Why the hell does strchr(somestring, '\0') succeed and locate the '\0' rather than returning NULL? What a load of garbage.

I just traced a segfault in one of my programs to this. strchr, fuck you. I'm sure that's a historical vestige of a bug in the 1977 implementation or something retarded like that. I hate C.

9 Name: dmpk2k!hinhT6kz2E 2006-01-17 03:04 ID:Heaven

I don't get it. Why shouldn't it work like that?

10 Name: #!/usr/bin/anon 2006-01-17 04:05 ID:WBWEvxEy

Because there's already a perfectly good way to find the terminator (&p[strlen(p)]) and because if strchr() didn't find the '\0', I could do things like

while (strchr("ABCDEFGHIJKLMNOPQRSTUVWXYZ", *p) == NULL)
p++;

to move to the first character that's not an uppercase letter. Instead I have to do

while (*p != '\0' && strchr("ABCDEFGHIJKLMNOPQRSTUVWXYZ", *p) == NULL)
p++;

Being able to use strchr() for determining if a character is a member of a set of characters would be far more useful than using strchr(s, '\0') as a synonym for &s[strlen(s)]. And yeah, I can still do it, but the extra pointless comparison is annoying, since this is the kind of thing I normally use strchr to do.

11 Name: #!/usr/bin/anon 2006-01-17 05:31 ID:OU5K9G1R

>>10
Eh, strchr(foo, '\0') does exactly what it advertises. Complaining about the extra work of making a comparison is kind of silly when you're using C to begin with.

12 Name: #!/usr/bin/anon 2006-01-17 06:53 ID:WYCdDF6x

Mainining over a million lines of php code, without a lick of version control.

containing shit like:

foreach ($array as $key=>$value) {
if ($foo == $searchkey) {
doSomething($value);
break;
}
}

And:

file1.php:

<?php
switch ($foo) {
case 'something': foo(); break;
case 'somethingelse': bar(); break;

file2.php:

<?php
include('file1.php');
case 'AND SOMETHING MORE': baz(); break;
}

I quit. I enjoyed every moment of my 4 weeks notice, smiling, dancing, happy, for the first time in my life, I could see the end of the horror.

13 Name: dmpk2k!hinhT6kz2E 2006-01-17 06:56 ID:Heaven

>>10
Well, thing is, not all arrays are null terminated. Once you recognize that, strchr()s behaviour is no longer all that surprising. Admittedly, using strchr() on such an array can be dangerous if you're not careful.

I think a more legitimate complaint is that we have null-terminated strings in C at all. It'd be nice if they updated C's standard libraries to reflect the times...

14 Name: #!/usr/bin/anon 2006-01-17 16:12 ID:WBWEvxEy

>>11,13
strchr()'s argument is a C string, which by definition has a terminating NUL. That NUL isn't part of the string, it designates the end of the string. The behavior of strchr(foo, '\0') also requires extra code to implement; compare:

char *decent_strchr(const char *s, int c) {
while (*s != '\0' && *s != c) s++;
if (*s == '\0') return NULL;
return s;
}
char *strchr(const char *s, int c) {
while (*s != '\0' && *s != c) s++;
if (*s == '\0' && c != '\0') return NULL;
return s;
}

Also, I just realized that strchr() takes a pointer to const char, and returns a pointer to non-const char, in the same buffer... smooth.

15 Name: !WAHa.06x36 2006-01-17 20:17 ID:jXSBUI2k

While I agree with your assessment that the behavior of strchr() doesn't really make sense, I wouldn't write code like >>10 in the first place. Not explicitly checking for NULs when parsing strings feels horribly shaky, no matter if the code happens to work anyway. I would have written that like this, probably:

while(*p) if(!strchr("ABCDEFGHIJKLMNOPQRSTUVWXYZ",*p++)) break;

16 Name: !WAHa.06x36 2006-01-17 20:19 ID:jXSBUI2k

(Of course, I wouldn't have really done that, I would have used *p>='A'&&*p<='Z', but let's assume your example was a simplifcation of a more complex set.)

17 Name: dmpk2k!hinhT6kz2E 2006-01-17 22:48 ID:Heaven

strchr()s design is strange because of the limitations imposed by null terminated strings.

Imagine that I'm capturing binary data off some interface into a character array. I need to check if this data contains arbitrary values. I can use strchr() to do this, provided I insert a \0 for the last value. This is possible because someone decided not to limit strchr().

It would be nicer in both cases if NULL were returned if nothing were found, but that kind of general design is only possible with pascal-style strings.

> and returns a pointer to non-const char,

And what exactly is it supposed to do?

18 Name: #!/usr/bin/anon 2006-01-17 23:34 ID:WBWEvxEy

> I can use strchr() to do this,

Wrong. There might be a '\0' in the middle of the array, and strchr() won't find anything after that. str*() are only useful for C strings, which are NUL-terminated and do not contain internal NUL bytes.

What strchr() should return is a const char *. In "const char *", the "const" refers to the memory being pointed to, not the pointer. Treating a "char *" as "const char *" is safe, but the reverse (which strchr() conveniently automatically does) isn't.

19 Name: dmpk2k!hinhT6kz2E 2006-01-18 02:23 ID:Heaven

> There might be a '\0' in the middle of the array

Uh, that was the point. What if want to search for \0 in a character array? Binary data does not contain 255 values.

> What strchr() should return is a const char *.

Provided that were possible, why should it?

> In "const char *", the "const" refers to the memory being pointed to, not the pointer

Huh? If I understand what you're saying, that's impossible.

I think you misunderstand the purpose behind the const char * in strchr()s declaration. All that means is the function promises the caller it won't modify the string (and even that is by no means assured).

20 Name: dmpk2k!hinhT6kz2E 2006-01-18 02:31 ID:Heaven

Ah, never mind. I see where you're coming from.

I still think it's a bit silly though. If you call a function with an inline string, even if the returned pointer were const, the string is no longer there anyway.

21 Name: #!/usr/bin/anon 2006-01-18 02:36 ID:Heaven

Think of the array

const char foo[] = "abcdefg\0hij";

which is some binary data. Suppose you want to look for the 'h' in that binary data. strchr() will not find it for you because the '\0' right before ends the string.

Also, it's entirely possible for a function to return "const char *".

22 Name: #!/usr/bin/anon 2006-01-18 02:39 ID:Heaven

>>20
Strings like "abcdef" in strchr("abcdef", ch) are always "there". They're usually stored in a read-only block of memory. It's no different from if you did

char *foo = "abcdef";
bar() { baz = strchr(foo, ch); }

23 Name: dmpk2k!hinhT6kz2E 2006-01-18 03:24 ID:Heaven

Yeah, I realized I wrong after I posted. It's a wonder what a walk in fresh air can do.

24 Name: #!/usr/bin/anon 2006-01-21 08:59 ID:Heaven

>>12

Congratulations, and good luck with future endeavors.

This thread has been closed. You cannot post in this thread any longer.