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.
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
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.
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.
Getting a new job would probably be less painful.
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.
I don't get it. Why shouldn't it work like that?
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.
>>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.
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.
>>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...
>>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.
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;
(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.)
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?
> 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.
> 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).
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.
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 *".
>>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); }
Yeah, I realized I wrong after I posted. It's a wonder what a walk in fresh air can do.
Congratulations, and good luck with future endeavors.