Groups | Search | Server Info | Keyboard shortcuts | Login | Register [http] [https] [nntp] [nntps]


Groups > comp.lang.c > #23984 > unrolled thread

Params -> local vars?

Started byJon Howson <nospam@nospam.com>
First post2012-07-30 19:35 +0000
Last post2012-12-17 14:13 -0800
Articles 18 — 12 participants

Back to article view | Back to comp.lang.c


Contents

  Params -> local vars? Jon Howson <nospam@nospam.com> - 2012-07-30 19:35 +0000
    Re: Params -> local vars? Eric Sosman <esosman@ieee-dot-org.invalid> - 2012-07-30 15:54 -0400
    Re: Params -> local vars? James Kuyper <jameskuyper@verizon.net> - 2012-07-30 16:00 -0400
    Re: Params -> local vars? Kenneth Brody <kenbrody@spamcop.net> - 2012-07-30 16:01 -0400
    Re: Params -> local vars? Stephen Sprunk <stephen@sprunk.org> - 2012-07-30 15:09 -0500
      Re: Params -> local vars? Mark Bluemel <mark_bluemel@pobox.com> - 2012-07-31 08:34 +0100
        Re: Params -> local vars? Kleuske <kleuske@nowhere.net> - 2012-07-31 19:29 +0000
          Re: Params -> local vars? Eric Sosman <esosman@ieee-dot-org.invalid> - 2012-07-31 15:51 -0400
        Re: Params -> local vars? Kenneth Brody <kenbrody@spamcop.net> - 2012-08-01 15:58 -0400
    Re: Params -> local vars? Keith Thompson <kst-u@mib.org> - 2012-07-30 13:49 -0700
    Re: Params -> local vars? Joe Pfeiffer <pfeiffer@cs.nmsu.edu> - 2012-07-30 21:56 -0600
    Re: Params -> local vars? David T. Ashley <dashley@gmail.com> - 2012-07-31 08:42 -0400
    Re: Params -> local vars? Tim Rentsch <txr@alumni.caltech.edu> - 2012-09-07 13:39 -0700
      Re: Params -> local vars? Keith Thompson <kst-u@mib.org> - 2012-09-07 17:55 -0700
        Re: Params -> local vars? Tim Rentsch <txr@alumni.caltech.edu> - 2012-09-08 05:09 -0700
          Re: Params -> local vars? Keith Thompson <kst-u@mib.org> - 2012-09-08 11:14 -0700
          Re: Params -> local vars? Richard Damon <news.x.richarddamon@xoxy.net> - 2012-09-08 16:43 -0400
            Re: Params -> local vars? Tim Rentsch <txr@alumni.caltech.edu> - 2012-12-17 14:13 -0800

#23984 — Params -> local vars?

FromJon Howson <nospam@nospam.com>
Date2012-07-30 19:35 +0000
SubjectParams -> local vars?
Message-ID<jv6nmr$15k$1@speranza.aioe.org>
Hello

I was reading thru some (yellowing!) mimeographed introductory notes on C 
and I found code like the below.

main(argc,argv)
  int argc;
  char *argv[];
{
  char *malloc();
  char *strcpy();
  int puts();
  void free();

  char *s;
  if(argc>1 &&(s=malloc(8+strlen(argv[1])))){
    strcpy(s,"Hello, ");
    strcpy(s+7,argv[1]);
    puts(s);
    free(s);
  }else{
    puts("Program failed, unknown error");
  }
}

I'm trying to work out what's happening. At the start of the function, I 
guess the parameters are being converted into local variables, maybe a 
way to get pass-by-value in C?

Also what is the advantage of declaring the string and memory functions 
locally to the function?

Cheers
Jon

[toc] | [next] | [standalone]


#23985

