CompuServe Thread

Forum unknown · Off the Cuff

What goes where?

29 messages in this thread
#109164From: John DraperFeb 14, 1988 5:53 PM
Rick, I fear you misunderstand. It is the general run of C coders who insist upon finding out just how much they can get away with. I hear the refreain oops.. make that refrain, over and over again. "We don't want strong type checking because we want the compiler to assume we know what we are doing." Most C programmers do not cast everything, probably because it would destroy most of their argument about the relative terseness of the language. I would also pointout that the best way to learn a language is to look at the examples of others, and I would suggest that most C programs (read most as >80%) are not as you describe, but are haphazard in their casting, sloppy in other ways, and generally poor by your definition. You are right about not using it if I don't like it. I don't, and I don't. I am not a fanatic about not using it, and have been known to write C on occasion, but much prefer languages that have more strict rules about how your source is treated. Regards, Larry.
#109455From: Richard Rae/SYSOPFeb 16, 1988 3:58 PM
I cannot comment on "the general run of C users" or "most C programmers" I can only comment on my practices and the code I write. You have specific arguments against the language. I am attempting to point out that, by putting down preconceived notions and approaching the language with a given attitude, THOSE PROBLEMS GO AWAY. "'We don't want strong type checking because we want the compiler to assume we know what we are doing." No comment to the first part, agreed to the second part. I don't want a compiler to decide ANYTHING, though I don't terribly mind it saying "Hey, are you SURE you wanted to do this? I'll compile it, but I thought I should mention it…". If I make a syntax error, I expect to be flagged. If I do something that looks strange, I want the compiler to accept it on the assumption that I DO KNOW WHAT I AM DOING. C and assembler fit this bill nicely. Warnings are okay; being forced through hoops to do something I *KNOW* I want to do, but the compiler can't see the logic behind, is not. You complain that most C code is "haphazard in… casting, sloppy in other ways, and generally poor by your definition". In other words, BAD CODE. Written by BAD PROGRAMMERS, I'd wager. We all know that in any given profession, there are a few who know what they are doing, and a large number who only proport to. Why is this the fault of the language? I'd wager these people also write bad code in BASIC or FORTRAN or Modula or anything else you'd care to try… can you imagine the mess they'd make in assembly? No, you haven't convinced me. But don't use C if you don't like it, that's fine. I have no argument with you OR your style. 8) Rick
#109547From: John DraperFeb 17, 1988 12:42 AM
Rick, Yes, I did generalize, perhaps too much, perhaps not. One thing… you say that you want the compiler to assume you know what you are doing. problem is, C does assume that, but only sometimes. implicit casts are one of those times. On the other hand, just try to assign a 'pointer to long' to a variable that has been declared as 'pointer to char', and the compiler suddenly decides you really dont know what you are doing, and says "Hey… you wanna do that, I make you jump through hoops". Regards, Larry.
#109549From: Steve AhlstromFeb 17, 1988 12:53 AM
Assigning a long pointer to a char pointer generates a warning. Hardly what I'd call hoop jumping. Either ignore the warning or cast to get rid of it.
#109564From: John DraperFeb 17, 1988 1:44 AM
Didn't know it generated a warning. "ignore it or cast it" sounds a lot like the prevalent attitude, which in turn probably results in more bad code than any other single factor.
#109572From: Steve AhlstromFeb 17, 1988 2:24 AM
It's not bad code. It's exactly what Rick was talking about. Basically it's a "I know what I'm doing, do it — if you must warn me about it fine, but do what I tell you not what you want me to do" (very liberally paraphrased!).
#109689From: Richard Rae/SYSOPFeb 17, 1988 9:37 PM
Yes, Steve, thank you… that's basically it. I wish I could remember some of the hoop-jumping I've had to do in my programming life; unfortunately I think my mind tends to throw up mental blocks against that sort of memory. 8) The two cases that do come easily to mind are a BASIC program which was required to execute an entered formula (I think John Foust commented on the same problem earlier; I managed to do it WITHOUT all his tests, but only at the expense of jumping through one MAJOR hoop), and a recent FORTRAN program which by all rights should have been trivial but wasn't… because FORTRAN doesn't allow recursion. Neither of these directly fit the issue in question, but at least they illustrate the problems one can run into working with a language which is inflexible in the one area one happens to need. About the only thing that's gotten in my way with C so far is the requirement that switch cases have to be constants… it'd be nice to be able to use variables once in a while.
#109707From: Ben BlishFeb 17, 1988 10:17 PM
You have my vote on that – that constant requirement is a pain in the keester. I have a question – somthing I would have liked to do; (this is directed generally, btw) you can pass the address of a routine by it's name…. can you execute it? Like, say I pass myfunc(strcmp); can myfunc, without resorting to the very simple assembler required to call that function, call it by using that variable? If not, that's something I would like to see. If so, how? –Ben–
#109733From: Nick Sullivan/TransactorFeb 18, 1988 12:25 AM
Ben, (*strcmp)() ought to do it. If you have an array of function names, thus: static int (*funcs[])() = { func1, func2, func3 }; you can call the nth one with: returnval = (*(funcs[n]))(args); Nick
#109733From: Nick Sullivan/TransactorFeb 18, 1988 12:25 AM
Ben, (*strcmp)() ought to do it. If you have an array of function names, thus: static int (*funcs[])() = { func1, func2, func3 }; you can call the nth one with: returnval = (*(funcs[n]))(args); Nick
#109735From: Don Curtis/SYSOPFeb 18, 1988 12:39 AM
You can pass a function pointer and then call that function by placing '()' after the name: char * george(a,b,c) int a,b,c; { do something return(char *); } harry(sam) char *sam(); { char *string; string = sam(); } bill() { harry(george); } Make sense? If not, look on page 118 of Harbison and Steele. In the above case…the function pointer sam was passed as the address of 'george' which is the actual function called by the line: string=sam();
#109735From: Don Curtis/SYSOPFeb 18, 1988 12:39 AM
You can pass a function pointer and then call that function by placing '()' after the name: char * george(a,b,c) int a,b,c; { do something return(char *); } harry(sam) char *sam(); { char *string; string = sam(); } bill() { harry(george); } Make sense? If not, look on page 118 of Harbison and Steele. In the above case…the function pointer sam was passed as the address of 'george' which is the actual function called by the line: string=sam();
#109738From: Don Curtis/SYSOPFeb 18, 1988 12:52 AM
Ben, Of course, I screwed up, the call should have been: string = sam(a,b,c); in the function harry. That's what I get for typing on-line and not looking back at what I started with. Don
#109738From: Don Curtis/SYSOPFeb 18, 1988 12:52 AM
Ben, Of course, I screwed up, the call should have been: string = sam(a,b,c); in the function harry. That's what I get for typing on-line and not looking back at what I started with. Don
#109765From: Richard Rae/SYSOPFeb 18, 1988 11:10 AM
Yes you can, though I think you have to get the pointer to the name of the function. I did that in one of my first C programs on an 8051… it was a pseudo-interrupt-driven task manager for an embedded system. It would scan the task list, determine which task (of the pending highest priority tasks) was oldest, then pass the NAME of that task to a function which handled execution. Though the details escape me (I probably have the code 'round here somewhere), it CAN be done.
#109765From: Richard Rae/SYSOPFeb 18, 1988 11:10 AM
Yes you can, though I think you have to get the pointer to the name of the function. I did that in one of my first C programs on an 8051… it was a pseudo-interrupt-driven task manager for an embedded system. It would scan the task list, determine which task (of the pending highest priority tasks) was oldest, then pass the NAME of that task to a function which handled execution. Though the details escape me (I probably have the code 'round here somewhere), it CAN be done.
#109707From: Ben BlishFeb 17, 1988 10:17 PM
You have my vote on that – that constant requirement is a pain in the keester. I have a question – somthing I would have liked to do; (this is directed generally, btw) you can pass the address of a routine by it's name…. can you execute it? Like, say I pass myfunc(strcmp); can myfunc, without resorting to the very simple assembler required to call that function, call it by using that variable? If not, that's something I would like to see. If so, how? –Ben–
#109689From: Richard Rae/SYSOPFeb 17, 1988 9:37 PM
Yes, Steve, thank you… that's basically it. I wish I could remember some of the hoop-jumping I've had to do in my programming life; unfortunately I think my mind tends to throw up mental blocks against that sort of memory. 8) The two cases that do come easily to mind are a BASIC program which was required to execute an entered formula (I think John Foust commented on the same problem earlier; I managed to do it WITHOUT all his tests, but only at the expense of jumping through one MAJOR hoop), and a recent FORTRAN program which by all rights should have been trivial but wasn't… because FORTRAN doesn't allow recursion. Neither of these directly fit the issue in question, but at least they illustrate the problems one can run into working with a language which is inflexible in the one area one happens to need. About the only thing that's gotten in my way with C so far is the requirement that switch cases have to be constants… it'd be nice to be able to use variables once in a while.
#109572From: Steve AhlstromFeb 17, 1988 2:24 AM
It's not bad code. It's exactly what Rick was talking about. Basically it's a "I know what I'm doing, do it — if you must warn me about it fine, but do what I tell you not what you want me to do" (very liberally paraphrased!).
#109564From: John DraperFeb 17, 1988 1:44 AM
Didn't know it generated a warning. "ignore it or cast it" sounds a lot like the prevalent attitude, which in turn probably results in more bad code than any other single factor.
#109549From: Steve AhlstromFeb 17, 1988 12:53 AM
Assigning a long pointer to a char pointer generates a warning. Hardly what I'd call hoop jumping. Either ignore the warning or cast to get rid of it.
#109688From: Richard Rae/SYSOPFeb 17, 1988 9:36 PM
If I were silly enough to assign a (long *) to a (char *), I'd EXPECT a warning from the compiler. Once again: YOU DO NOT DEPEND ON THE LANGUAGE TO DO THE THINGS YOU SHOULD BE DOING YOURSELF. Casting, from my viewpoint, is one of those things that is the programmer's responsibility. The whole thing is a non-issue for me, since I always explicitly cast. If I get a compile warning, I did something wrong.
#109715From: John DraperFeb 17, 1988 11:13 PM
Rick, Are you saying that you do this? int a; int b; (int)a = (int)b; stop you from making an assignment that violates your casting conventions, either through a typo or plain oversight? Regards, Larry.
#109766From: Richard Rae/SYSOPFeb 18, 1988 11:10 AM
<Sigh> I would THINK that "always explicitly cast" implies that it's done WHEN THE DATA TYPES ARE DIFFERENT. In my estimation, int a,b,r; long int c; r=(int)a+(int)b; is just as incorrect as (given the above declarations) r=b+c; In the latter case, you have not performed a needed cast, the function of the formula is non-obvious without including a look at the definitions, and the result (compilability, warning messages, and actual execution results) are highly compiler dependent. In the former case, you have performed UNneeded casts, which make the reason for having the casts unclear and causes potential confusion, clutters the program unnecessarily, and makes actually needed casts non-unique and therefore more difficult to see. Come on, Larry, ALWAYS doesn't ALWAYS mean ALWAYS. 8) Rick
#109766From: Richard Rae/SYSOPFeb 18, 1988 11:10 AM
<Sigh> I would THINK that "always explicitly cast" implies that it's done WHEN THE DATA TYPES ARE DIFFERENT. In my estimation, int a,b,r; long int c; r=(int)a+(int)b; is just as incorrect as (given the above declarations) r=b+c; In the latter case, you have not performed a needed cast, the function of the formula is non-obvious without including a look at the definitions, and the result (compilability, warning messages, and actual execution results) are highly compiler dependent. In the former case, you have performed UNneeded casts, which make the reason for having the casts unclear and causes potential confusion, clutters the program unnecessarily, and makes actually needed casts non-unique and therefore more difficult to see. Come on, Larry, ALWAYS doesn't ALWAYS mean ALWAYS. 8) Rick
#109715From: John DraperFeb 17, 1988 11:13 PM
Rick, Are you saying that you do this? int a; int b; (int)a = (int)b; stop you from making an assignment that violates your casting conventions, either through a typo or plain oversight? Regards, Larry.
#109688From: Richard Rae/SYSOPFeb 17, 1988 9:36 PM
If I were silly enough to assign a (long *) to a (char *), I'd EXPECT a warning from the compiler. Once again: YOU DO NOT DEPEND ON THE LANGUAGE TO DO THE THINGS YOU SHOULD BE DOING YOURSELF. Casting, from my viewpoint, is one of those things that is the programmer's responsibility. The whole thing is a non-issue for me, since I always explicitly cast. If I get a compile warning, I did something wrong.
#109547From: John DraperFeb 17, 1988 12:42 AM
Rick, Yes, I did generalize, perhaps too much, perhaps not. One thing… you say that you want the compiler to assume you know what you are doing. problem is, C does assume that, but only sometimes. implicit casts are one of those times. On the other hand, just try to assign a 'pointer to long' to a variable that has been declared as 'pointer to char', and the compiler suddenly decides you really dont know what you are doing, and says "Hey… you wanna do that, I make you jump through hoops". Regards, Larry.
#109455From: Richard Rae/SYSOPFeb 16, 1988 3:58 PM
I cannot comment on "the general run of C users" or "most C programmers" I can only comment on my practices and the code I write. You have specific arguments against the language. I am attempting to point out that, by putting down preconceived notions and approaching the language with a given attitude, THOSE PROBLEMS GO AWAY. "'We don't want strong type checking because we want the compiler to assume we know what we are doing." No comment to the first part, agreed to the second part. I don't want a compiler to decide ANYTHING, though I don't terribly mind it saying "Hey, are you SURE you wanted to do this? I'll compile it, but I thought I should mention it…". If I make a syntax error, I expect to be flagged. If I do something that looks strange, I want the compiler to accept it on the assumption that I DO KNOW WHAT I AM DOING. C and assembler fit this bill nicely. Warnings are okay; being forced through hoops to do something I *KNOW* I want to do, but the compiler can't see the logic behind, is not. You complain that most C code is "haphazard in… casting, sloppy in other ways, and generally poor by your definition". In other words, BAD CODE. Written by BAD PROGRAMMERS, I'd wager. We all know that in any given profession, there are a few who know what they are doing, and a large number who only proport to. Why is this the fault of the language? I'd wager these people also write bad code in BASIC or FORTRAN or Modula or anything else you'd care to try… can you imagine the mess they'd make in assembly? No, you haven't convinced me. But don't use C if you don't like it, that's fine. I have no argument with you OR your style. 8) Rick