I have some code that has in the header file:
void foo( char bar );
and in the source file:
void foo( bar )
char bar;
{ /* etc. */ }
The compiler (with many warnings enabled) warns that the
prototype doesn't match the definition. (However this code
has worked fine in the past, I only turned the warning level
up recently and the warning appeared).
Given that the prototype is visible in the source file, is
there actually any problem with this code? The compiler
can see the prototype when it is compiling the definition
so must it know to grab a char off the stack (or whatever)
instead of an int?
NB. The definition can't be changed to ANSI-style because
it's automatically generated by a third party precompiler. 13 2991
Old Wolf wrote:
I have some code that has in the header file:
void foo( char bar );
and in the source file:
void foo( bar )
char bar;
{ /* etc. */ }
The compiler (with many warnings enabled) warns that the
prototype doesn't match the definition. (However this code
has worked fine in the past, I only turned the warning level
up recently and the warning appeared).
Given that the prototype is visible in the source file, is
there actually any problem with this code? The compiler
can see the prototype when it is compiling the definition
so must it know to grab a char off the stack (or whatever)
instead of an int?
Your declaration says that the caller passes an argument of type char. Your
definition says that the caller passes an argument of type int[*], which
foo() will convert to a char when the function is called. The compiler is
right to complain.
NB. The definition can't be changed to ANSI-style because
it's automatically generated by a third party precompiler.
In your header, you can use
void foo( int bar );
and in your source file, you can either use
void foo( bar )
int bar;
{
char baz = bar;
/* ... */
}
or if your precompiler can handle it, you can change the header as shown
above, but keep the source file as
void foo( bar )
char bar;
{
/* ... */
}
[*] assuming CHAR_MAX <= INT_MAX
On Jun 14, 12:25 pm, Harald van D k <true...@gmail.comwrote:
Old Wolf wrote:
I have some code that has in the header file:
void foo( char bar );
and in the source file:
void foo( bar )
char bar;
{ /* etc. */ }
Your declaration says that the caller passes an argument of type char. Your
definition says that the caller passes an argument of type int[*], which
foo() will convert to a char when the function is called. The compiler is
right to complain.
So the compiler will read the arguments as per K&R,
and not as per the visible prototype?
NB. The definition can't be changed to ANSI-style because
it's automatically generated by a third party precompiler.
In your header, you can use
void foo( int bar );
and in your source file, you can either use
void foo( bar )
int bar;
{
char baz = bar;
That was my temporary workaround :)
or if your precompiler can handle it, you can change the header as shown
above, but keep the source file as
void foo( bar )
char bar;
{
I'll give that a go and see if it likes it.
How is the conversion from int to char specified
for these K&R style definitions? Does it read an
int and then convert in the same way as an
ordinary implicit conversion from int to char?
On Jun 14, 7:57 am, Old Wolf <oldw...@inspire.net.nzwrote:
I have some code that has in the header file:
void foo( char bar );
This is a ANSI C style declare.
Old Wolf wrote:
On Jun 14, 12:25 pm, Harald van D k <true...@gmail.comwrote:
>Old Wolf wrote:
>>I have some code that has in the header file: void foo( char bar ); and in the source file: void foo( bar ) char bar; { /* etc. */ }
Your declaration says that the caller passes an argument of type char. Your definition says that the caller passes an argument of type int[*], which foo() will convert to a char when the function is called. The compiler is right to complain.
So the compiler will read the arguments as per K&R,
and not as per the visible prototype?
The header's declaration conflicts with the function's
definition (which is also a declaration). If the header said
void floo(double boo);
.... and the definition said
int floo(int goo, char *shoo, const struct glue **moo)
{ ... }
.... would you expect the compiler to reconcile them in
some magical way? Of course not: The declaration and the
definition disagree, and that's that. The compiler must
issue a diagnostic; if it then decides to accept the faulty
program, it "reads arguments" according to its own whim.
--
Eric Sosman es*****@acm-dot-org.invalid
Eric Sosman <esos...@acm-dot-org.invalidwrote:
The header's declaration conflicts with the function's
definition (which is also a declaration). If the header said
void floo(double boo);
... and the definition said
int floo(int goo, char *shoo, const struct glue **moo)
{ ... }
... would you expect the compiler to reconcile them in
some magical way? Of course not: The declaration and the
definition disagree, and that's that.
If, as suggested by Harald, the header is:
void foo( int bar );
and the definition is:
void foo( bar )
char bar;
{ .... }
then do you know if the code is correct, or is this
still a mismatch? I'm concerned about how the compiler
will turn the int 'bar' into a char.
Old Wolf wrote:
Eric Sosman <esos...@acm-dot-org.invalidwrote:
> The header's declaration conflicts with the function's definition (which is also a declaration). If the header said
void floo(double boo);
... and the definition said
int floo(int goo, char *shoo, const struct glue **moo) { ... }
... would you expect the compiler to reconcile them in some magical way? Of course not: The declaration and the definition disagree, and that's that.
If, as suggested by Harald, the header is:
void foo( int bar );
and the definition is:
void foo( bar )
char bar;
{ .... }
then do you know if the code is correct, or is this
still a mismatch? I'm concerned about how the compiler
will turn the int 'bar' into a char.
Wouldn't that be UB? The compiler might use different tricks
(registers?) to pass int and char to functions.
--
Ian Collins.
On Jun 14, 3:26 pm, Ian Collins <ian-n...@hotmail.comwrote:
Old Wolf wrote:
If, as suggested by Harald, the header is:
void foo( int bar );
and the definition is:
void foo( bar )
char bar;
{ .... }
then do you know if the code is correct, or is this
still a mismatch? I'm concerned about how the compiler
will turn the int 'bar' into a char.
Wouldn't that be UB? The compiler might use different tricks
(registers?) to pass int and char to functions.
Well it might be OK if the behaviour of the
definition is to read an int using the int-passing
mechanism, and then convert it to char using an
implicit conversion. That's what Harald suggested.
I don't know whether the compiler will behave this
way or not; I was wondering if Eric could confirm
or deny.
Old Wolf wrote:
On Jun 14, 3:26 pm, Ian Collins <ian-n...@hotmail.comwrote:
>Old Wolf wrote:
>>If, as suggested by Harald, the header is: void foo( int bar ); and the definition is: void foo( bar ) char bar; { .... } then do you know if the code is correct, or is this still a mismatch? I'm concerned about how the compiler will turn the int 'bar' into a char.
Wouldn't that be UB? The compiler might use different tricks (registers?) to pass int and char to functions.
Well it might be OK if the behaviour of the
definition is to read an int using the int-passing
mechanism, and then convert it to char using an
implicit conversion. That's what Harald suggested.
I'd expect the char you pass to be sign extended to int (assuming char
is signed) and passed by whatever means to the function. How the
parameter value is retrieved would determine whether this would work.
--
Ian Collins.
Old Wolf wrote:
On Jun 14, 12:25 pm, Harald van D k <true...@gmail.comwrote:
>Old Wolf wrote:
I have some code that has in the header file:
void foo( char bar );
and in the source file:
void foo( bar )
char bar;
{ /* etc. */ }
Your declaration says that the caller passes an argument of type char. Your definition says that the caller passes an argument of type int[*], which foo() will convert to a char when the function is called. The compiler is right to complain.
So the compiler will read the arguments as per K&R,
and not as per the visible prototype?
Yes.
NB. The definition can't be changed to ANSI-style because
it's automatically generated by a third party precompiler.
In your header, you can use
void foo( int bar );
and in your source file, you can either use
void foo( bar ) int bar; { char baz = bar;
That was my temporary workaround :)
>or if your precompiler can handle it, you can change the header as shown above, but keep the source file as
void foo( bar ) char bar; {
I'll give that a go and see if it likes it.
How is the conversion from int to char specified
for these K&R style definitions? Does it read an
int and then convert in the same way as an
ordinary implicit conversion from int to char?
Right. The function call operator will have converted foo's argument to int,
and that argument is then converted "as if by assignment" to char on entry
of foo.
On Wed, 13 Jun 2007 16:57:14 -0700, in comp.lang.c , Old Wolf
<ol*****@inspire.net.nzwrote:
>I have some code that has in the header file:
void foo( char bar );
and in the source file:
void foo( bar )
char bar;
{ /* etc. */ }
The compiler (with many warnings enabled) warns that the prototype doesn't match the definition. (However this code has worked fine in the past, I only turned the warning level up recently and the warning appeared).
Fixes are either convert the definition to ANSI style, or remove the
prototype (make it a declaration instead).
>Given that the prototype is visible in the source file, is there actually any problem with this code?
Quite possibly. The prototype tells the compiler to expect a char, but
the definition suggests otherwise so the compiler can presumably jump
either way.
--
Mark McIntyre
"Debugging is twice as hard as writing the code in the first place.
Therefore, if you write the code as cleverly as possible, you are,
by definition, not smart enough to debug it."
--Brian Kernighan
Old Wolf wrote:
Eric Sosman <esos...@acm-dot-org.invalidwrote:
> The header's declaration conflicts with the function's definition (which is also a declaration). If the header said
void floo(double boo);
... and the definition said
int floo(int goo, char *shoo, const struct glue **moo) { ... }
... would you expect the compiler to reconcile them in some magical way? Of course not: The declaration and the definition disagree, and that's that.
If, as suggested by Harald, the header is:
void foo( int bar );
and the definition is:
void foo( bar )
char bar;
{ .... }
then do you know if the code is correct, or is this
still a mismatch? I'm concerned about how the compiler
will turn the int 'bar' into a char.
It's implementation-defined whether Harald's rewrite
is correct. On systems where plain `char' promotes to
`int' it's correct. On those few where `char' promotes
to `unsigned int' (INT_MAX < CHAR_MAX <= UINT_MAX), the
declaration and definition disagree. Even on most of the
latter you'll get away with it -- but you'll know in your
heart that it's wrong.
"You've got to ask yourself one question: 'Do I
feel lucky?' Well do ya, punk?" -- Harry Callahan
--
Eric Sosman es*****@acm-dot-org.invalid
Old Wolf wrote:
On Jun 14, 3:26 pm, Ian Collins <ian-n...@hotmail.comwrote:
>>Old Wolf wrote:
>>>If, as suggested by Harald, the header is: void foo( int bar );
>>>and the definition is: void foo( bar ) char bar; { .... }
>>>then do you know if the code is correct, or is this still a mismatch? I'm concerned about how the compiler will turn the int 'bar' into a char.
Wouldn't that be UB? The compiler might use different tricks (registers?) to pass int and char to functions.
Well it might be OK if the behaviour of the
definition is to read an int using the int-passing
mechanism, and then convert it to char using an
implicit conversion. That's what Harald suggested.
I don't know whether the compiler will behave this
way or not; I was wondering if Eric could confirm
or deny.
That depends on the particular compiler. If you are only using a single
compiler, you can verify. If it were me, I would change the code to
make it Standard conforming.
--
Thad
On Jun 14, 4:57 am, Old Wolf <oldw...@inspire.net.nzwrote:
I have some code that has in the header file:
void foo( char bar );
Changing this to
#include <limits.h>
#if CHAR_MAX <= INT_MAX
void foo(int);
#else
void foo(unsigned int);
#endif
I think this will solve the problem cited by Eric.
>
and in the source file:
void foo( bar )
char bar;
{ /* etc. */ }
In K&R style of function definition, the functions definition like the
above are effectively equivalent to:
void foo( buf_bar )
PROMOTED_TYPE buf_bar;/*PROMOTED_TYPE is int if CHAR_MAX <= INT_MAX or
else it is unsigned int*/
{
char bar = buf_bar;
/*Use 'bar' as char in ur code*/
/* etc. */
}
This ratiociantes the error generated by the compiler.
>
The compiler (with many warnings enabled) warns that the
prototype doesn't match the definition. (However this code
has worked fine in the past, I only turned the warning level
up recently and the warning appeared).
Given that the prototype is visible in the source file, is
there actually any problem with this code? The compiler
can see the prototype when it is compiling the definition
so must it know to grab a char off the stack (or whatever)
instead of an int?
NB. The definition can't be changed to ANSI-style because
it's automatically generated by a third party precompiler.
This thread has been closed and replies have been disabled. Please start a new discussion. Similar topics
by: Michael B. |
last post by:
I tend to use rather descriptive names for parameters, so the old style of
declaration appeals to me, as I can keep a declaration within 80 chars:
void * newKlElem...
|
by: Agoston Bejo |
last post by:
What happens exactly when I do the following:
struct A {
int i;
string j;
A() {}
};
void f(A& a) {
cout << a.i << endl;
|
by: Alex |
last post by:
Hi all,
I'm writing a small web application which searches a database based on
a date field, and populates a datagrid control with the results. The
datagrid control has selection buttons added...
|
by: I.M. !Knuth |
last post by:
Hi. I'm more-or-less a C newbie. I thought I had pointers under control until
I started goofing around with this:
...
|
by: Heinrich Pumpernickel |
last post by:
what does this warning mean ?
#include <stdio.h>
int main()
{
long l = 100;
printf("l is %li\n", l * 10L);
|
by: dewi |
last post by:
Dear All,
I am trying to compile a C code using Visual C++. Can anyone explain how to solve it?
Thank You.
#include <math.h>
#include <string.h>
#include "RV2AJFRONT_NEW.h"
#include...
|
by: benn |
last post by:
Here's the setup...
Defines.h file contains:
enum DAY { monday, tueday };
DayFunctions.h contains prototype:
void printIsMonday ( enum DAY currentDay);
DayFunctions.c contains:
|
by: lllomh |
last post by:
Define the method first
this.state = {
buttonBackgroundColor: 'green',
isBlinking: false, // A new status is added to identify whether the button is blinking or not
}
autoStart=()=>{
|
by: DJRhino |
last post by:
Was curious if anyone else was having this same issue or not....
I was just Up/Down graded to windows 11 and now my access combo boxes are not acting right. With win 10 I could start typing...
|
by: isladogs |
last post by:
The next Access Europe meeting will be on Wednesday 4 Oct 2023 starting at 18:00 UK time (6PM UTC+1) and finishing at about 19:15 (7.15PM)
The start time is equivalent to 19:00 (7PM) in Central...
|
by: Aliciasmith |
last post by:
In an age dominated by smartphones, having a mobile app for your business is no longer an option; it's a necessity. Whether you're a startup or an established enterprise, finding the right mobile app...
|
by: tracyyun |
last post by:
Hello everyone,
I have a question and would like some advice on network connectivity. I have one computer connected to my router via WiFi, but I have two other computers that I want to be able to...
|
by: NeoPa |
last post by:
Introduction
For this article I'll be using a very simple database which has Form (clsForm) & Report (clsReport) classes that simply handle making the calling Form invisible until the Form, or all...
|
by: Teri B |
last post by:
Hi, I have created a sub-form Roles. In my course form the user selects the roles assigned to the course.
0ne-to-many. One course many roles.
Then I created a report based on the Course form and...
|
by: isladogs |
last post by:
The next Access Europe meeting will be on Wednesday 1 Nov 2023 starting at 18:00 UK time (6PM UTC) and finishing at about 19:15 (7.15PM)
Please note that the UK and Europe revert to winter time on...
|
by: NeoPa |
last post by:
Introduction
For this article I'll be focusing on the Report (clsReport) class. This simply handles making the calling Form invisible until all of the Reports opened by it have been closed, when it...
| |