FromEric Sosman <esosman@ieee-dot-org.invalid>
Date2012-07-30 15:54 -0400
Message-ID<jv6opm$q0v$1@dont-email.me>
In reply to#23984
On 7/30/2012 3:35 PM, Jon Howson wrote:
> Hello
>
> I was reading thru some (yellowing!) mimeographed introductory notes on C
> and I found code like the below.
>
> main(argc,argv)
>    int argc;
>    char *argv[];
> {
>    char *malloc();
>    char *strcpy();
>    int puts();
>    void free();
>
>    char *s;
>    if(argc>1 &&(s=malloc(8+strlen(argv[1])))){
>      strcpy(s,"Hello, ");
>      strcpy(s+7,argv[1]);
>      puts(s);
>      free(s);
>    }else{
>      puts("Program failed, unknown error");
>    }
> }
>
> I'm trying to work out what's happening. At the start of the function, I
> guess the parameters are being converted into local variables, maybe a
> way to get pass-by-value in C?

     It's the original "K&R style" way of defining functions and
function parameters.  In this style, the names of the parameters
are separated from their types: The first line lists the names,
in order, and the lines before the opening `{' "complete" the
picture by filling in the missing details: types and perhaps
qualifiers.

     Modern C still supports K&R style in the name of backward
compatibility, but it's been obsolete since C89/C90 compilers
became generally available some two decades ago.  In a way, it's
a good sign that you didn't know about this style; it shows that
progress is indeed taking place!

> Also what is the advantage of declaring the string and memory functions
> locally to the function?

     None; it's an anti-advantage.  In the long-gone Days of Yore
there was no universally-available header declaring malloc() and
free() -- some implementations provided <malloc.h>, some didn't.
Also, there was no universal header for the string functions --
some implementations used <string.h> and some used <strings.h>.
In those days there might have been a small advantage in declaring
those functions yourself, so you didn't have to worry about them
being in different (or no!) places on different systems.  (Note also
that malloc() is declared as returning a `char*' -- K&R C had no
`void*'.)

     But there's never been a good reason to write a free-hand
declaration of puts()!  The <stdio.h> header has been around since
a microsecond after the Big Bang, and the right way to declare the
I/O functions has always been `#include <stdio.h>'.

     Those old notes may have value, but only on Antiques Road Show.

-- 
Eric Sosman
esosman@ieee-dot-org.invalid

[toc] | [prev] | [next] | [standalone]


#23987

FromJames Kuyper <jameskuyper@verizon.net>
Date2012-07-30 16:00 -0400
Message-ID<5016E7E6.3090109@verizon.net>
In reply to#23984
On 07/30/2012 03:35 PM, Jon Howson wrote:
> Hello
> 
> I was reading thru some (yellowing!) mimeographed introductory notes on C 
> and I found code like the below.
> 
> main(argc,argv)
>   int argc;
>   char *argv[];
> {
>   char *malloc();
>   char *strcpy();
>   int puts();
>   void free();
> 
>   char *s;
>   if(argc>1 &&(s=malloc(8+strlen(argv[1])))){
>     strcpy(s,"Hello, ");
>     strcpy(s+7,argv[1]);
>     puts(s);
>     free(s);
>   }else{
>     puts("Program failed, unknown error");
>   }
> }
> 
> I'm trying to work out what's happening. At the start of the function, I 
> guess the parameters are being converted into local variables, maybe a 
> way to get pass-by-value in C?

No - that's a non-prototyped function definition. They're still
supported by the C standard, but they've been obsolete ever since the
introduction of function prototypes in C90. Function prototypes turn on
various mandatory diagnostics, but as far as the actual behavior of the
code, that declaration is equivalent to:

	main(int argc, char *argv[])

Note that no return type is specified. This used to be permitted; the
function was implicitly declared as returning an 'int'. However,
"implicit int" has not been supported since C99.

> Also what is the advantage of declaring the string and memory functions 
> locally to the function?

You are allowed to provide your own declaration of some standard library
functions, so long as it is compatible with the correct declaration.
However, it's always a bad idea, even when permitted. You're much better
off #including the appropriate standard headers. In this case, those are
strings.h, stdio.h, and stdlib.h.

The advantage is very small, or possibly even negative: it restricts the
scope of those declarations to the body of main(). This allows
definition of identifiers with the same name and a different meaning
outside of main(), but that would still only work if they did not have
external linkage.

One disadvantage is that a declarations may become incorrect, even if it
originally was correct. That is in fact the case in this code. At one
time, before the first standard, malloc() returned a char*. However,
since the first standard malloc() has returned a void*. However, since
char* and void* are required to have the same representation and
alignment requirements, they are intended to be equivalent for this kind
of use; it would take a pretty perverse (but still fully conforming)
implementation of C for that to be a real problem.

