Re: reply the answer
- From: Harald van Dijk <truedfx@xxxxxxxxx>
- Date: Sat, 30 Jun 2007 19:10:10 +0200
Joe Wright wrote:
Harald van Dijk wrote:
CBFalconer wrote:
Harald van D?k wrote:
Army1987 wrote:Bushwah. There is no need to supply a const parameter to puts.
[...]You do, however, need to make sure you pass an argument of type
if (puts("HELLOWORLD !") < 0)
[...]
In C90, you don't strictly
need a prototype for puts() because it returns int and has no
"strange" arguments.
const char *, not char *.
if (puts((const char *) "HELLOWORLD !") < 0)
There is a special exception for function calls where no
prototype is in scope that says it is okay to pass an argument
of type char * when the function accepts const char * (any
pointer to any character type or void) but it only applies to
functions whose /definition/ also doesn't include a prototype.
Whether the definition of puts includes a prototype is not
specified by the C standard.
All the 'const' in the function prototype says is that the function
will not alter the passed parameter. I suspect you are thinking
C++, which is different.
I am not thinking of C++, I am thinking of C. I'm quoting from n1124; I
don't believe C90 was any different in this regard. Calls to functions
without a prototype in scope are described in 6.5.2.2p6, which contains
"If the function is defined with a type that includes a prototype, and
[...] the types of the arguments after promotion are not compatible with
the types of the parameters, the behavior is undefined."
Since puts is allowed to be defined with a type that includes a prototype
(the standard never says otherwise), and const char * is not compatible
with char *, the behaviour is undefined. What part of that is "bushwah"?
I have puts() prototyped in stdio.h like..
int puts(const char *s);
..and defined something like..
#include <stdio.h>
int puts(const char *s)
{
int c;
while ((c = *s++))
putchar(c);
return putchar('\n');
}
You will note that const does not apply to s but to *s. It's a promise
to the compiler that puts() will not write to its input string,
Functions are allowed to cast away constness and modify the target of any
pointers they receive. This program is strictly conforming:
void f(const int *i) {
*(int *) i = 0;
}
int main(void) {
int i = 1;
f(&i);
return i;
}
Compilers are not allowed to assume that functions accepting
pointer-to-const arguments will not modify the pointed-to objects. puts is
not allowed to write to its input string because and only because this is
not part of its function description.
not that
it won't change s.
Of course. And even if it did mean that, the as-if rule would still allow it
to modify s, because the modifications would not be visible after puts
returns.
Given that 'puts(argv[1])' is incompatible in your view, how would you
qualify the argument?
I would include <stdio.h>, and let the compiler perform the implicit
conversion from char * to const char *.
If I had a good reason to avoid including <stdio.h>, I would provide a
prototyped declaration, and let the compiler perform the implicit
conversion from char * to const char *.
If I had a good reason to not provide a prototyped declaration, then I would
cast the argument from char * to const char * to match the parameter's type
(if the argument isn't const char * already), as I have done in my reply to
Army1987.
.
- Follow-Ups:
- Re: reply the answer
- From: Keith Thompson
- Re: reply the answer
- References:
- reply the answer
- From: guthena
- Re: reply the answer
- From: Army1987
- Re: reply the answer
- From: Harald van Dijk
- Re: reply the answer
- From: CBFalconer
- Re: reply the answer
- From: Harald van Dijk
- Re: reply the answer
- From: Joe Wright
- reply the answer
- Prev by Date: Re: Struct assignment
- Next by Date: Re: Machine epsilon: conclusion
- Previous by thread: Re: reply the answer
- Next by thread: Re: reply the answer
- Index(es):
Relevant Pages
|
|