| PLEX86 | ||
|
Ridiculous warnings make ridiculous code. 14050
Just to keep in practice... :-) I've already seen Jeff Relf's response so I know he's seen this already. In comp.os.linux.advocacy, Kelsey Bjarnason wrote on Tue, 29 Mar 2005 01:37:54 GMT an implicit printf() warning. Also, printf() is not the best of routines to use here; puts() would be slightly more efficient. However, printf() is extremely general. A good starter, if one doesn't need arguments (if one does main() will of course need the traditional 'int main(int argc, char **argv)'). The main problem with this one is that it has a "magic number", namely, 100. Of course since nothing is done with the pointer after allocation it is far from clear what the number should be (sizeof(astructure)? n * sizeof(astructure)? 65536?) or precisely what it should mean. The cast is unnecessary in C, as I understand it, but is probably going to be added by just about everybody, for clarity. (More modern C++ compilers will accept Presumably this is a bit gloppier from a visual standpoint, but far easier to find in a text editor.) The compiler cannot catch this one. It's either a bug or a feature; the above is a reasonable implementation ofbin-false, except on older versions return. (Returning "0" on pre-4.0 VMS C would be considered a warning or an error; I forget which. The last three bits are what determines the severity. Presumably this quirk has long since been fixed.) The compiler cannot catch this one -- if there's anything to catch. This is a pointer-type mismatch. On most systems one will get 12 doubles, plus 4 bytes left over for giggles. Storing into the 13th "double" in the ensuing array will cause stack corruption on most systems. Fetching past the 12th double may result in segmentation violations and-or address errors. (Note that on HP-UX, the stack goes *up*, not *down*, as things are pushed thereonto; storing into such a stack won't cause too many problems unless the stack is already very deep, although one will fetch anomalous results under certain conditions.) The C compiler cannot catch this one. The C++ compiler will elicit a general warning on the void * pointer buttignment. I'm not sure about this one, but the third argument is probably now an anachronism. Also, the test expression should ideally be 'envpi != NULL' but the usage above is so common it's probably not a big issue. The few signatures I've seen suggest that the second argument should be named 'argp' in this particular case, but that's extremely petty. Buffer overflow problem. The sscanf should be modified to "%31s", or replaced with a more sophisticated loop that reads things a char at a time. (Since most systems have a line buffer this won't be as stupid as one might think -- and it takes some work to specify that it should *not* be line-buffered.) This is not one the compiler can elegantly catch. Also, the & is not appropriate here; arrays are already pointers. A good compiler should catch this one. (A digression, admittedly: C is rather sloppy about pointers and arrays generally. In program File2.c, for instance, a more proper declaration in a quasi-C language might be along the lines of char (*c100); but no one ever bothers. This is not to be confused with Ridiculous warnings make ridiculous code. 14051 In comp.os.linux.advocacy, Kelsey Bjarnason wrote on Sun, 03 Apr 2005 03:13:08 GMT I'd not want to rely on it anyway, but gcc in particular does pick... char (*c)100; What is it's scope In comp.os.linux.advocacy, JeffRelf wrote on 05 Apr 2005 12:25:34 GMT For g++-x86 it's also... which is an array of 100 char pointers.) stdlib.h is misspelled (the compiler quickly catches this one). A usage issue would require that externfunc() be declared in a .h file. rand() is correctly used but the buttert will result in some strangely random failures -- if the compile enables it. However, those strangely random failures may never occur during the lifetime of the computer unless this is in a very frequent inner loop (1 ms * 2^31 = 24.8 days). Note that in its implemented form File7 will always succeed or fail on a given architecture-libc implementation, as rand() is always seeded with 1 and therefore x will be the same value on every run. min() is a problem no matter how one slices it; ideally it would be declared in a system file but I for one don't know which one. However, buttuming it's necessary here the subsbreastution expression needs parentheses around x and y. Also, one of the expressions is evaluated twice (but only one!) because of the designed-in brain-deadedness of CPP; in C++ one can define and the system will take pains to evaluate expressions exactly once, either when construction an actual function call or transliterating the expression into function code inline (as the inline keyword suggests it should do). One can declare a function min() in C if one really wants to, but it does incur a minor performance penalty. The code will print out "X is less" if x == y; this is incorrect logic though the bug is latent as conditions stand in this file. Regex Pattern Matching algorithm in monoc JeffRelf I'm looking at the source code for mono's Regex implementation right now. You can download that source here ( use the clbutt libraries download ). One of the files ( quicksearch.cs -- it's all... The generation of "y++ is less" may or may not occur given x=3 and y=4 in the above depending on the expression parse tree. The problem is that the compiler is actually seeing for the iftest, and the compiler has an interesting decision to make during code dump. 1 It can evaluate the left side of the comparison '==' first, then the right side, then increment either x or y. 2 It can evaluate the right side first, then the left side, then increment x or y. 3 It can evaluate the left side of the comparison '==' first, then increment either x or y, then evaluate the right side. A similar condition exists for the third min(). Here's some additional ones that are even worse. In my previous employer some of these bugs actually bit, and bit very hard, during a project. It was not pretty. * File9.c * char * copyString(char * source) { char * p = (char *) malloc(strlen(source)) strcpy(p, source); return p; } int main() { char * copy = copyString("Hello, world!"); puts(copy); copy = copyString("How are you?"); puts(copy); return 0; } * File10.c * char * generateString() { char buffer128; sprintf(buffer,"Name%d", rand()); return buffer; } int main() { char * newName = generateString(); puts(newName); return 0; } * File11.c * static char bigBuf1048576; static char * bufptr; char * myAlloc(int n) { char * newMem = bufptr; bufptr += n; return newMem; } char * copyString(char * source) { char * newString = myAlloc(strlen(source) + 1);* hint hint * strcpy(newString, source); return newString; } int main() { char * a = copyString("Axis"); char * b = copyString("Beowulf"); char * c = copyString("Coriolis"); char * d = copyString("Dunderheaded"); char ** stringArray = (char **) myAlloc(4 * sizeof(char *)); stringArray0 = a; stringArray1 = b; stringArray2 = c; stringArray3 = d; printf("You've got a string array with %s %s %s %s-n" , stringArray0, stringArray1, stringArray2, stringArray3); return 0; } -- It's still legal to go .sigless.
|
||||||||