[toc] | [prev] | [next] | [standalone]


#23989

FromKenneth Brody <kenbrody@spamcop.net>
Date2012-07-30 16:01 -0400
Message-ID<xPidnRDZ-dKvdYvNnZ2dnUVZ_rKdnZ2d@bestweb.net>
In reply to#23984
On 7/30/2012 3:35 PM, Jon Howson wrote:
> Hello
>
> I was reading thru some (yellowing!) mimeographed introductory notes on C
> and I found code like the below.
>
> main(argc,argv)
>    int argc;
>    char *argv[];
> {
>    char *malloc();
>    char *strcpy();
>    int puts();
>    void free();
>
>    char *s;
>    if(argc>1 &&(s=malloc(8+strlen(argv[1])))){
>      strcpy(s,"Hello, ");
>      strcpy(s+7,argv[1]);
>      puts(s);
>      free(s);
>    }else{
>      puts("Program failed, unknown error");
>    }
> }
>
> I'm trying to work out what's happening. At the start of the function, I
> guess the parameters are being converted into local variables, maybe a
> way to get pass-by-value in C?

What do you mean by "at the start of the function"?  If you mean the 
"malloc" and "strcpy" statements, then what it's doing is:

1 - Allocating a buffer 8 bytes larger than the length of argv[1].
2 - Building a string consisting of "Hello, " (7 bytes) followed by the
     contents of argv[1].  (Plus the terminal '\0', hence the "8+" on
     the malloc.)
3 - Outputting that string.

> Also what is the advantage of declaring the string and memory functions
> locally to the function?

Nowadays, absolutely nothing.  In fact, I'm not even sure if the C standard 
allows you to to those without invoking the dreaded "undefined behavior". 
Way back when, the program could compile faster w/o the need to read the 
standard header files which defined those functions.

-- 
Kenneth Brody

[toc] | [prev] | [next] | [standalone]


#23993

FromStephen Sprunk <stephen@sprunk.org>
Date2012-07-30 15:09 -0500
Message-ID<jv6pl1$p6$1@dont-email.me>
In reply to#23984
On 30-Jul-12 14:35, Jon Howson wrote:
> I was reading thru some (yellowing!) mimeographed introductory notes on C 
> and I found code like the below.
> 
> main(argc,argv)
>   int argc;
>   char *argv[];
> {
>   char *malloc();
>   char *strcpy();
>   int puts();
>   void free();
> 
>   char *s;
>   if(argc>1 &&(s=malloc(8+strlen(argv[1])))){
>     strcpy(s,"Hello, ");
>     strcpy(s+7,argv[1]);
>     puts(s);
>     free(s);
>   }else{
>     puts("Program failed, unknown error");
>   }
> }
> 
> I'm trying to work out what's happening. At the start of the function, I 
> guess the parameters are being converted into local variables, maybe a 
> way to get pass-by-value in C?
> 
> Also what is the advantage of declaring the string and memory functions 
> locally to the function?

This is K&R C, which had a different syntax for arguments and no
standard headers.  To restate it in ANSI C:

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

int main(int argc, char *argv[]) {
  char *s;

  if (argc>1 && (s = malloc(strlen(argv[1]) + 8))) {
    strcpy(s, "Hello, ");
    strcpy(s+7, argv[1]);
    puts(s);
    free(s);
  } else {
    puts("Program failed, unknown error");
  }
}

A modern coder would just use printf(), but perhaps that hadn't been
taught yet or would have obscured what the text was trying to teach
about string manipulation--or printf() was considered excessive for such
a trivial task on the day's limited machines.

Unless you're interested in software archaeology, I would recommend you
discard any text that uses K&R C, which has been obsolete since ANSI C
was published in 1989.

S

-- 
Stephen Sprunk         "God does not play dice."  --Albert Einstein
CCIE #3723         "God is an inveterate gambler, and He throws the
K5SSS        dice at every possible opportunity." --Stephen Hawking

[toc] | [prev] | [next] | [standalone]


#24017

