Forum unknown
· Off the Cuff
What goes where?
29 messages in this thread
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.
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
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.
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.
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.
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!).
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.
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–
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
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
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();
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();
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
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
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.
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.
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–
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.
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!).
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.
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.
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.
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.
<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
<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
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.
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.
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.
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