Re: reply the answer



Joe Wright wrote:
Harald van Dijk wrote:
CBFalconer wrote:
Harald van D?k wrote:
Army1987 wrote:
[...]
if (puts("HELLOWORLD !") < 0)
[...]
In C90, you don't strictly
need a prototype for puts() because it returns int and has no
"strange" arguments.
You do, however, need to make sure you pass an argument of type
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.
Bushwah. There is no need to supply a const parameter to puts.
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.
.



Relevant Pages

  • Re: Can u tell me the explanation reg this problem
    ... value although it's implicitly declared to return int and there isn't a ... proper prototype of printf in scope), ... understood as const char*, ... termination status returned by the program to the operating system ...
    (comp.lang.c)
  • Re: Function arguments and their size
    ... >void f(int a, char b); ... As long as there is a prototype in scope, ... would pass a double to a function that needs an int, ...
    (comp.lang.c)
  • Re: integer promotions
    ... The f's prototype is provided, then an one-byte copy of x is passed to ... No, the value of 'x' is passed as a char, which is one byte by ... The prototype is not provided, then a four-byte int, which contains the ... is passed to f(unix/intel platform). ...
    (comp.lang.c)
  • Re: "Bus Error" related to compiler option
    ... > char b; ... int main ... No prototype for memset up to now. ... Use memcpy() for everything to be on the safe side. ...
    (comp.lang.c)
  • Re: FOUND was (Re: Init_xxx(with arg ??) in C for ruby ext ???)
    ... char *orig_path; ... int alias_file_broken; ... puts a.alias_path ...
    (comp.lang.ruby)