FromMark Bluemel <mark_bluemel@pobox.com>
Date2012-07-31 08:34 +0100
Message-ID<jv81qi$77g$2@dont-email.me>
In reply to#23993
On 30/07/2012 21:09, Stephen Sprunk wrote:

> Unless you're interested in software archaeology, I would recommend you
> discard any text that uses K&R C, which has been obsolete since ANSI C
> was published in 1989.

A little harsh - I think that K&R 1st edition is worth keeping if you 
have a copy.

[toc] | [prev] | [next] | [standalone]


#24029

FromKleuske <kleuske@nowhere.net>
Date2012-07-31 19:29 +0000
Message-ID<jv9bn8$82f$1@dont-email.me>
In reply to#24017
On Tue, 31 Jul 2012 08:34:42 +0100, Mark Bluemel saw fit to publish the
following:

> On 30/07/2012 21:09, Stephen Sprunk wrote:
> 
>> Unless you're interested in software archaeology, I would recommend you
>> discard any text that uses K&R C, which has been obsolete since ANSI C
>> was published in 1989.
> 
> A little harsh - I think that K&R 1st edition is worth keeping if you 
> have a copy.

Not really smart, either. It may just be a collectors item.I would pay
money for an original K&R manual, if only for sentimental reasons.

For educational purposes, however, I'm with Sprunk.

[toc] | [prev] | [next] | [standalone]


#24030

FromEric Sosman <esosman@ieee-dot-org.invalid>
Date2012-07-31 15:51 -0400
Message-ID<jv9cvr$idc$1@dont-email.me>
In reply to#24029
On 7/31/2012 3:29 PM, Kleuske wrote:
> On Tue, 31 Jul 2012 08:34:42 +0100, Mark Bluemel saw fit to publish the
> following:
>
>> On 30/07/2012 21:09, Stephen Sprunk wrote:
>>
>>> Unless you're interested in software archaeology, I would recommend you
>>> discard any text that uses K&R C, which has been obsolete since ANSI C
>>> was published in 1989.
>>
>> A little harsh - I think that K&R 1st edition is worth keeping if you
>> have a copy.
>
> Not really smart, either. It may just be a collectors item.I would pay
> money for an original K&R manual, if only for sentimental reasons.

     US$3.44 plus $3.99 shipping on Ebay.  Get 'em while they're hot.

     (No, I'm not selling mine.)

> For educational purposes, however, I'm with Sprunk.

     Seconded, or maybe thirded.  The language has changed a lot
in the three and a half decades since K&R came off the presses,
and many code samples in K&R, though exemplary (by definition!)
at the time would nowadays be considered poor style if not just
plain broken.

	"Whan that Aprill, with his shoures soote
	 The droghte of March hath perced to the roote
	 And bathed every veyne in swich licour,
	 Of which vertu engendred is the flour ..."

A classic of English literature, but not much help in learning
English.  Just so with K&R: The language has moved on.

-- 
Eric Sosman
esosman@ieee-dot-org.invalid

[toc] | [prev] | [next] | [standalone]


#24089

FromKenneth Brody <kenbrody@spamcop.net>
Date2012-08-01 15:58 -0400
Message-ID<7pedndUUZ9zUF4TNnZ2dnUVZ_vadnZ2d@bestweb.net>
In reply to#24017
On 7/31/2012 3:34 AM, Mark Bluemel wrote:
> On 30/07/2012 21:09, Stephen Sprunk wrote:
>
>> Unless you're interested in software archaeology, I would recommend you
>> discard any text that uses K&R C, which has been obsolete since ANSI C
>> was published in 1989.
>
> A little harsh - I think that K&R 1st edition is worth keeping if you have a
> copy.

And if you don't want your copy, I'll send you my address.  I'll be happy to 
take it off your hands, no charge.

-- 
Kenneth Brody

[toc] | [prev] | [next] | [standalone]


#23998

FromKeith Thompson <kst-u@mib.org>
Date2012-07-30 13:49 -0700
Message-ID<lnmx2h2cvx.fsf@nuthaus.mib.org>
In reply to#23984
Jon Howson <nospam@nospam.com> writes:
> I was reading thru some (yellowing!) mimeographed introductory notes on C 
> and I found code like the below.
>
> main(argc,argv)
>   int argc;
>   char *argv[];

This is an old-style function definition.  It was the only form
available before the 1989 ANSI C standard introduced prototypes
(borrowed from C++).  It's still legal -- except for the omission of the
return type of main, which has been invalid since C99.

The modern equivalent is:

    int main(int argc, char *argv[]) { ... }

which has the advantage that it makes the parameter types visible to
callers (which is typically less relevant for main than for other
functions).

> {
>   char *malloc();
>   char *strcpy();
>   int puts();
>   void free();
>
>   char *s;
>   if(argc>1 &&(s=malloc(8+strlen(argv[1])))){
>     strcpy(s,"Hello, ");
>     strcpy(s+7,argv[1]);
>     puts(s);
>     free(s);
>   }else{
>     puts("Program failed, unknown error");
>   }
> }
>
> I'm trying to work out what's happening. At the start of the function, I 
> guess the parameters are being converted into local variables, maybe a 
> way to get pass-by-value in C?

As I wrote above, it's an old-style definition.  (Parameters are really
local variables anyway; they differ from other local variables in how
they're declared and in the way they're initialized with the values of
the arguments given in the call.)

> Also what is the advantage of declaring the string and memory functions 
> locally to the function?

None.  The right way to get those declarations is:

    #include <stdlib.h> /* malloc, free */
    #include <string.h> /* strcpy */
    #include <stdio.h>  /* puts */

which also has the advantage of providing prototypes, so the compiler
can diagnose calls with incorrect arguments.

The code as posted will probably work with modern compilers (as long as
they permit the old-style "implicit int" rule, dropped by C99), but it's
not a good example for writing new code.

-- 
Keith Thompson (The_Other_Keith) kst-u@mib.org  <http://www.ghoti.net/~kst>
    Will write code for food.
"We must do something.  This is something.  Therefore, we must do this."
    -- Antony Jay and Jonathan Lynn, "Yes Minister"

[toc] | [prev] | [next] | [standalone]


#24014

FromJoe Pfeiffer <pfeiffer@cs.nmsu.edu>
Date2012-07-30 21:56 -0600
Message-ID<1btxwoeg85.fsf@pfeifferfamily.net>
In reply to#23984
Jon Howson <nospam@nospam.com> writes:

> Hello
>
> I was reading thru some (yellowing!) mimeographed introductory notes on C 
> and I found code like the below.
>
> main(argc,argv)
>   int argc;
>   char *argv[];
> {
>   char *malloc();
>   char *strcpy();
>   int puts();
>   void free();
>
>   char *s;
>   if(argc>1 &&(s=malloc(8+strlen(argv[1])))){
>     strcpy(s,"Hello, ");
>     strcpy(s+7,argv[1]);
>     puts(s);
>     free(s);
>   }else{
>     puts("Program failed, unknown error");
>   }
> }
>
> I'm trying to work out what's happening. At the start of the function, I 
> guess the parameters are being converted into local variables, maybe a 
> way to get pass-by-value in C?

Do you mean this part?

> main(argc,argv)
>   int argc;
>   char *argv[];
> {

That's just the way parameters used to be declared.  It means exactly
the same thing as

main(int argc, char *argv[])

> Also what is the advantage of declaring the string and memory functions 
> locally to the function?

I can't think of one off-hand.

[toc] | [prev] | [next] | [standalone]


#24026

FromDavid T. Ashley <dashley@gmail.com>
Date2012-07-31 08:42 -0400
Message-ID<sdkf18hjlr5tg25o41c8d4abljob668vuv@4ax.com>
In reply to#23984
On Mon, 30 Jul 2012 19:35:55 +0000 (UTC), Jon Howson
<nospam@nospam.com> wrote:

>Hello
>
>I was reading thru some (yellowing!) mimeographed introductory notes on C 
>and I found code like the below.
>
>main(argc,argv)
>  int argc;
>  char *argv[];
>{
>  char *malloc();
>  char *strcpy();
>  int puts();
>  void free();
>
>  char *s;
>  if(argc>1 &&(s=malloc(8+strlen(argv[1])))){
>    strcpy(s,"Hello, ");
>    strcpy(s+7,argv[1]);
>    puts(s);
>    free(s);
>  }else{
>    puts("Program failed, unknown error");
>  }
>}
>
>I'm trying to work out what's happening. At the start of the function, I 
>guess the parameters are being converted into local variables, maybe a 
>way to get pass-by-value in C?

In C, there is no real distinction between parameters and local
variables (except that you can't declare parameters as "static"). They
are the same animal.  Automatic storage.

In C, EVERYTHING is in fact pass-by-value.  The language has a brutal
consistency.

If you want to pass by reference, you have to do it explicitly with a
pointer, i.e.

//Assigns an integer to 1--a very useful function.  I think it
//deserves a patent.
void assign_1(int *arg)
{
   *arg = 1;
}


int main(void)
{
  int one;

  assign_1(&one);

  return(0);
}

DTA.

[toc] | [prev] | [next] | [standalone]


#26081

FromTim Rentsch <txr@alumni.caltech.edu>
Date2012-09-07 13:39 -0700
Message-ID<kfn8vclh8j4.fsf@x-alumni2.alumni.caltech.edu>
In reply to#23984
Jon Howson <nospam@nospam.com> writes:

> Hello
>
> I was reading thru some (yellowing!) mimeographed introductory notes on C 
> and I found code like the below.
>
> main(argc,argv)
>   int argc;
>   char *argv[];
> {
>   char *malloc();
>   char *strcpy();
>   int puts();
>   void free();
>
>   char *s;
>   if(argc>1 &&(s=malloc(8+strlen(argv[1])))){
>     strcpy(s,"Hello, ");
>     strcpy(s+7,argv[1]);
>     puts(s);
>     free(s);
>   }else{
>     puts("Program failed, unknown error");
>   }
> }
>
> I'm trying to work out what's happening. At the start of the function, I 
> guess the parameters are being converted into local variables, maybe a 
> way to get pass-by-value in C?  [snip]

Just a few clarifications/additions to points made in other responses.

1. This style of parameter declaration (dating from more than 30
years ago, before C was standardized) is labelled 'obsolescent'
by the Standard.  That means it's accepted now but don't count
on it being so in future revisions of the Standard.  (On the other
hand it has been obsolescent for more than 20 years now.)

2. The newer (ie, current) style of parameter declarations is called
"prototypes", as for example

    int main( int argc, char *argv[] ){ ... }

3. The prototype style of parameter declaration allows (and requires)
any call after the prototype declaration to have the types of its
arguments checked against the parameter types given in the prototype.
In contrast, the old style of parameter declaration does not do
such type checking (and the Standard says specifically that such
type checking will not be done).

4. The argument values are passed the same way in both cases,
except that, when old-style parameter declarations are used,
the parameter types are adjusted in some cases to reflect the
lack of knowledge about the types used.  For example, a parameter
declared as 'char' will be passed as 'int' (or 'unsigned int' in
some implementations).

5. Except for the change of types mentioned in (4), how parameters
are used in function bodies is the same for both old-style and
the prototype form of parameter declaration.

6. Most people advise using the prototype declaration style when
writing any new code.  I myself follow that advice in most cases
(and refrain now from trying to explain any of the exceptions).

7. For existing code using the older-style (aka "K&R style")
declarations, the most obvious benefit of changing it over to the
prototype form is better type checking.  There are however two
gotcha's worth noting.  One, the higher level of type checking
could produce compilation errors even though the code in question
works fine.  (Of course it's also possible the code doesn't work
fine, and the type checking showed a problem.)  Two, because of
the different rules for how parameter types work, it's possible
for a change that looks innocuous at face value to turn working
code into non-working code (and probably also the reverse, but I
think that's even less likely).  So those changes are not ones
that should be made completely mindlessly and automatically.

8. (I'm skipping the question about the local function declarations
for malloc(), etc, because I don't have anything to add about
that here.)

[toc] | [prev] | [next] | [standalone]


#26110

FromKeith Thompson <kst-u@mib.org>
Date2012-09-07 17:55 -0700
Message-ID<lna9x1s583.fsf@nuthaus.mib.org>
In reply to#26081
Tim Rentsch <txr@alumni.caltech.edu> writes:
[...]
> 3. The prototype style of parameter declaration allows (and requires)
> any call after the prototype declaration to have the types of its
> arguments checked against the parameter types given in the prototype.
> In contrast, the old style of parameter declaration does not do
> such type checking (and the Standard says specifically that such
> type checking will not be done).
[...]

Checking is not *required*, but an implementation is free to perform it
anyway.

For example:

    void func(arg)
    int arg;
    {
        /* ... */
    }

    ...

    func("foo");

The call has undefined behavior.  No diagnostic is required (and I
don't think I've seen a compiler warn about this), but (a) compilers
are free to warn about anything they like, and (b) given undefined
behavior that's detectable at compile time, a compiler is free to
treat it as a fatal error.

-- 
Keith Thompson (The_Other_Keith) kst-u@mib.org  <http://www.ghoti.net/~kst>
    Will write code for food.
"We must do something.  This is something.  Therefore, we must do this."
    -- Antony Jay and Jonathan Lynn, "Yes Minister"

[toc] | [prev] | [next] | [standalone]


#26132

FromTim Rentsch <txr@alumni.caltech.edu>
Date2012-09-08 05:09 -0700
Message-ID<kfnbohgyavl.fsf@x-alumni2.alumni.caltech.edu>
In reply to#26110
Keith Thompson <kst-u@mib.org> writes:

> Tim Rentsch <txr@alumni.caltech.edu> writes:
> [...]
>> 3. The prototype style of parameter declaration allows (and requires)
>> any call after the prototype declaration to have the types of its
>> arguments checked against the parameter types given in the prototype.
>> In contrast, the old style of parameter declaration does not do
>> such type checking (and the Standard says specifically that such
>> type checking will not be done).
> [...]
>
> Checking is not *required*, but an implementation is free to perform it
> anyway.  [snip example]

Talking about function calls, 6.5.2.2 p 8 says "the number and
types of arguments are not compared with those of the parameters
in a function definition that does not include a function
prototype declarator."

You're right that implementations are free to issue any
diagnostics they want.  At the same time, what is in those
diagnostics cannot depend on the results of comparisons
that implementations are prohibited from making.

[toc] | [prev] | [next] | [standalone]


#26146

FromKeith Thompson <kst-u@mib.org>
Date2012-09-08 11:14 -0700
Message-ID<lnsjasjs9v.fsf@nuthaus.mib.org>
In reply to#26132
Tim Rentsch <txr@alumni.caltech.edu> writes:
> Keith Thompson <kst-u@mib.org> writes:
>> Tim Rentsch <txr@alumni.caltech.edu> writes:
>> [...]
>>> 3. The prototype style of parameter declaration allows (and requires)
>>> any call after the prototype declaration to have the types of its
>>> arguments checked against the parameter types given in the prototype.
>>> In contrast, the old style of parameter declaration does not do
>>> such type checking (and the Standard says specifically that such
>>> type checking will not be done).
>> [...]
>>
>> Checking is not *required*, but an implementation is free to perform it
>> anyway.  [snip example]
>
> Talking about function calls, 6.5.2.2 p 8 says "the number and
> types of arguments are not compared with those of the parameters
> in a function definition that does not include a function
> prototype declarator."

The full paragraph is:

    No other conversions are performed implicitly; in particular,
    the number and types of arguments are not compared with those
    of the parameters in a function definition that does not include
    a function prototype declarator.

> You're right that implementations are free to issue any
> diagnostics they want.  At the same time, what is in those
> diagnostics cannot depend on the results of comparisons
> that implementations are prohibited from making.

My suspicion is that the intent was not to forbid making those
comparisons, just that any argument conversions should not depend
on such comparisons.  It certainly does *say* that the comparisons
are not performed, but it's in the context of implicit conversions.

It doesn't make much sense to forbid a compiler to perform
comparisons don't necessarily have any effect.  And as long as
old-style function definitions are in the language, it would be nice
if some compilers could warn about calls with mismatched arguments.

Off to comp.std.c.

-- 
Keith Thompson (The_Other_Keith) kst-u@mib.org  <http://www.ghoti.net/~kst>
    Will write code for food.
"We must do something.  This is something.  Therefore, we must do this."
    -- Antony Jay and Jonathan Lynn, "Yes Minister"

[toc] | [prev] | [next] | [standalone]


#26149

FromRichard Damon <news.x.richarddamon@xoxy.net>
Date2012-09-08 16:43 -0400
Message-ID<k2gale$9mr$1@dont-email.me>
In reply to#26132
On 9/8/12 8:09 AM, Tim Rentsch wrote:
> Keith Thompson <kst-u@mib.org> writes:
> 
>> Tim Rentsch <txr@alumni.caltech.edu> writes:
>> [...]
>>> 3. The prototype style of parameter declaration allows (and requires)
>>> any call after the prototype declaration to have the types of its
>>> arguments checked against the parameter types given in the prototype.
>>> In contrast, the old style of parameter declaration does not do
>>> such type checking (and the Standard says specifically that such
>>> type checking will not be done).
>> [...]
>>
>> Checking is not *required*, but an implementation is free to perform it
>> anyway.  [snip example]
> 
> Talking about function calls, 6.5.2.2 p 8 says "the number and
> types of arguments are not compared with those of the parameters
> in a function definition that does not include a function
> prototype declarator."
> 
> You're right that implementations are free to issue any
> diagnostics they want.  At the same time, what is in those
> diagnostics cannot depend on the results of comparisons
> that implementations are prohibited from making.
> 

The implementation is not prohibited from making any comparisons that it
might want to make, and can say what ever it wants to say, as long as it
prints at least some sort of diagnostic message for a program that
violates a constraint.

It is free to emit a message for anything it wants, even for things that
are "valid code". It is still conforming to issue warnings for things
like unneeded parenthesis or missing unneeded parenthesis that some
coding style might suggest be included due to people often getting
things wrong.

The resulting program output from the implementation (only required if
the program violates no constraints) must produce the standard defined
behavior (for as long as the standard defines the behavior, possibly
with some implementation defined behavior when that is mandated by the
standard). Since calling a non-prototyped function with the wrong
parameter types is not a constraint violation, the compiler can not use
this as grounds to not produce a resulting program (although when/if the
call occurs it creates undefined behavior), but it is free to make what
ever warnings it wants.



[toc] | [prev] | [next] | [standalone]


#29435

FromTim Rentsch <txr@alumni.caltech.edu>
Date2012-12-17 14:13 -0800
Message-ID<kfn4njkgwd5.fsf@x-alumni2.alumni.caltech.edu>
In reply to#26149
Richard Damon <news.x.richarddamon@xoxy.net> writes:

> On 9/8/12 8:09 AM, Tim Rentsch wrote:
>> Keith Thompson <kst-u@mib.org> writes:
>> 
>>> Tim Rentsch <txr@alumni.caltech.edu> writes:
>>> [...]
>>>> 3. The prototype style of parameter declaration allows (and requires)
>>>> any call after the prototype declaration to have the types of its
>>>> arguments checked against the parameter types given in the prototype.
>>>> In contrast, the old style of parameter declaration does not do
>>>> such type checking (and the Standard says specifically that such
>>>> type checking will not be done).
>>> [...]
>>>
>>> Checking is not *required*, but an implementation is free to perform it
>>> anyway.  [snip example]
>> 
>> Talking about function calls, 6.5.2.2 p 8 says "the number and
>> types of arguments are not compared with those of the parameters
>> in a function definition that does not include a function
>> prototype declarator."
>> 
>> You're right that implementations are free to issue any
>> diagnostics they want.  At the same time, what is in those
>> diagnostics cannot depend on the results of comparisons
>> that implementations are prohibited from making.
>
> The implementation is not prohibited from making any comparisons that it
> might want to make, and can say what ever it wants to say, as long as it
> prints at least some sort of diagnostic message for a program that
> violates a constraint.  [snip elaboration]

If you're arguing that the wording of 6.5.2.2 p 8 allows more
than one interpretation, and that interpretation might not
disallow such checking, I agree that aspect is debatable.

If you're arguing that implementations are always free to issue
diagnostics, regardless of how the restrictions in 6.5.2.2 p 8 are
worded, I can't agree with that -- the license to issue diagnostics
does not trump the obligation to meet all other requirements in the
Standard, whatever they are, for all conforming implementations.

[toc] | [prev] | [standalone]


Back to top | Article view | comp.lang.c


csiph-web